Merge "Fix Volume Dialog button size" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 6393fdb..e184704 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -56,7 +56,7 @@
         "android.media.tv.flags-aconfig-java",
         "android.multiuser.flags-aconfig-java",
         "android.net.platform.flags-aconfig-java",
-        "android.net.vcn.flags-aconfig-java",
+        "android.net.vcn.flags-aconfig-java-export",
         "android.net.wifi.flags-aconfig-java",
         "android.nfc.flags-aconfig-java",
         "android.os.flags-aconfig-java",
@@ -100,7 +100,7 @@
         "com.android.media.flags.performance-aconfig-java",
         "com.android.media.flags.projection-aconfig-java",
         "com.android.net.thread.platform.flags-aconfig-java",
-        "com.android.ranging.flags.ranging-aconfig-java",
+        "com.android.ranging.flags.ranging-aconfig-java-export",
         "com.android.server.contextualsearch.flags-java",
         "com.android.server.flags.services-aconfig-java",
         "com.android.text.flags-aconfig-java",
@@ -373,6 +373,11 @@
     name: "android.security.flags-aconfig-java-export",
     aconfig_declarations: "android.security.flags-aconfig",
     mode: "exported",
+    min_sdk_version: "30",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.wifi",
+    ],
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
@@ -1170,16 +1175,21 @@
 }
 
 // VCN
+// TODO:376339506 Move the VCN code, the flag declaration and
+// java_aconfig_library to framework-connectivity-b
 aconfig_declarations {
     name: "android.net.vcn.flags-aconfig",
     package: "android.net.vcn",
-    container: "system",
+    container: "com.android.tethering",
+    exportable: true,
     srcs: ["core/java/android/net/vcn/*.aconfig"],
 }
 
 java_aconfig_library {
-    name: "android.net.vcn.flags-aconfig-java",
+    name: "android.net.vcn.flags-aconfig-java-export",
     aconfig_declarations: "android.net.vcn.flags-aconfig",
+    mode: "exported",
+    min_sdk_version: "35",
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
@@ -1646,13 +1656,6 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
-// Ranging
-java_aconfig_library {
-    name: "com.android.ranging.flags.ranging-aconfig-java",
-    aconfig_declarations: "ranging_aconfig_flags",
-    defaults: ["framework-minus-apex-aconfig-java-defaults"],
-}
-
 // System Server
 aconfig_declarations {
     name: "android.systemserver.flags-aconfig",
diff --git a/Android.bp b/Android.bp
index 49a6a2b..424a4a71 100644
--- a/Android.bp
+++ b/Android.bp
@@ -397,6 +397,8 @@
         "ext",
         "framework-updatable-stubs-module_libs_api",
         "unsupportedappusage",
+        // TODO(b/379770939): remove prod version of flags from other containers in framework
+        "aconfig_storage_stub",
     ],
     sdk_version: "core_platform",
     static_libs: [
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index a92a543..d748a3b 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -18,7 +18,7 @@
                tests/
                tools/
 bpfmt = -d
-ktfmt = --kotlinlang-style --include-dirs=services/permission,packages/SystemUI,libs/WindowManager/Shell/src/com/android/wm/shell/freeform
+ktfmt = --kotlinlang-style --include-dirs=services/permission,packages/SystemUI,libs/WindowManager/Shell/src/com/android/wm/shell/freeform,libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education
 
 [Hook Scripts]
 checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
diff --git a/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java
index 46250d7..d950b70 100644
--- a/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java
+++ b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java
@@ -34,6 +34,8 @@
 public class TextClassificationManagerPerfTest {
     private static final String WRITE_DEVICE_CONFIG_PERMISSION =
             "android.permission.WRITE_DEVICE_CONFIG";
+    private static final String WRITE_ALLOWLISTED_DEVICE_CONFIG_PERMISSION =
+            "android.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG";
 
     @Rule
     public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@@ -44,7 +46,7 @@
     public static void setUpClass() {
         InstrumentationRegistry.getInstrumentation().getUiAutomation()
                 .adoptShellPermissionIdentity(
-                        WRITE_DEVICE_CONFIG_PERMISSION);
+                        WRITE_DEVICE_CONFIG_PERMISSION, WRITE_ALLOWLISTED_DEVICE_CONFIG_PERMISSION);
     }
 
     @AfterClass
diff --git a/apct-tests/perftests/tracing/src/com/android/internal/protolog/ProtoLogPerfTest.java b/apct-tests/perftests/tracing/src/com/android/internal/protolog/ProtoLogPerfTest.java
index 7ef8c53..7168fbe 100644
--- a/apct-tests/perftests/tracing/src/com/android/internal/protolog/ProtoLogPerfTest.java
+++ b/apct-tests/perftests/tracing/src/com/android/internal/protolog/ProtoLogPerfTest.java
@@ -19,6 +19,9 @@
 import android.os.Bundle;
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.perftests.utils.Stats;
+import android.tracing.perfetto.DataSourceParams;
+import android.tracing.perfetto.InitArguments;
+import android.tracing.perfetto.Producer;
 
 import androidx.test.InstrumentationRegistry;
 
@@ -70,6 +73,8 @@
     }
 
     private IProtoLog mProcessedProtoLogger;
+    private static ProtoLogDataSource sTestDataSource;
+    private static final String TEST_PROTOLOG_DATASOURCE_NAME = "test.android.protolog";
     private static final String MOCK_TEST_FILE_PATH = "mock/file/path";
     private static final perfetto.protos.Protolog.ProtoLogViewerConfig VIEWER_CONFIG =
             perfetto.protos.Protolog.ProtoLogViewerConfig.newBuilder()
@@ -89,6 +94,17 @@
 
     @BeforeClass
     public static void init() {
+        Producer.init(InitArguments.DEFAULTS);
+
+        sTestDataSource = new ProtoLogDataSource(TEST_PROTOLOG_DATASOURCE_NAME);
+        DataSourceParams params =
+                new DataSourceParams.Builder()
+                        .setBufferExhaustedPolicy(
+                                DataSourceParams
+                                        .PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
+                        .build();
+        sTestDataSource.register(params);
+
         ProtoLog.init(TestProtoLogGroup.values());
     }
 
@@ -98,9 +114,10 @@
         TestProtoLogGroup.TEST_GROUP.setLogToLogcat(mLogToLogcat);
 
         mProcessedProtoLogger = new ProcessedPerfettoProtoLogImpl(
+                sTestDataSource,
                 MOCK_TEST_FILE_PATH,
                 () -> new AutoClosableProtoInputStream(VIEWER_CONFIG.toByteArray()),
-                () -> {},
+                (instance) -> {},
                 TestProtoLogGroup.values()
         );
     }
diff --git a/apex/jobscheduler/service/aconfig/app_idle.aconfig b/apex/jobscheduler/service/aconfig/app_idle.aconfig
index f079c02..74d2a59 100644
--- a/apex/jobscheduler/service/aconfig/app_idle.aconfig
+++ b/apex/jobscheduler/service/aconfig/app_idle.aconfig
@@ -21,3 +21,10 @@
        purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "adjust_default_bucket_elevation_params"
+    namespace: "backstage_power"
+    description: "Adjust the default bucket evaluation parameters"
+    bug: "379909479"
+}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 1c6e40e..a5a08fb 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -573,6 +573,7 @@
                         case Constants.KEY_MIN_LINEAR_BACKOFF_TIME_MS:
                         case Constants.KEY_MIN_EXP_BACKOFF_TIME_MS:
                         case Constants.KEY_SYSTEM_STOP_TO_FAILURE_RATIO:
+                        case Constants.KEY_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF:
                             mConstants.updateBackoffConstantsLocked();
                             break;
                         case Constants.KEY_CONN_CONGESTION_DELAY_FRAC:
@@ -679,6 +680,8 @@
         private static final String KEY_MIN_EXP_BACKOFF_TIME_MS = "min_exp_backoff_time_ms";
         private static final String KEY_SYSTEM_STOP_TO_FAILURE_RATIO =
                 "system_stop_to_failure_ratio";
+        private static final String KEY_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF =
+                "abandoned_job_timeouts_before_aggressive_backoff";
         private static final String KEY_CONN_CONGESTION_DELAY_FRAC = "conn_congestion_delay_frac";
         private static final String KEY_CONN_PREFETCH_RELAX_FRAC = "conn_prefetch_relax_frac";
         private static final String KEY_CONN_USE_CELL_SIGNAL_STRENGTH =
@@ -750,6 +753,7 @@
         private static final long DEFAULT_MIN_LINEAR_BACKOFF_TIME_MS = JobInfo.MIN_BACKOFF_MILLIS;
         private static final long DEFAULT_MIN_EXP_BACKOFF_TIME_MS = JobInfo.MIN_BACKOFF_MILLIS;
         private static final int DEFAULT_SYSTEM_STOP_TO_FAILURE_RATIO = 3;
+        private static final int DEFAULT_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF = 3;
         private static final float DEFAULT_CONN_CONGESTION_DELAY_FRAC = 0.5f;
         private static final float DEFAULT_CONN_PREFETCH_RELAX_FRAC = 0.5f;
         private static final boolean DEFAULT_CONN_USE_CELL_SIGNAL_STRENGTH = true;
@@ -845,7 +849,12 @@
          * incremental failure in the backoff policy calculation.
          */
         int SYSTEM_STOP_TO_FAILURE_RATIO = DEFAULT_SYSTEM_STOP_TO_FAILURE_RATIO;
-
+        /**
+         * Number of consecutive timeouts by abandoned jobs before we change to aggressive backoff
+         * policy.
+         */
+        int ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF =
+                DEFAULT_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF;
         /**
          * The fraction of a job's running window that must pass before we
          * consider running it when the network is congested.
@@ -1078,6 +1087,10 @@
             SYSTEM_STOP_TO_FAILURE_RATIO = DeviceConfig.getInt(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
                     KEY_SYSTEM_STOP_TO_FAILURE_RATIO,
                     DEFAULT_SYSTEM_STOP_TO_FAILURE_RATIO);
+            ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF = DeviceConfig.getInt(
+                    DeviceConfig.NAMESPACE_JOB_SCHEDULER,
+                    KEY_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF,
+                    DEFAULT_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF);
         }
 
         // TODO(141645789): move into ConnectivityController.CcConfig
@@ -1287,6 +1300,8 @@
             pw.print(KEY_MIN_LINEAR_BACKOFF_TIME_MS, MIN_LINEAR_BACKOFF_TIME_MS).println();
             pw.print(KEY_MIN_EXP_BACKOFF_TIME_MS, MIN_EXP_BACKOFF_TIME_MS).println();
             pw.print(KEY_SYSTEM_STOP_TO_FAILURE_RATIO, SYSTEM_STOP_TO_FAILURE_RATIO).println();
+            pw.print(KEY_ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF,
+                    ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF).println();
             pw.print(KEY_CONN_CONGESTION_DELAY_FRAC, CONN_CONGESTION_DELAY_FRAC).println();
             pw.print(KEY_CONN_PREFETCH_RELAX_FRAC, CONN_PREFETCH_RELAX_FRAC).println();
             pw.print(KEY_CONN_USE_CELL_SIGNAL_STRENGTH, CONN_USE_CELL_SIGNAL_STRENGTH).println();
@@ -2085,8 +2100,12 @@
         if (DEBUG) {
             Slog.v(TAG, debugPrefix + " ready=" + jobReady);
         }
-        if (!jobReady) {
-            return job.getPendingJobReasons();
+        final JobRestriction restriction = checkIfRestricted(job);
+        if (DEBUG) {
+            Slog.v(TAG, debugPrefix + " restriction=" + restriction);
+        }
+        if (!jobReady || restriction != null) {
+            return job.getPendingJobReasons(restriction);
         }
 
         final boolean userStarted = areUsersStartedLocked(job);
@@ -2106,18 +2125,6 @@
             return new int[] { JobScheduler.PENDING_JOB_REASON_APP };
         }
 
-        final JobRestriction restriction = checkIfRestricted(job);
-        if (DEBUG) {
-            Slog.v(TAG, debugPrefix + " restriction=" + restriction);
-        }
-        if (restriction != null) {
-            // Currently this will return _DEVICE_STATE because of thermal reasons.
-            // TODO (b/372031023): does it make sense to move this along with the
-            //  pendingJobReasons() call above and also get the pending reasons from
-            //  all of the restriction controllers?
-            return new int[] { restriction.getPendingReason() };
-        }
-
         // The following can be a little more expensive, so we are doing it later,
         // but still before checking with the package manager!
         final boolean jobPending = mPendingJobQueue.contains(job);
@@ -3005,6 +3012,7 @@
 
         final long initialBackoffMillis = job.getInitialBackoffMillis();
         int numFailures = failureToReschedule.getNumFailures();
+        int numAbandonedFailures = failureToReschedule.getNumAbandonedFailures();
         int numSystemStops = failureToReschedule.getNumSystemStops();
         // We should back off slowly if JobScheduler keeps stopping the job,
         // but back off immediately if the issue appeared to be the app's fault
@@ -3014,9 +3022,19 @@
                 || internalStopReason == JobParameters.INTERNAL_STOP_REASON_ANR
                 || stopReason == JobParameters.STOP_REASON_USER) {
             numFailures++;
+        } else if (android.app.job.Flags.handleAbandonedJobs()
+                && internalStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED) {
+            numAbandonedFailures++;
+            numFailures++;
         } else {
             numSystemStops++;
         }
+
+        int backoffPolicy = job.getBackoffPolicy();
+        if (shouldUseAggressiveBackoff(numAbandonedFailures)) {
+            backoffPolicy = JobInfo.BACKOFF_POLICY_EXPONENTIAL;
+        }
+
         final int backoffAttempts =
                 numFailures + numSystemStops / mConstants.SYSTEM_STOP_TO_FAILURE_RATIO;
         final long earliestRuntimeMs;
@@ -3025,7 +3043,7 @@
             earliestRuntimeMs = JobStatus.NO_EARLIEST_RUNTIME;
         } else {
             long delayMillis;
-            switch (job.getBackoffPolicy()) {
+            switch (backoffPolicy) {
                 case JobInfo.BACKOFF_POLICY_LINEAR: {
                     long backoff = initialBackoffMillis;
                     if (backoff < mConstants.MIN_LINEAR_BACKOFF_TIME_MS) {
@@ -3054,7 +3072,7 @@
         }
         JobStatus newJob = new JobStatus(failureToReschedule,
                 earliestRuntimeMs,
-                JobStatus.NO_LATEST_RUNTIME, numFailures, numSystemStops,
+                JobStatus.NO_LATEST_RUNTIME, numFailures, numAbandonedFailures, numSystemStops,
                 failureToReschedule.getLastSuccessfulRunTime(), sSystemClock.millis(),
                 failureToReschedule.getCumulativeExecutionTimeMs());
         if (stopReason == JobParameters.STOP_REASON_USER) {
@@ -3077,6 +3095,20 @@
     }
 
     /**
+     * Returns {@code true} if the given number of abandoned failures indicates that JobScheduler
+     * should use an aggressive backoff policy.
+     *
+     * @param numAbandonedFailures The number of abandoned failures.
+     * @return {@code true} if the given number of abandoned failures indicates that JobScheduler
+     *     should use an aggressive backoff policy.
+     */
+    public boolean shouldUseAggressiveBackoff(int numAbandonedFailures) {
+        return android.app.job.Flags.handleAbandonedJobs()
+                && numAbandonedFailures
+                        > mConstants.ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF;
+    }
+
+    /**
      * Maximum time buffer in which JobScheduler will try to optimize periodic job scheduling. This
      * does not cause a job's period to be larger than requested (eg: if the requested period is
      * shorter than this buffer). This is used to put a limit on when JobScheduler will intervene
@@ -3155,6 +3187,7 @@
             return new JobStatus(periodicToReschedule,
                     elapsedNow + period - flex, elapsedNow + period,
                     0 /* numFailures */, 0 /* numSystemStops */,
+                    0 /* numAbandonedFailures */,
                     sSystemClock.millis() /* lastSuccessfulRunTime */,
                     periodicToReschedule.getLastFailedRunTime(),
                     0 /* Reset cumulativeExecutionTime because of successful execution */);
@@ -3171,6 +3204,7 @@
         return new JobStatus(periodicToReschedule,
                 newEarliestRunTimeElapsed, newLatestRuntimeElapsed,
                 0 /* numFailures */, 0 /* numSystemStops */,
+                0 /* numAbandonedFailures */,
                 sSystemClock.millis() /* lastSuccessfulRunTime */,
                 periodicToReschedule.getLastFailedRunTime(),
                 0 /* Reset cumulativeExecutionTime because of successful execution */);
@@ -3179,6 +3213,10 @@
     @VisibleForTesting
     void maybeProcessBuggyJob(@NonNull JobStatus jobStatus, int debugStopReason) {
         boolean jobTimedOut = debugStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT;
+        if (android.app.job.Flags.handleAbandonedJobs()) {
+            jobTimedOut |= (debugStopReason
+                == JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED);
+        }
         // If madeActive = 0, the job never actually started.
         if (!jobTimedOut && jobStatus.madeActive > 0) {
             final long executionDurationMs = sUptimeMillisClock.millis() - jobStatus.madeActive;
@@ -3260,9 +3298,12 @@
         // we stop it.
         final JobStatus rescheduledJob = needsReschedule
                 ? getRescheduleJobForFailureLocked(jobStatus, stopReason, debugStopReason) : null;
+        final boolean isStopReasonAbandoned = android.app.job.Flags.handleAbandonedJobs()
+                && (debugStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED);
         if (rescheduledJob != null
                 && !rescheduledJob.shouldTreatAsUserInitiatedJob()
                 && (debugStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT
+                || isStopReasonAbandoned
                 || debugStopReason == JobParameters.INTERNAL_STOP_REASON_PREEMPT)) {
             rescheduledJob.disallowRunInBatterySaverAndDoze();
         }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
index d8934d8..dfb3681 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
@@ -269,7 +269,9 @@
                         convertRtcBoundsToElapsed(utcTimes, elapsedNow);
                 JobStatus newJob = new JobStatus(job,
                         elapsedRuntimes.first, elapsedRuntimes.second,
-                        0, 0, job.getLastSuccessfulRunTime(), job.getLastFailedRunTime(),
+                        0 /* numFailures */, 0 /* numAbandonedFailures */,
+                        0 /* numSystemStops */, job.getLastSuccessfulRunTime(),
+                        job.getLastFailedRunTime(),
                         job.getCumulativeExecutionTimeMs());
                 newJob.prepareLocked();
                 toAdd.add(newJob);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index b0784f1..5a33aa0 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -66,6 +66,7 @@
 import com.android.server.job.JobServerProtoEnums;
 import com.android.server.job.JobStatusDumpProto;
 import com.android.server.job.JobStatusShortInfoProto;
+import com.android.server.job.restrictions.JobRestriction;
 
 import dalvik.annotation.optimization.NeverCompile;
 
@@ -315,6 +316,12 @@
     private final int numFailures;
 
     /**
+     * How many times this job has stopped due to {@link
+     * JobParameters#STOP_REASON_TIMEOUT_ABANDONED}.
+     */
+    private final int mNumAbandonedFailures;
+
+    /**
      * The number of times JobScheduler has forced this job to stop due to reasons mostly outside
      * of the app's control.
      */
@@ -604,6 +611,8 @@
      * @param tag A string associated with the job for debugging/logging purposes.
      * @param numFailures Count of how many times this job has requested a reschedule because
      *     its work was not yet finished.
+     * @param mNumAbandonedFailures Count of how many times this job has requested a reschedule
+     *     because it was abandoned.
      * @param numSystemStops Count of how many times JobScheduler has forced this job to stop due to
      *     factors mostly out of the app's control.
      * @param earliestRunTimeElapsedMillis Milestone: earliest point in time at which the job
@@ -616,7 +625,7 @@
      */
     private JobStatus(JobInfo job, int callingUid, String sourcePackageName,
             int sourceUserId, int standbyBucket, @Nullable String namespace, String tag,
-            int numFailures, int numSystemStops,
+            int numFailures, int mNumAbandonedFailures, int numSystemStops,
             long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis,
             long lastSuccessfulRunTime, long lastFailedRunTime, long cumulativeExecutionTimeMs,
             int internalFlags,
@@ -676,6 +685,7 @@
         this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
         this.mOriginalLatestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
         this.numFailures = numFailures;
+        this.mNumAbandonedFailures = mNumAbandonedFailures;
         mNumSystemStops = numSystemStops;
 
         int requiredConstraints = job.getConstraintFlags();
@@ -749,7 +759,8 @@
         this(jobStatus.getJob(), jobStatus.getUid(),
                 jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(),
                 jobStatus.getStandbyBucket(), jobStatus.getNamespace(),
-                jobStatus.getSourceTag(), jobStatus.getNumFailures(), jobStatus.getNumSystemStops(),
+                jobStatus.getSourceTag(), jobStatus.getNumFailures(),
+                jobStatus.getNumAbandonedFailures(), jobStatus.getNumSystemStops(),
                 jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed(),
                 jobStatus.getLastSuccessfulRunTime(), jobStatus.getLastFailedRunTime(),
                 jobStatus.getCumulativeExecutionTimeMs(),
@@ -786,6 +797,7 @@
         this(job, callingUid, sourcePkgName, sourceUserId,
                 standbyBucket, namespace,
                 sourceTag, /* numFailures */ 0, /* numSystemStops */ 0,
+                /* mNumAbandonedFailures */ 0,
                 earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
                 lastSuccessfulRunTime, lastFailedRunTime, cumulativeExecutionTimeMs,
                 innerFlags, dynamicConstraints);
@@ -805,13 +817,15 @@
     /** Create a new job to be rescheduled with the provided parameters. */
     public JobStatus(JobStatus rescheduling,
             long newEarliestRuntimeElapsedMillis,
-            long newLatestRuntimeElapsedMillis, int numFailures, int numSystemStops,
+            long newLatestRuntimeElapsedMillis, int numFailures,
+            int mNumAbandonedFailures, int numSystemStops,
             long lastSuccessfulRunTime, long lastFailedRunTime,
             long cumulativeExecutionTimeMs) {
         this(rescheduling.job, rescheduling.getUid(),
                 rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(),
                 rescheduling.getStandbyBucket(), rescheduling.getNamespace(),
-                rescheduling.getSourceTag(), numFailures, numSystemStops,
+                rescheduling.getSourceTag(), numFailures,
+                mNumAbandonedFailures, numSystemStops,
                 newEarliestRuntimeElapsedMillis,
                 newLatestRuntimeElapsedMillis,
                 lastSuccessfulRunTime, lastFailedRunTime, cumulativeExecutionTimeMs,
@@ -850,7 +864,8 @@
         int standbyBucket = JobSchedulerService.standbyBucketForPackage(jobPackage,
                 sourceUserId, elapsedNow);
         return new JobStatus(job, callingUid, sourcePkg, sourceUserId,
-                standbyBucket, namespace, tag, /* numFailures */ 0, /* numSystemStops */ 0,
+                standbyBucket, namespace, tag, /* numFailures */ 0,
+                /* mNumAbandonedFailures */ 0, /* numSystemStops */ 0,
                 earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
                 0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */,
                 /* cumulativeExecutionTime */ 0,
@@ -1145,6 +1160,13 @@
     }
 
     /**
+     * Returns the number of times the job stopped previously for STOP_REASON_TIMEOUT_ABANDONED.
+     */
+    public int getNumAbandonedFailures() {
+        return mNumAbandonedFailures;
+    }
+
+    /**
      * Returns the number of times the system stopped a previous execution of this job for reasons
      * that were likely outside the app's control.
      */
@@ -2179,11 +2201,20 @@
      * This will return all potential reasons why the job is pending.
      */
     @NonNull
-    public int[] getPendingJobReasons() {
+    public int[] getPendingJobReasons(@Nullable JobRestriction restriction) {
         final int unsatisfiedConstraints = ~satisfiedConstraints
                 & (requiredConstraints | mDynamicConstraints | IMPLICIT_CONSTRAINTS);
         final ArrayList<Integer> reasons = constraintsToPendingJobReasons(unsatisfiedConstraints);
 
+        if (restriction != null) {
+            // Currently only ThermalStatusRestriction extends the JobRestriction class and
+            // returns PENDING_JOB_REASON_DEVICE_STATE if the job is restricted because of thermal.
+            @JobScheduler.PendingJobReason final int reason = restriction.getPendingReason();
+            if (!reasons.contains(reason)) {
+                reasons.addLast(reason);
+            }
+        }
+
         if (reasons.isEmpty()) {
             if (getEffectiveStandbyBucket() == NEVER_INDEX) {
                 Slog.wtf(TAG, "App in NEVER bucket querying pending job reason");
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index c9d3407..9871d71 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -337,11 +337,11 @@
      */
     long[] mAppStandbyElapsedThresholds = DEFAULT_ELAPSED_TIME_THRESHOLDS;
     /** Minimum time a strong usage event should keep the bucket elevated. */
-    long mStrongUsageTimeoutMillis = ConstantsObserver.DEFAULT_STRONG_USAGE_TIMEOUT;
+    long mStrongUsageTimeoutMillis = ConstantsObserver.DEFAULT_LEGACY_STRONG_USAGE_TIMEOUT;
     /** Minimum time a notification seen event should keep the bucket elevated. */
     long mNotificationSeenTimeoutMillis = ConstantsObserver.DEFAULT_NOTIFICATION_TIMEOUT;
     /** Minimum time a slice pinned event should keep the bucket elevated. */
-    long mSlicePinnedTimeoutMillis = ConstantsObserver.DEFAULT_SLICE_PINNED_TIMEOUT;
+    long mSlicePinnedTimeoutMillis = ConstantsObserver.DEFAULT_LEGACY_SLICE_PINNED_TIMEOUT;
     /** The standby bucket that an app will be promoted on a notification-seen event */
     int mNotificationSeenPromotedBucket =
             ConstantsObserver.DEFAULT_NOTIFICATION_SEEN_PROMOTED_BUCKET;
@@ -362,7 +362,9 @@
     /** Maximum time to wait for a prediction before using simple timeouts to downgrade buckets. */
     long mPredictionTimeoutMillis = DEFAULT_PREDICTION_TIMEOUT;
     /** Maximum time a sync adapter associated with a CP should keep the buckets elevated. */
-    long mSyncAdapterTimeoutMillis = ConstantsObserver.DEFAULT_SYNC_ADAPTER_TIMEOUT;
+    long mSyncAdapterTimeoutMillis = ConstantsObserver.DEFAULT_LEGACY_SYNC_ADAPTER_TIMEOUT;
+    /** The bucket that an app will be promoted on a sync adapter associated with a CP */
+    int mSyncAdapaterPromotedBucket = STANDBY_BUCKET_ACTIVE;
     /**
      * Maximum time an exempted sync should keep the buckets elevated, when sync is scheduled in
      * non-doze
@@ -751,7 +753,7 @@
                         userId);
                 synchronized (mAppIdleLock) {
                     reportNoninteractiveUsageCrossUserLocked(packageName, userId,
-                            STANDBY_BUCKET_ACTIVE, REASON_SUB_USAGE_SYNC_ADAPTER,
+                            mSyncAdapaterPromotedBucket, REASON_SUB_USAGE_SYNC_ADAPTER,
                             elapsedRealtime, mSyncAdapterTimeoutMillis, linkedProfiles);
                 }
             }
@@ -2446,6 +2448,8 @@
         pw.println("Flags: ");
         pw.println("    " + Flags.FLAG_AVOID_IDLE_CHECK
                 + ": " + Flags.avoidIdleCheck());
+        pw.println("    " + Flags.FLAG_ADJUST_DEFAULT_BUCKET_ELEVATION_PARAMS
+                + ": " + Flags.adjustDefaultBucketElevationParams());
         pw.println();
 
         synchronized (mCarrierPrivilegedLock) {
@@ -2481,6 +2485,9 @@
         pw.print("  mSyncAdapterTimeoutMillis=");
         TimeUtils.formatDuration(mSyncAdapterTimeoutMillis, pw);
         pw.println();
+        pw.print("  mSyncAdapaterPromotedBucket=");
+        pw.print(standbyBucketToString(mSyncAdapaterPromotedBucket));
+        pw.println();
         pw.print("  mSystemInteractionTimeoutMillis=");
         TimeUtils.formatDuration(mSystemInteractionTimeoutMillis, pw);
         pw.println();
@@ -3059,12 +3066,18 @@
 
         public static final long DEFAULT_CHECK_IDLE_INTERVAL_MS =
                 COMPRESS_TIME ? ONE_MINUTE : 4 * ONE_HOUR;
-        public static final long DEFAULT_STRONG_USAGE_TIMEOUT =
+        public static final long DEFAULT_LEGACY_STRONG_USAGE_TIMEOUT =
                 COMPRESS_TIME ? ONE_MINUTE : 1 * ONE_HOUR;
+
+        public static final long DEFAULT_CURRENT_STRONG_USAGE_TIMEOUT =
+                COMPRESS_TIME ? ONE_MINUTE : 5 * ONE_MINUTE;
         public static final long DEFAULT_NOTIFICATION_TIMEOUT =
                 COMPRESS_TIME ? 12 * ONE_MINUTE : 12 * ONE_HOUR;
-        public static final long DEFAULT_SLICE_PINNED_TIMEOUT =
+        public static final long DEFAULT_LEGACY_SLICE_PINNED_TIMEOUT =
                 COMPRESS_TIME ? 12 * ONE_MINUTE : 12 * ONE_HOUR;
+
+        public static final long DEFAULT_CURRENT_SLICE_PINNED_TIMEOUT =
+                COMPRESS_TIME ? 12 * ONE_MINUTE : 2 * ONE_HOUR;
         public static final int DEFAULT_NOTIFICATION_SEEN_PROMOTED_BUCKET =
                 STANDBY_BUCKET_WORKING_SET;
         public static final boolean DEFAULT_RETAIN_NOTIFICATION_SEEN_IMPACT_FOR_PRE_T_APPS = false;
@@ -3073,8 +3086,11 @@
                 COMPRESS_TIME ? 2 * ONE_MINUTE : 2 * ONE_HOUR;
         public static final long DEFAULT_SYSTEM_INTERACTION_TIMEOUT =
                 COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE;
-        public static final long DEFAULT_SYNC_ADAPTER_TIMEOUT =
+        public static final long DEFAULT_LEGACY_SYNC_ADAPTER_TIMEOUT =
                 COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE;
+
+        public static final long DEFAULT_CURRENT_SYNC_ADAPTER_TIMEOUT =
+                COMPRESS_TIME ? ONE_MINUTE : 2 * ONE_HOUR;
         public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT =
                 COMPRESS_TIME ? (ONE_MINUTE / 2) : 10 * ONE_MINUTE;
         public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT =
@@ -3117,6 +3133,9 @@
             cr.registerContentObserver(Global.getUriFor(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED),
                     false, this);
             mInjector.registerDeviceConfigPropertiesChangedListener(this);
+
+            processDefaultConstants();
+
             // Load all the constants.
             // postOneTimeCheckIdleStates() doesn't need to be called on boot.
             processProperties(mInjector.getDeviceConfigProperties());
@@ -3135,6 +3154,17 @@
             postOneTimeCheckIdleStates();
         }
 
+        private void processDefaultConstants() {
+            if (!Flags.adjustDefaultBucketElevationParams()) {
+                return;
+            }
+
+            mSlicePinnedTimeoutMillis = DEFAULT_CURRENT_SLICE_PINNED_TIMEOUT;
+            mSyncAdapterTimeoutMillis = DEFAULT_CURRENT_SYNC_ADAPTER_TIMEOUT;
+            mSyncAdapaterPromotedBucket = STANDBY_BUCKET_WORKING_SET;
+            mStrongUsageTimeoutMillis = DEFAULT_CURRENT_STRONG_USAGE_TIMEOUT;
+        }
+
         private void processProperties(DeviceConfig.Properties properties) {
             boolean timeThresholdsUpdated = false;
             synchronized (mAppIdleLock) {
@@ -3182,11 +3212,16 @@
                         case KEY_SLICE_PINNED_HOLD_DURATION:
                             mSlicePinnedTimeoutMillis = properties.getLong(
                                     KEY_SLICE_PINNED_HOLD_DURATION,
-                                    DEFAULT_SLICE_PINNED_TIMEOUT);
+                                    Flags.adjustDefaultBucketElevationParams()
+                                            ? DEFAULT_CURRENT_SLICE_PINNED_TIMEOUT
+                                            : DEFAULT_LEGACY_SLICE_PINNED_TIMEOUT);
                             break;
                         case KEY_STRONG_USAGE_HOLD_DURATION:
                             mStrongUsageTimeoutMillis = properties.getLong(
-                                    KEY_STRONG_USAGE_HOLD_DURATION, DEFAULT_STRONG_USAGE_TIMEOUT);
+                                    KEY_STRONG_USAGE_HOLD_DURATION,
+                                    Flags.adjustDefaultBucketElevationParams()
+                                            ? DEFAULT_CURRENT_STRONG_USAGE_TIMEOUT
+                                            : DEFAULT_LEGACY_STRONG_USAGE_TIMEOUT);
                             break;
                         case KEY_PREDICTION_TIMEOUT:
                             mPredictionTimeoutMillis = properties.getLong(
@@ -3203,7 +3238,10 @@
                             break;
                         case KEY_SYNC_ADAPTER_HOLD_DURATION:
                             mSyncAdapterTimeoutMillis = properties.getLong(
-                                    KEY_SYNC_ADAPTER_HOLD_DURATION, DEFAULT_SYNC_ADAPTER_TIMEOUT);
+                                    KEY_SYNC_ADAPTER_HOLD_DURATION,
+                                    Flags.adjustDefaultBucketElevationParams()
+                                            ? DEFAULT_CURRENT_SYNC_ADAPTER_TIMEOUT
+                                            : DEFAULT_LEGACY_SYNC_ADAPTER_TIMEOUT);
                             break;
                         case KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION:
                             mExemptedSyncScheduledDozeTimeoutMillis = properties.getLong(
diff --git a/boot/boot-image-profile-extra.txt b/boot/boot-image-profile-extra.txt
index e31eb3a..fd51f9c 100644
--- a/boot/boot-image-profile-extra.txt
+++ b/boot/boot-image-profile-extra.txt
@@ -23,4 +23,25 @@
 # For now, compile all methods in MessageQueue to avoid performance cliffs for
 # flagged/evolving hot code paths. See: b/338098106
 HSPLandroid/os/MessageQueue;->*
-HSPLandroid/os/MessageQueue$*;->*
+HSPLandroid/os/MessageQueue$FileDescriptorRecord;->*
+HSPLandroid/os/MessageQueue$IdleHandler;->*
+HSPLandroid/os/MessageQueue$MessageCompare;->*
+HSPLandroid/os/MessageQueue$MatchAllFutureMessages;->*
+HSPLandroid/os/MessageQueue$MatchAllMessages;->*
+HSPLandroid/os/MessageQueue$MatchBarrierToken;->*
+HSPLandroid/os/MessageQueue$MatchDeliverableMessages;->*
+HSPLandroid/os/MessageQueue$MatchHandler;->*
+HSPLandroid/os/MessageQueue$MatchHandlerAndObject;->*
+HSPLandroid/os/MessageQueue$MatchHandlerAndObjectEquals;->*
+HSPLandroid/os/MessageQueue$MatchHandlerRunnableAndObject;->*
+HSPLandroid/os/MessageQueue$MatchHandlerRunnableAndObjectEquals;->*
+HSPLandroid/os/MessageQueue$MatchHandlerWhatAndObject;->*
+HSPLandroid/os/MessageQueue$MatchHandlerWhatAndObjectEquals;->*
+HSPLandroid/os/MessageQueue$MessageCounts;->*
+HSPLandroid/os/MessageQueue$StackNode;->*
+HSPLandroid/os/MessageQueue$MessageNode;->*
+HSPLandroid/os/MessageQueue$OnFileDescriptorEventListener$Events;->*
+HSPLandroid/os/MessageQueue$OnFileDescriptorEventListener;->*
+HSPLandroid/os/MessageQueue$StackNodeType;->*
+HSPLandroid/os/MessageQueue$StateNode;->*
+HSPLandroid/os/MessageQueue$TimedParkStateNode;->*
diff --git a/cmds/idmap2/idmap2/CreateMultiple.cpp b/cmds/idmap2/idmap2/CreateMultiple.cpp
index 68800cd..2608c69 100644
--- a/cmds/idmap2/idmap2/CreateMultiple.cpp
+++ b/cmds/idmap2/idmap2/CreateMultiple.cpp
@@ -99,7 +99,7 @@
 
   std::vector<std::string> idmap_paths;
   for (const std::string& overlay_apk_path : overlay_apk_paths) {
-    const std::string idmap_path = Idmap::CanonicalIdmapPathFor(idmap_dir, overlay_apk_path);
+    std::string idmap_path = Idmap::CanonicalIdmapPathFor(idmap_dir, overlay_apk_path);
     const uid_t uid = getuid();
     if (!UidHasWriteAccessToPath(uid, idmap_path)) {
       LOG(WARNING) << "uid " << uid << "does not have write access to " << idmap_path.c_str();
@@ -111,7 +111,7 @@
                 !ignore_overlayable)) {
       const auto overlay = OverlayResourceContainer::FromPath(overlay_apk_path);
       if (!overlay) {
-        LOG(WARNING) << "failed to load apk " << overlay_apk_path.c_str();
+        LOG(WARNING) << "failed to load apk " << overlay_apk_path;
         continue;
       }
 
@@ -138,7 +138,7 @@
       }
     }
 
-    idmap_paths.emplace_back(idmap_path);
+    idmap_paths.emplace_back(std::move(idmap_path));
   }
 
   for (const std::string& idmap_path : idmap_paths) {
diff --git a/cmds/interrupter/Android.bp b/cmds/interrupter/Android.bp
deleted file mode 100644
index d7f744d..0000000
--- a/cmds/interrupter/Android.bp
+++ /dev/null
@@ -1,20 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-cc_library_shared {
-    name: "interrupter",
-    host_supported: true,
-    srcs: ["interrupter.c"],
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wunused",
-        "-Wunreachable-code",
-    ],
-}
diff --git a/cmds/interrupter/interrupter.c b/cmds/interrupter/interrupter.c
deleted file mode 100644
index 8bb522a2..0000000
--- a/cmds/interrupter/interrupter.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-
-/**
- * The probability of a syscall failing from 0.0 to 1.0
- */
-#define PROBABILITY 0.9
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* for various intercepted calls */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <dlfcn.h>
-
-#include "interrupter.h"
-
-static int probability = PROBABILITY * RAND_MAX;
-
-static int maybe_interrupt() {
-    if (rand() < probability) {
-        return 1;
-    }
-    return 0;
-}
-
-DEFINE_INTERCEPT(read, ssize_t, int, void*, size_t);
-DEFINE_INTERCEPT(write, ssize_t, int, const void*, size_t);
-DEFINE_INTERCEPT(accept, int, int, struct sockaddr*, socklen_t*);
-DEFINE_INTERCEPT(creat, int, const char*, mode_t);
diff --git a/cmds/interrupter/interrupter.h b/cmds/interrupter/interrupter.h
deleted file mode 100644
index 9ad0277e..0000000
--- a/cmds/interrupter/interrupter.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define CONCATENATE(arg1, arg2)   CONCATENATE1(arg1, arg2)
-#define CONCATENATE1(arg1, arg2)  CONCATENATE2(arg1, arg2)
-#define CONCATENATE2(arg1, arg2)  arg1##arg2
-
-#define INTERRUPTER(sym) \
-    if (real_##sym == NULL) \
-        __init_##sym(); \
-    if (maybe_interrupt()) { \
-        errno = EINTR; \
-        return -1; \
-    }
-
-#define CALL_FUNCTION_1(sym, ret, type1) \
-ret (*real_##sym)(type1) = NULL; \
-ret sym(type1 arg1) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1); \
-}
-
-#define CALL_FUNCTION_2(sym, ret, type1, type2) \
-ret (*real_##sym)(type1, type2) = NULL; \
-ret sym(type1 arg1, type2 arg2) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1, arg2); \
-}
-
-#define CALL_FUNCTION_3(sym, ret, type1, type2, type3) \
-ret (*real_##sym)(type1, type2, type3) = NULL; \
-ret sym(type1 arg1, type2 arg2, type3 arg3) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1, arg2, arg3); \
-}
-
-#define CALL_FUNCTION_4(sym, ret, type1, type2, type3, type4) \
-ret (*real_##sym)(type1, type2, type3, type4) = NULL; \
-ret sym(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1, arg2, arg3, arg4); \
-}
-
-#define CALL_FUNCTION_5(sym, ret, type1, type2, type3, type4, type5) \
-ret (*real_##sym)(type1, type2, type3, type4, type5) = NULL; \
-ret sym(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1, arg2, arg3, arg4, arg5); \
-}
-
-#define DEFINE_INTERCEPT_N(N, sym, ret, ...) \
-static void __init_##sym(void); \
-CONCATENATE(CALL_FUNCTION_, N)(sym, ret, __VA_ARGS__) \
-static void __init_##sym(void) { \
-    real_##sym = dlsym(RTLD_NEXT, #sym); \
-    if (real_##sym == NULL) { \
-        fprintf(stderr, "Error hooking " #sym ": %s\n", dlerror()); \
-    } \
-}
-
-#define INTERCEPT_NARG(...) INTERCEPT_NARG_N(__VA_ARGS__, INTERCEPT_RSEQ_N())
-#define INTERCEPT_NARG_N(...) INTERCEPT_ARG_N(__VA_ARGS__)
-#define INTERCEPT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
-#define INTERCEPT_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0
-
-#define DEFINE_INTERCEPT(sym, ret, ...) DEFINE_INTERCEPT_N(INTERCEPT_NARG(__VA_ARGS__), sym, ret, __VA_ARGS__)
diff --git a/core/api/current.txt b/core/api/current.txt
index 76f3e5a..af7d6f1 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1502,6 +1502,7 @@
     field public static final int shadowRadius = 16843108; // 0x1010164
     field public static final int shape = 16843162; // 0x101019a
     field public static final int shareInterpolator = 16843195; // 0x10101bb
+    field @FlaggedApi("android.nfc.nfc_associated_role_services") public static final int shareRolePriority;
     field @Deprecated public static final int sharedUserId = 16842763; // 0x101000b
     field @Deprecated public static final int sharedUserLabel = 16843361; // 0x1010261
     field public static final int sharedUserMaxSdkVersion = 16844365; // 0x101064d
@@ -2451,6 +2452,7 @@
     field public static final int primary = 16908300; // 0x102000c
     field public static final int progress = 16908301; // 0x102000d
     field public static final int redo = 16908339; // 0x1020033
+    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final int remoteViewsMetricsId;
     field public static final int replaceText = 16908340; // 0x1020034
     field public static final int secondaryProgress = 16908303; // 0x102000f
     field public static final int selectAll = 16908319; // 0x102001f
@@ -9892,6 +9894,8 @@
     field public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
     field public static final String ACTION_APPWIDGET_RESTORED = "android.appwidget.action.APPWIDGET_RESTORED";
     field public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
+    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EVENT_CATEGORY_APPWIDGET = "android.appwidget";
+    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EVENT_TYPE_WIDGET_INTERACTION = "widget_interaction";
     field public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
     field public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds";
     field public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
@@ -9901,6 +9905,10 @@
     field public static final String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
     field public static final String EXTRA_CUSTOM_EXTRAS = "customExtras";
     field public static final String EXTRA_CUSTOM_INFO = "customInfo";
+    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_CLICKED_VIEWS = "android.appwidget.extra.EVENT_CLICKED_VIEWS";
+    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_DURATION_MS = "android.appwidget.extra.EVENT_DURATION_MS";
+    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_POSITION_RECT = "android.appwidget.extra.EVENT_POSITION_RECT";
+    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_SCROLLED_VIEWS = "android.appwidget.extra.EVENT_SCROLLED_VIEWS";
     field public static final String EXTRA_HOST_ID = "hostId";
     field public static final int INVALID_APPWIDGET_ID = 0; // 0x0
     field public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
@@ -13146,9 +13154,9 @@
     method public void setAppLabel(@Nullable CharSequence);
     method public void setAppPackageName(@Nullable String);
     method public void setApplicationEnabledSettingPersistent();
+    method @FlaggedApi("android.content.pm.sdk_dependency_installer") public void setAutoInstallDependenciesEnabled(boolean);
     method @Deprecated public void setAutoRevokePermissionsMode(boolean);
     method public void setDontKillApp(boolean);
-    method @FlaggedApi("android.content.pm.sdk_dependency_installer") public void setEnableAutoInstallDependencies(boolean);
     method public void setInstallLocation(int);
     method public void setInstallReason(int);
     method public void setInstallScenario(int);
@@ -13217,8 +13225,8 @@
   public abstract class PackageManager {
     ctor @Deprecated public PackageManager();
     method @Deprecated public abstract void addPackageToPreferred(@NonNull String);
-    method public abstract boolean addPermission(@NonNull android.content.pm.PermissionInfo);
-    method public abstract boolean addPermissionAsync(@NonNull android.content.pm.PermissionInfo);
+    method @Deprecated @FlaggedApi("android.permission.flags.permission_tree_apis_deprecated") public abstract boolean addPermission(@NonNull android.content.pm.PermissionInfo);
+    method @Deprecated @FlaggedApi("android.permission.flags.permission_tree_apis_deprecated") public abstract boolean addPermissionAsync(@NonNull android.content.pm.PermissionInfo);
     method @Deprecated public abstract void addPreferredActivity(@NonNull android.content.IntentFilter, int, @Nullable android.content.ComponentName[], @NonNull android.content.ComponentName);
     method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public boolean addWhitelistedRestrictedPermission(@NonNull String, @NonNull String, int);
     method public boolean canPackageQuery(@NonNull String, @NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -13359,7 +13367,7 @@
     method @NonNull public java.util.List<android.content.pm.PackageManager.Property> queryServiceProperty(@NonNull String);
     method public void relinquishUpdateOwnership(@NonNull String);
     method @Deprecated public abstract void removePackageFromPreferred(@NonNull String);
-    method public abstract void removePermission(@NonNull String);
+    method @Deprecated @FlaggedApi("android.permission.flags.permission_tree_apis_deprecated") public abstract void removePermission(@NonNull String);
     method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public boolean removeWhitelistedRestrictedPermission(@NonNull String, @NonNull String, int);
     method public void requestChecksums(@NonNull String, boolean, int, @NonNull java.util.List<java.security.cert.Certificate>, @NonNull android.content.pm.PackageManager.OnChecksumsReadyListener) throws java.security.cert.CertificateEncodingException, android.content.pm.PackageManager.NameNotFoundException;
     method @Nullable public abstract android.content.pm.ResolveInfo resolveActivity(@NonNull android.content.Intent, int);
@@ -18954,6 +18962,7 @@
     method @FlaggedApi("android.hardware.flags.luts_api") @NonNull public int[] getSamplingKeys();
     method @FlaggedApi("android.hardware.flags.luts_api") public int getSize();
     field @FlaggedApi("android.hardware.flags.luts_api") public static final int ONE_DIMENSION = 1; // 0x1
+    field @FlaggedApi("android.hardware.flags.luts_api") public static final int SAMPLING_KEY_CIE_Y = 2; // 0x2
     field @FlaggedApi("android.hardware.flags.luts_api") public static final int SAMPLING_KEY_MAX_RGB = 1; // 0x1
     field @FlaggedApi("android.hardware.flags.luts_api") public static final int SAMPLING_KEY_RGB = 0; // 0x0
     field @FlaggedApi("android.hardware.flags.luts_api") public static final int THREE_DIMENSION = 3; // 0x3
@@ -21098,6 +21107,7 @@
     method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl onCreateInputMethodInterface();
     method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
     method public boolean onGenericMotionEvent(android.view.MotionEvent);
+    method @FlaggedApi("android.view.inputmethod.verify_key_event") public boolean onShouldVerifyKeyEvent(@NonNull android.view.KeyEvent);
     method public boolean onTrackballEvent(android.view.MotionEvent);
   }
 
@@ -21115,6 +21125,7 @@
     method public void dispatchTrackballEvent(int, android.view.MotionEvent, android.view.inputmethod.InputMethodSession.EventCallback);
     method public boolean isEnabled();
     method public boolean isRevoked();
+    method @FlaggedApi("android.view.inputmethod.verify_key_event") public boolean onShouldVerifyKeyEvent(@NonNull android.view.KeyEvent);
     method public void revokeSelf();
     method public void setEnabled(boolean);
   }
@@ -23507,6 +23518,18 @@
     field public static final int HEVCProfileMain10HDR10 = 4096; // 0x1000
     field public static final int HEVCProfileMain10HDR10Plus = 8192; // 0x2000
     field public static final int HEVCProfileMainStill = 4; // 0x4
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseAac = 16908290; // 0x1020002
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseEnhancedAac = 17039362; // 0x1040002
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseEnhancedFlac = 17039364; // 0x1040004
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseEnhancedOpus = 17039361; // 0x1040001
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseEnhancedPcm = 17039368; // 0x1040008
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseFlac = 16908292; // 0x1020004
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseOpus = 16908289; // 0x1020001
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBasePcm = 16908296; // 0x1020008
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileSimpleAac = 16842754; // 0x1010002
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileSimpleFlac = 16842756; // 0x1010004
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileSimpleOpus = 16842753; // 0x1010001
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileSimplePcm = 16842760; // 0x1010008
     field public static final int MPEG2LevelH14 = 2; // 0x2
     field public static final int MPEG2LevelHL = 3; // 0x3
     field public static final int MPEG2LevelHP = 4; // 0x4
@@ -24152,6 +24175,8 @@
     field public static final String KEY_OPERATING_RATE = "operating-rate";
     field public static final String KEY_OUTPUT_REORDER_DEPTH = "output-reorder-depth";
     field public static final String KEY_PCM_ENCODING = "pcm-encoding";
+    field @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public static final String KEY_PICTURE_PROFILE_ID = "picture-profile-id";
+    field @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public static final String KEY_PICTURE_PROFILE_INSTANCE = "picture-profile-instance";
     field public static final String KEY_PICTURE_TYPE = "picture-type";
     field public static final String KEY_PIXEL_ASPECT_RATIO_HEIGHT = "sar-height";
     field public static final String KEY_PIXEL_ASPECT_RATIO_WIDTH = "sar-width";
@@ -24204,6 +24229,7 @@
     field public static final String MIMETYPE_AUDIO_FLAC = "audio/flac";
     field public static final String MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw";
     field public static final String MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
+    field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final String MIMETYPE_AUDIO_IAMF = "audio/iamf";
     field public static final String MIMETYPE_AUDIO_IEC61937 = "audio/x-iec61937";
     field public static final String MIMETYPE_AUDIO_MPEG = "audio/mpeg";
     field public static final String MIMETYPE_AUDIO_MPEGH_BL_L3 = "audio/mhm1.03";
@@ -25598,6 +25624,7 @@
     method public void addOnSpatializerStateChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerStateChangedListener);
     method public boolean canBeSpatialized(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioFormat);
     method public int getImmersiveAudioLevel();
+    method @FlaggedApi("android.media.audio.spatializer_capabilities") @NonNull public java.util.List<java.lang.Integer> getSpatializedChannelMasks();
     method public boolean isAvailable();
     method public boolean isEnabled();
     method public boolean isHeadTrackerAvailable();
@@ -27060,6 +27087,53 @@
 
 package android.media.quality {
 
+  @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class AmbientBacklightEvent implements android.os.Parcelable {
+    ctor public AmbientBacklightEvent(int, @Nullable android.media.quality.AmbientBacklightMetadata);
+    method public int describeContents();
+    method public int getEventType();
+    method @Nullable public android.media.quality.AmbientBacklightMetadata getMetadata();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int AMBIENT_BACKLIGHT_EVENT_DISABLED = 2; // 0x2
+    field public static final int AMBIENT_BACKLIGHT_EVENT_ENABLED = 1; // 0x1
+    field public static final int AMBIENT_BACKLIGHT_EVENT_INTERRUPTED = 4; // 0x4
+    field public static final int AMBIENT_BACKLIGHT_EVENT_METADATA = 3; // 0x3
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.quality.AmbientBacklightEvent> CREATOR;
+  }
+
+  @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class AmbientBacklightMetadata implements android.os.Parcelable {
+    ctor public AmbientBacklightMetadata(@NonNull String, int, int, int, int, int, @NonNull int[]);
+    method public int describeContents();
+    method public int getColorFormat();
+    method public int getCompressAlgorithm();
+    method @IntRange(from=0) public int getHorizontalZonesNumber();
+    method @NonNull public String getPackageName();
+    method public int getSource();
+    method @IntRange(from=0) public int getVerticalZonesNumber();
+    method @NonNull public int[] getZonesColors();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.quality.AmbientBacklightMetadata> CREATOR;
+  }
+
+  @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class AmbientBacklightSettings implements android.os.Parcelable {
+    ctor public AmbientBacklightSettings(int, int, int, int, int, boolean, int);
+    method public int describeContents();
+    method public int getColorFormat();
+    method @IntRange(from=0) public int getHorizontalZonesNumber();
+    method @IntRange(from=1) public int getMaxFps();
+    method public int getSource();
+    method public int getThreshold();
+    method @IntRange(from=0) public int getVerticalZonesNumber();
+    method public boolean isLetterboxOmitted();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int ALGORITHM_NONE = 0; // 0x0
+    field public static final int ALGORITHM_RLE = 1; // 0x1
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.quality.AmbientBacklightSettings> CREATOR;
+    field public static final int SOURCE_AUDIO = 1; // 0x1
+    field public static final int SOURCE_AUDIO_VIDEO = 3; // 0x3
+    field public static final int SOURCE_NONE = 0; // 0x0
+    field public static final int SOURCE_VIDEO = 2; // 0x2
+  }
+
   @FlaggedApi("android.media.tv.flags.media_quality_fw") public class MediaQualityContract {
   }
 
@@ -27070,17 +27144,41 @@
     field public static final String PARAMETER_SHARPNESS = "sharpness";
   }
 
+  public static final class MediaQualityContract.SoundQuality {
+    field public static final String PARAMETER_BALANCE = "balance";
+    field public static final String PARAMETER_BASS = "bass";
+    field public static final String PARAMETER_TREBLE = "treble";
+  }
+
   @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class MediaQualityManager {
     method public void createPictureProfile(@NonNull android.media.quality.PictureProfile);
+    method public void createSoundProfile(@NonNull android.media.quality.SoundProfile);
     method @NonNull public java.util.List<android.media.quality.PictureProfile> getAvailablePictureProfiles();
+    method @NonNull public java.util.List<android.media.quality.SoundProfile> getAvailableSoundProfiles();
     method @NonNull public java.util.List<android.media.quality.ParamCapability> getParamCapabilities(@NonNull java.util.List<java.lang.String>);
     method @Nullable public android.media.quality.PictureProfile getPictureProfile(int, @NonNull String);
+    method @Nullable public android.media.quality.SoundProfile getSoundProfile(int, @NonNull String);
+    method public boolean isAmbientBacklightEnabled();
     method public boolean isAutoPictureQualityEnabled();
+    method public boolean isAutoSoundQualityEnabled();
     method public boolean isSuperResolutionEnabled();
+    method public void registerAmbientBacklightCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.AmbientBacklightCallback);
     method public void registerPictureProfileCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.PictureProfileCallback);
+    method public void registerSoundProfileCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.SoundProfileCallback);
     method public void removePictureProfile(@NonNull String);
+    method public void removeSoundProfile(@NonNull String);
+    method public void setAmbientBacklightEnabled(boolean);
+    method public void setAmbientBacklightSettings(@NonNull android.media.quality.AmbientBacklightSettings);
+    method public void unregisterAmbientBacklightCallback(@NonNull android.media.quality.MediaQualityManager.AmbientBacklightCallback);
     method public void unregisterPictureProfileCallback(@NonNull android.media.quality.MediaQualityManager.PictureProfileCallback);
+    method public void unregisterSoundProfileCallback(@NonNull android.media.quality.MediaQualityManager.SoundProfileCallback);
     method public void updatePictureProfile(@NonNull String, @NonNull android.media.quality.PictureProfile);
+    method public void updateSoundProfile(@NonNull String, @NonNull android.media.quality.SoundProfile);
+  }
+
+  public abstract static class MediaQualityManager.AmbientBacklightCallback {
+    ctor public MediaQualityManager.AmbientBacklightCallback();
+    method public void onAmbientBacklightEvent(@NonNull android.media.quality.AmbientBacklightEvent);
   }
 
   public abstract static class MediaQualityManager.PictureProfileCallback {
@@ -27092,6 +27190,15 @@
     method public void onPictureProfileUpdated(@NonNull String, @NonNull android.media.quality.PictureProfile);
   }
 
+  public abstract static class MediaQualityManager.SoundProfileCallback {
+    ctor public MediaQualityManager.SoundProfileCallback();
+    method public void onError(int);
+    method public void onParamCapabilitiesChanged(@Nullable String, @NonNull java.util.List<android.media.quality.ParamCapability>);
+    method public void onSoundProfileAdded(@NonNull String, @NonNull android.media.quality.SoundProfile);
+    method public void onSoundProfileRemoved(@NonNull String, @NonNull android.media.quality.SoundProfile);
+    method public void onSoundProfileUpdated(@NonNull String, @NonNull android.media.quality.SoundProfile);
+  }
+
   @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class ParamCapability implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public android.os.Bundle getCapabilities();
@@ -27136,6 +27243,32 @@
     method @NonNull public android.media.quality.PictureProfile.Builder setParameters(@NonNull android.os.PersistableBundle);
   }
 
+  @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class SoundProfile implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public String getInputId();
+    method @NonNull public String getName();
+    method @Nullable public String getPackageName();
+    method @NonNull public android.os.PersistableBundle getParameters();
+    method @Nullable public String getProfileId();
+    method public int getProfileType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.quality.SoundProfile> CREATOR;
+    field public static final int ERROR_DUPLICATE = 2; // 0x2
+    field public static final int ERROR_INVALID_ARGUMENT = 3; // 0x3
+    field public static final int ERROR_NOT_ALLOWLISTED = 4; // 0x4
+    field public static final int ERROR_NO_PERMISSION = 1; // 0x1
+    field public static final int ERROR_UNKNOWN = 0; // 0x0
+    field public static final int TYPE_APPLICATION = 2; // 0x2
+    field public static final int TYPE_SYSTEM = 1; // 0x1
+  }
+
+  public static final class SoundProfile.Builder {
+    ctor public SoundProfile.Builder(@NonNull String);
+    ctor public SoundProfile.Builder(@NonNull android.media.quality.SoundProfile);
+    method @NonNull public android.media.quality.SoundProfile build();
+    method @NonNull public android.media.quality.SoundProfile.Builder setParameters(@NonNull android.os.PersistableBundle);
+  }
+
 }
 
 package android.media.session {
@@ -33479,9 +33612,14 @@
   @FlaggedApi("android.os.cpu_gpu_headrooms") public final class CpuHeadroomParams {
     ctor public CpuHeadroomParams();
     method public int getCalculationType();
+    method @IntRange(from=android.os.CpuHeadroomParams.CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to=android.os.CpuHeadroomParams.CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) public long getCalculationWindowMillis();
     method public void setCalculationType(int);
+    method public void setCalculationWindowMillis(@IntRange(from=android.os.CpuHeadroomParams.CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to=android.os.CpuHeadroomParams.CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int);
+    method public void setTids(@NonNull int...);
     field public static final int CPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; // 0x1
     field public static final int CPU_HEADROOM_CALCULATION_TYPE_MIN = 0; // 0x0
+    field public static final int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000; // 0x2710
+    field public static final int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50; // 0x32
   }
 
   public final class CpuUsageInfo implements android.os.Parcelable {
@@ -33734,9 +33872,13 @@
   @FlaggedApi("android.os.cpu_gpu_headrooms") public final class GpuHeadroomParams {
     ctor public GpuHeadroomParams();
     method public int getCalculationType();
+    method @IntRange(from=android.os.GpuHeadroomParams.GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to=android.os.GpuHeadroomParams.GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) public int getCalculationWindowMillis();
     method public void setCalculationType(int);
+    method public void setCalculationWindowMillis(@IntRange(from=android.os.GpuHeadroomParams.GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to=android.os.GpuHeadroomParams.GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int);
     field public static final int GPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; // 0x1
     field public static final int GPU_HEADROOM_CALCULATION_TYPE_MIN = 0; // 0x0
+    field public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000; // 0x2710
+    field public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50; // 0x32
   }
 
   public class Handler {
@@ -34849,6 +34991,13 @@
     field public static final int EFFECT_TICK = 2; // 0x2
   }
 
+  @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public static final class VibrationEffect.BasicEnvelopeBuilder {
+    ctor public VibrationEffect.BasicEnvelopeBuilder();
+    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.BasicEnvelopeBuilder addControlPoint(@FloatRange(from=0, to=1) float, @FloatRange(from=0, to=1) float, long);
+    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect build();
+    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.BasicEnvelopeBuilder setInitialSharpness(@FloatRange(from=0, to=1) float);
+  }
+
   public static final class VibrationEffect.Composition {
     method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int);
     method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float);
@@ -34869,7 +35018,7 @@
 
   @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public static final class VibrationEffect.WaveformEnvelopeBuilder {
     ctor public VibrationEffect.WaveformEnvelopeBuilder();
-    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.WaveformEnvelopeBuilder addControlPoint(@FloatRange(from=0, to=1) float, @FloatRange(from=0) float, int);
+    method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.WaveformEnvelopeBuilder addControlPoint(@FloatRange(from=0, to=1) float, @FloatRange(from=0) float, long);
     method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect build();
     method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.WaveformEnvelopeBuilder setInitialFrequencyHz(@FloatRange(from=0) float);
   }
@@ -37573,7 +37722,6 @@
   }
 
   @FlaggedApi("android.provider.new_default_account_api_enabled") public static final class ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState {
-    ctor public ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState(int, @Nullable android.accounts.Account);
     method @Nullable public android.accounts.Account getAccount();
     method public int getState();
     method @NonNull public static android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState ofCloud(@NonNull android.accounts.Account);
@@ -42455,7 +42603,7 @@
     method @NonNull public java.util.List<java.lang.String> getBreadcrumbs();
     method @NonNull public android.os.Bundle getExtras();
     method @NonNull public String getKey();
-    method @Nullable public android.app.PendingIntent getLaunchIntent();
+    method @Nullable public android.content.Intent getLaunchIntent();
     method @NonNull public java.util.List<java.lang.String> getReadPermissions();
     method @NonNull public String getScreenKey();
     method @Nullable public String getSummary();
@@ -42480,7 +42628,7 @@
     method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setBreadcrumbs(@NonNull java.util.List<java.lang.String>);
     method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setEnabled(boolean);
     method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setExtras(@NonNull android.os.Bundle);
-    method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setLaunchIntent(@Nullable android.app.PendingIntent);
+    method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setLaunchIntent(@Nullable android.content.Intent);
     method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setReadPermissions(@NonNull java.util.List<java.lang.String>);
     method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setRestricted(boolean);
     method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setSummary(@Nullable String);
@@ -42500,19 +42648,18 @@
   }
 
   @FlaggedApi("com.android.settingslib.flags.settings_catalyst") public class SettingsPreferenceServiceClient implements java.lang.AutoCloseable {
-    ctor public SettingsPreferenceServiceClient(@NonNull android.content.Context, @NonNull String);
+    ctor public SettingsPreferenceServiceClient(@NonNull android.content.Context, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.SettingsPreferenceServiceClient,java.lang.Exception>);
     method public void close();
     method public void getAllPreferenceMetadata(@NonNull android.service.settings.preferences.MetadataRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.MetadataResult,java.lang.Exception>);
     method public void getPreferenceValue(@NonNull android.service.settings.preferences.GetValueRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.GetValueResult,java.lang.Exception>);
     method public void setPreferenceValue(@NonNull android.service.settings.preferences.SetValueRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.SetValueResult,java.lang.Exception>);
-    method public void start();
-    method public void stop();
   }
 
   @FlaggedApi("com.android.settingslib.flags.settings_catalyst") public final class SettingsPreferenceValue implements android.os.Parcelable {
     method public int describeContents();
     method public boolean getBooleanValue();
     method public double getDoubleValue();
+    method public int getIntValue();
     method public long getLongValue();
     method @Nullable public String getStringValue();
     method public int getType();
@@ -42520,6 +42667,7 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.service.settings.preferences.SettingsPreferenceValue> CREATOR;
     field public static final int TYPE_BOOLEAN = 0; // 0x0
     field public static final int TYPE_DOUBLE = 2; // 0x2
+    field public static final int TYPE_INT = 4; // 0x4
     field public static final int TYPE_LONG = 1; // 0x1
     field public static final int TYPE_STRING = 3; // 0x3
   }
@@ -42529,6 +42677,7 @@
     method @NonNull public android.service.settings.preferences.SettingsPreferenceValue build();
     method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setBooleanValue(boolean);
     method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setDoubleValue(double);
+    method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setIntValue(int);
     method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setLongValue(long);
     method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setStringValue(@Nullable String);
   }
@@ -50312,9 +50461,9 @@
   public static class TtsSpan.TimeBuilder extends android.text.style.TtsSpan.SemioticClassBuilder<android.text.style.TtsSpan.TimeBuilder> {
     ctor public TtsSpan.TimeBuilder();
     ctor public TtsSpan.TimeBuilder(int, int);
-    method public android.text.style.TtsSpan.TimeBuilder setHours(int);
-    method public android.text.style.TtsSpan.TimeBuilder setMinutes(int);
-    method @FlaggedApi("com.android.text.flags.tts_span_duration") @NonNull public android.text.style.TtsSpan.TimeBuilder setSeconds(int);
+    method public android.text.style.TtsSpan.TimeBuilder setHours(@IntRange(from=0, to=24) int);
+    method public android.text.style.TtsSpan.TimeBuilder setMinutes(@IntRange(from=0, to=59) int);
+    method @FlaggedApi("com.android.text.flags.tts_span_duration") @NonNull public android.text.style.TtsSpan.TimeBuilder setSeconds(@IntRange(from=0, to=59) int);
   }
 
   public static class TtsSpan.VerbatimBuilder extends android.text.style.TtsSpan.SemioticClassBuilder<android.text.style.TtsSpan.VerbatimBuilder> {
@@ -51797,7 +51946,7 @@
     method public int getState();
     method @FlaggedApi("com.android.server.display.feature.flags.enable_get_suggested_frame_rate") public float getSuggestedFrameRate(int);
     method public android.view.Display.Mode[] getSupportedModes();
-    method @Deprecated public float[] getSupportedRefreshRates();
+    method @FlaggedApi("com.android.server.display.feature.flags.enable_get_supported_refresh_rates") @NonNull public float[] getSupportedRefreshRates();
     method @Deprecated public int getWidth();
     method @FlaggedApi("com.android.server.display.feature.flags.enable_has_arr_support") public boolean hasArrSupport();
     method public boolean isHdr();
@@ -53406,6 +53555,7 @@
     method @NonNull public android.view.SurfaceControl.Transaction setBuffer(@NonNull android.view.SurfaceControl, @Nullable android.hardware.HardwareBuffer, @Nullable android.hardware.SyncFence, @Nullable java.util.function.Consumer<android.hardware.SyncFence>);
     method @NonNull public android.view.SurfaceControl.Transaction setBufferSize(@NonNull android.view.SurfaceControl, @IntRange(from=0) int, @IntRange(from=0) int);
     method @NonNull public android.view.SurfaceControl.Transaction setBufferTransform(@NonNull android.view.SurfaceControl, int);
+    method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") @NonNull public android.view.SurfaceControl.Transaction setContentPriority(@NonNull android.view.SurfaceControl, int);
     method @NonNull public android.view.SurfaceControl.Transaction setCrop(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect);
     method @NonNull public android.view.SurfaceControl.Transaction setDamageRegion(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Region);
     method @NonNull public android.view.SurfaceControl.Transaction setDataSpace(@NonNull android.view.SurfaceControl, int);
@@ -56354,6 +56504,7 @@
     method public float getMin();
     method public int getType();
     method @Deprecated public static android.view.accessibility.AccessibilityNodeInfo.RangeInfo obtain(int, float, float, float);
+    field @FlaggedApi("android.view.accessibility.indeterminate_range_info") @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.RangeInfo INDETERMINATE;
     field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
     field @FlaggedApi("android.view.accessibility.indeterminate_range_info") public static final int RANGE_TYPE_INDETERMINATE = 3; // 0x3
     field public static final int RANGE_TYPE_INT = 0; // 0x0
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index c184ba5..83699ac 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -34,6 +34,7 @@
     field public static final String ACCESS_VIBRATOR_STATE = "android.permission.ACCESS_VIBRATOR_STATE";
     field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
     field public static final String ADD_ALWAYS_UNLOCKED_DISPLAY = "android.permission.ADD_ALWAYS_UNLOCKED_DISPLAY";
+    field @FlaggedApi("android.companion.virtualdevice.flags.enable_limited_vdm_role") public static final String ADD_MIRROR_DISPLAY = "android.permission.ADD_MIRROR_DISPLAY";
     field public static final String ADD_TRUSTED_DISPLAY = "android.permission.ADD_TRUSTED_DISPLAY";
     field public static final String ADJUST_RUNTIME_PERMISSIONS_POLICY = "android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY";
     field public static final String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
@@ -94,7 +95,6 @@
     field public static final String BIND_TRANSLATION_SERVICE = "android.permission.BIND_TRANSLATION_SERVICE";
     field public static final String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
     field public static final String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE";
-    field @FlaggedApi("android.content.pm.verification_service") public static final String BIND_VERIFICATION_AGENT = "android.permission.BIND_VERIFICATION_AGENT";
     field public static final String BIND_VISUAL_QUERY_DETECTION_SERVICE = "android.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE";
     field public static final String BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE = "android.permission.BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE";
     field public static final String BIND_WEARABLE_SENSING_SERVICE = "android.permission.BIND_WEARABLE_SENSING_SERVICE";
@@ -194,6 +194,7 @@
     field public static final String MANAGE_ACCESSIBILITY = "android.permission.MANAGE_ACCESSIBILITY";
     field @Deprecated public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
     field public static final String MANAGE_ACTIVITY_TASKS = "android.permission.MANAGE_ACTIVITY_TASKS";
+    field @FlaggedApi("android.security.aapm_api") public static final String MANAGE_ADVANCED_PROTECTION_MODE = "android.permission.MANAGE_ADVANCED_PROTECTION_MODE";
     field public static final String MANAGE_APP_HIBERNATION = "android.permission.MANAGE_APP_HIBERNATION";
     field public static final String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS";
     field public static final String MANAGE_APP_PREDICTIONS = "android.permission.MANAGE_APP_PREDICTIONS";
@@ -376,7 +377,6 @@
     field public static final String SERIAL_PORT = "android.permission.SERIAL_PORT";
     field @FlaggedApi("android.security.fsverity_api") public static final String SETUP_FSVERITY = "android.permission.SETUP_FSVERITY";
     field public static final String SET_ACTIVITY_WATCHER = "android.permission.SET_ACTIVITY_WATCHER";
-    field @FlaggedApi("android.security.aapm_api") public static final String SET_ADVANCED_PROTECTION_MODE = "android.permission.SET_ADVANCED_PROTECTION_MODE";
     field public static final String SET_CLIP_SOURCE = "android.permission.SET_CLIP_SOURCE";
     field public static final String SET_DEFAULT_ACCOUNT_FOR_CONTACTS = "android.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS";
     field public static final String SET_HARMFUL_APP_WARNINGS = "android.permission.SET_HARMFUL_APP_WARNINGS";
@@ -430,7 +430,6 @@
     field @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public static final String USE_ON_DEVICE_INTELLIGENCE = "android.permission.USE_ON_DEVICE_INTELLIGENCE";
     field public static final String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK";
     field public static final String UWB_PRIVILEGED = "android.permission.UWB_PRIVILEGED";
-    field @FlaggedApi("android.content.pm.verification_service") public static final String VERIFICATION_AGENT = "android.permission.VERIFICATION_AGENT";
     field @FlaggedApi("android.os.vibrator.vendor_vibration_effects") public static final String VIBRATE_VENDOR_EFFECTS = "android.permission.VIBRATE_VENDOR_EFFECTS";
     field public static final String WHITELIST_AUTO_REVOKE_PERMISSIONS = "android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS";
     field public static final String WHITELIST_RESTRICTED_PERMISSIONS = "android.permission.WHITELIST_RESTRICTED_PERMISSIONS";
@@ -2324,6 +2323,24 @@
     field public static final int FEATURE_STATUS_UNAVAILABLE = 0; // 0x0
   }
 
+  @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence_module") public final class InferenceInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getEndTimeMillis();
+    method public long getStartTimeMillis();
+    method public long getSuspendedTimeMillis();
+    method public int getUid();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.ondeviceintelligence.InferenceInfo> CREATOR;
+  }
+
+  public static final class InferenceInfo.Builder {
+    ctor public InferenceInfo.Builder(int);
+    method @NonNull public android.app.ondeviceintelligence.InferenceInfo build();
+    method @NonNull public android.app.ondeviceintelligence.InferenceInfo.Builder setEndTimeMillis(long);
+    method @NonNull public android.app.ondeviceintelligence.InferenceInfo.Builder setStartTimeMillis(long);
+    method @NonNull public android.app.ondeviceintelligence.InferenceInfo.Builder setSuspendedTimeMillis(long);
+  }
+
   @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public class OnDeviceIntelligenceException extends java.lang.Exception {
     ctor public OnDeviceIntelligenceException(int, @NonNull String, @NonNull android.os.PersistableBundle);
     ctor public OnDeviceIntelligenceException(int, @NonNull android.os.PersistableBundle);
@@ -2353,6 +2370,7 @@
   @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public final class OnDeviceIntelligenceManager {
     method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void getFeature(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.app.ondeviceintelligence.Feature,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
     method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void getFeatureDetails(@NonNull android.app.ondeviceintelligence.Feature, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.app.ondeviceintelligence.FeatureDetails,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
+    method @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence_module") @NonNull @RequiresPermission(android.Manifest.permission.DUMP) public java.util.List<android.app.ondeviceintelligence.InferenceInfo> getLatestInferenceInfo(long);
     method @Nullable @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public String getRemoteServicePackageName();
     method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void getVersion(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.LongConsumer);
     method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void listFeatures(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.util.List<android.app.ondeviceintelligence.Feature>,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
@@ -3418,14 +3436,14 @@
   public class WearableSensingManager {
     method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public int getAvailableConnectionCount();
     method @Nullable public static android.app.wearable.WearableSensingDataRequest getDataRequestFromIntent(@NonNull android.content.Intent);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideConnection(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @Deprecated @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideConnection(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideConnection(@NonNull android.app.wearable.WearableConnection, @NonNull java.util.concurrent.Executor);
     method @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideData(@NonNull android.os.PersistableBundle, @Nullable android.os.SharedMemory, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideDataStream(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @FlaggedApi("android.app.wearable.enable_provide_read_only_pfd") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideReadOnlyParcelFileDescriptor(@NonNull android.os.ParcelFileDescriptor, @NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void registerDataRequestObserver(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void removeAllConnections();
-    method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public boolean removeConnection(@NonNull android.app.wearable.WearableConnection);
+    method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void removeConnection(@NonNull android.app.wearable.WearableConnection);
     method @FlaggedApi("android.app.wearable.enable_hotword_wearable_sensing_api") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void startHotwordRecognition(@Nullable android.content.ComponentName, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @FlaggedApi("android.app.wearable.enable_hotword_wearable_sensing_api") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void stopHotwordRecognition(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void unregisterDataRequestObserver(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
@@ -3922,6 +3940,7 @@
     field public static final String WIFI_NL80211_SERVICE = "wifinl80211";
     field @Deprecated public static final String WIFI_RTT_SERVICE = "rttmanager";
     field public static final String WIFI_SCANNING_SERVICE = "wifiscanner";
+    field @FlaggedApi("android.net.wifi.flags.usd") public static final String WIFI_USD_SERVICE = "wifi_usd";
   }
 
   public final class ContextParams {
@@ -4227,13 +4246,12 @@
   }
 
   public class PackageInstaller {
-    method @FlaggedApi("android.content.pm.verification_service") @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public final int getVerificationPolicy();
     method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull java.io.File, int) throws android.content.pm.PackageInstaller.PackageParsingException;
     method @FlaggedApi("android.content.pm.read_install_info") @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull android.os.ParcelFileDescriptor, @Nullable String, int) throws android.content.pm.PackageInstaller.PackageParsingException;
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
-    method @FlaggedApi("android.content.pm.verification_service") @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public final boolean setVerificationPolicy(int);
     field public static final String ACTION_CONFIRM_INSTALL = "android.content.pm.action.CONFIRM_INSTALL";
     field public static final String ACTION_CONFIRM_PRE_APPROVAL = "android.content.pm.action.CONFIRM_PRE_APPROVAL";
+    field @FlaggedApi("android.content.pm.sdk_dependency_installer") public static final String ACTION_INSTALL_DEPENDENCY = "android.content.pm.action.INSTALL_DEPENDENCY";
     field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2
     field public static final int DATA_LOADER_TYPE_NONE = 0; // 0x0
     field public static final int DATA_LOADER_TYPE_STREAMING = 1; // 0x1
@@ -4242,20 +4260,12 @@
     field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_DELETE_FLAGS = "android.content.pm.extra.DELETE_FLAGS";
     field public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
     field @Deprecated public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH";
-    field @FlaggedApi("android.content.pm.verification_service") public static final String EXTRA_VERIFICATION_FAILURE_REASON = "android.content.pm.extra.VERIFICATION_FAILURE_REASON";
     field public static final int LOCATION_DATA_APP = 0; // 0x0
     field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
     field public static final int LOCATION_MEDIA_OBB = 1; // 0x1
     field public static final int REASON_CONFIRM_PACKAGE_CHANGE = 0; // 0x0
     field public static final int REASON_OWNERSHIP_CHANGED = 1; // 0x1
     field public static final int REASON_REMIND_OWNERSHIP = 2; // 0x2
-    field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE = 1; // 0x1
-    field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED = 2; // 0x2
-    field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_FAILED_REASON_UNKNOWN = 0; // 0x0
-    field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_POLICY_BLOCK_FAIL_CLOSED = 3; // 0x3
-    field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_POLICY_BLOCK_FAIL_OPEN = 1; // 0x1
-    field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_POLICY_BLOCK_FAIL_WARN = 2; // 0x2
-    field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_POLICY_NONE = 0; // 0x0
   }
 
   public static class PackageInstaller.InstallInfo {
@@ -4375,7 +4385,6 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, @NonNull java.util.List<java.lang.String>);
     field public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS";
     field public static final String ACTION_REQUEST_PERMISSIONS_FOR_OTHER = "android.content.pm.action.REQUEST_PERMISSIONS_FOR_OTHER";
-    field @FlaggedApi("android.content.pm.verification_service") public static final String ACTION_VERIFY_PACKAGE = "android.content.pm.action.VERIFY_PACKAGE";
     field @FlaggedApi("android.content.pm.asl_in_apk_app_metadata_source") public static final int APP_METADATA_SOURCE_APK = 1; // 0x1
     field @FlaggedApi("android.content.pm.asl_in_apk_app_metadata_source") public static final int APP_METADATA_SOURCE_INSTALLER = 2; // 0x2
     field @FlaggedApi("android.content.pm.asl_in_apk_app_metadata_source") public static final int APP_METADATA_SOURCE_SYSTEM_IMAGE = 3; // 0x3
@@ -4707,62 +4716,6 @@
 
 }
 
-package android.content.pm.verify.pkg {
-
-  @FlaggedApi("android.content.pm.verification_service") public final class VerificationSession implements android.os.Parcelable {
-    method public int describeContents();
-    method public long extendTimeRemaining(long);
-    method @NonNull public java.util.List<android.content.pm.SharedLibraryInfo> getDeclaredLibraries();
-    method @NonNull public android.os.PersistableBundle getExtensionParams();
-    method public int getId();
-    method public int getInstallSessionId();
-    method @NonNull public String getPackageName();
-    method @NonNull public android.content.pm.SigningInfo getSigningInfo();
-    method @NonNull public android.net.Uri getStagedPackageUri();
-    method public long getTimeoutTime();
-    method public int getVerificationPolicy();
-    method public void reportVerificationComplete(@NonNull android.content.pm.verify.pkg.VerificationStatus);
-    method public void reportVerificationComplete(@NonNull android.content.pm.verify.pkg.VerificationStatus, @NonNull android.os.PersistableBundle);
-    method public void reportVerificationIncomplete(int);
-    method public boolean setVerificationPolicy(int);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.verify.pkg.VerificationSession> CREATOR;
-    field public static final int VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE = 1; // 0x1
-    field public static final int VERIFICATION_INCOMPLETE_UNKNOWN = 0; // 0x0
-  }
-
-  @FlaggedApi("android.content.pm.verification_service") public final class VerificationStatus implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getAslStatus();
-    method @NonNull public String getFailureMessage();
-    method public boolean isVerified();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.verify.pkg.VerificationStatus> CREATOR;
-    field public static final int VERIFIER_STATUS_ASL_BAD = 2; // 0x2
-    field public static final int VERIFIER_STATUS_ASL_GOOD = 1; // 0x1
-    field public static final int VERIFIER_STATUS_ASL_UNDEFINED = 0; // 0x0
-  }
-
-  public static final class VerificationStatus.Builder {
-    ctor public VerificationStatus.Builder();
-    method @NonNull public android.content.pm.verify.pkg.VerificationStatus build();
-    method @NonNull public android.content.pm.verify.pkg.VerificationStatus.Builder setAslStatus(int);
-    method @NonNull public android.content.pm.verify.pkg.VerificationStatus.Builder setFailureMessage(@NonNull String);
-    method @NonNull public android.content.pm.verify.pkg.VerificationStatus.Builder setVerified(boolean);
-  }
-
-  @FlaggedApi("android.content.pm.verification_service") public abstract class VerifierService extends android.app.Service {
-    ctor public VerifierService();
-    method @Nullable public android.os.IBinder onBind(@Nullable android.content.Intent);
-    method public abstract void onPackageNameAvailable(@NonNull String);
-    method public abstract void onVerificationCancelled(@NonNull String);
-    method public abstract void onVerificationRequired(@NonNull android.content.pm.verify.pkg.VerificationSession);
-    method public abstract void onVerificationRetry(@NonNull android.content.pm.verify.pkg.VerificationSession);
-    method public abstract void onVerificationTimeout(int);
-  }
-
-}
-
 package android.content.rollback {
 
   public final class PackageRollbackInfo implements android.os.Parcelable {
@@ -5257,6 +5210,11 @@
     method @NonNull public java.util.Collection<android.hardware.contexthub.HubServiceInfo> getServiceInfoCollection();
     method @Nullable public String getTag();
     method public int getVersion();
+    field public static final int REASON_CLOSE_ENDPOINT_SESSION_REQUESTED = 4; // 0x4
+    field public static final int REASON_ENDPOINT_INVALID = 5; // 0x5
+    field public static final int REASON_ENDPOINT_STOPPED = 6; // 0x6
+    field public static final int REASON_FAILURE = 0; // 0x0
+    field public static final int REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED = 3; // 0x3
   }
 
   public static final class HubEndpoint.Builder {
@@ -5323,9 +5281,8 @@
   }
 
   @FlaggedApi("android.chre.flags.offload_api") public final class HubServiceInfo implements android.os.Parcelable {
-    ctor public HubServiceInfo(@NonNull String, int, int, int, @NonNull android.os.ParcelableHolder);
+    ctor public HubServiceInfo(@NonNull String, int, int, int);
     method public int describeContents();
-    method @NonNull public android.os.ParcelableHolder getExtendedInfo();
     method public int getFormat();
     method public int getMajorVersion();
     method public int getMinorVersion();
@@ -5340,16 +5297,17 @@
   public static final class HubServiceInfo.Builder {
     ctor public HubServiceInfo.Builder(@NonNull String, int, int, int);
     method @NonNull public android.hardware.contexthub.HubServiceInfo build();
-    method @NonNull public android.hardware.contexthub.HubServiceInfo.Builder setExtendedInfo(@Nullable android.os.Parcelable);
+  }
+
+  @FlaggedApi("android.chre.flags.offload_api") public interface IHubEndpointDiscoveryCallback {
+    method public void onEndpointsStarted(@NonNull java.util.List<android.hardware.contexthub.HubDiscoveryInfo>);
+    method public void onEndpointsStopped(@NonNull java.util.List<android.hardware.contexthub.HubDiscoveryInfo>, int);
   }
 
   @FlaggedApi("android.chre.flags.offload_api") public interface IHubEndpointLifecycleCallback {
     method public void onSessionClosed(@NonNull android.hardware.contexthub.HubEndpointSession, int);
     method @NonNull public android.hardware.contexthub.HubEndpointSessionResult onSessionOpenRequest(@NonNull android.hardware.contexthub.HubEndpointInfo, @Nullable android.hardware.contexthub.HubServiceInfo);
     method public void onSessionOpened(@NonNull android.hardware.contexthub.HubEndpointSession);
-    field public static final int REASON_CLOSE_ENDPOINT_SESSION_REQUESTED = 4; // 0x4
-    field public static final int REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED = 3; // 0x3
-    field public static final int REASON_UNSPECIFIED = 0; // 0x0
   }
 
   @FlaggedApi("android.chre.flags.offload_api") public interface IHubEndpointMessageCallback {
@@ -6365,11 +6323,16 @@
     method @Deprecated public int registerCallback(@NonNull android.hardware.location.ContextHubManager.Callback);
     method @Deprecated public int registerCallback(android.hardware.location.ContextHubManager.Callback, android.os.Handler);
     method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpoint(@NonNull android.hardware.contexthub.HubEndpoint);
+    method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpointDiscoveryCallback(long, @NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback);
+    method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpointDiscoveryCallback(long, @NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback, @NonNull java.util.concurrent.Executor);
+    method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpointDiscoveryCallback(@NonNull String, @NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback);
+    method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpointDiscoveryCallback(@NonNull String, @NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback, @NonNull java.util.concurrent.Executor);
     method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public int sendMessage(int, int, @NonNull android.hardware.location.ContextHubMessage);
     method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public int unloadNanoApp(int);
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public android.hardware.location.ContextHubTransaction<java.lang.Void> unloadNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
     method @Deprecated public int unregisterCallback(@NonNull android.hardware.location.ContextHubManager.Callback);
     method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void unregisterEndpoint(@NonNull android.hardware.contexthub.HubEndpoint);
+    method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void unregisterEndpointDiscoveryCallback(@NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback);
     field public static final int AUTHORIZATION_DENIED = 0; // 0x0
     field public static final int AUTHORIZATION_DENIED_GRACE_PERIOD = 1; // 0x1
     field public static final int AUTHORIZATION_GRANTED = 2; // 0x2
@@ -7674,9 +7637,11 @@
     method public boolean isActive();
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean isMuted();
     method public boolean isSpatialized();
-    field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_APP_OPS = 8; // 0x8
+    field @Deprecated @FlaggedApi("android.media.audio.muted_by_port_volume_api") @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_APP_OPS = 8; // 0x8
     field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_CLIENT_VOLUME = 16; // 0x10
     field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_MASTER = 1; // 0x1
+    field @FlaggedApi("android.media.audio.muted_by_port_volume_api") @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_OP_CONTROL_AUDIO = 128; // 0x80
+    field @FlaggedApi("android.media.audio.muted_by_port_volume_api") @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_OP_PLAY_AUDIO = 8; // 0x8
     field @FlaggedApi("android.media.audio.muted_by_port_volume_api") @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_PORT_VOLUME = 64; // 0x40
     field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_STREAM_MUTED = 4; // 0x4
     field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_STREAM_VOLUME = 2; // 0x2
@@ -8160,8 +8125,13 @@
     method @NonNull public java.util.List<java.lang.String> getPictureProfileAllowList();
     method @NonNull public java.util.List<java.lang.String> getPictureProfilePackageNames();
     method @NonNull public java.util.List<android.media.quality.PictureProfile> getPictureProfilesByPackage(@NonNull String);
+    method @NonNull public java.util.List<java.lang.String> getSoundProfileAllowList();
+    method @NonNull public java.util.List<java.lang.String> getSoundProfilePackageNames();
+    method @NonNull public java.util.List<android.media.quality.SoundProfile> getSoundProfilesByPackage(@NonNull String);
     method public void setAutoPictureQualityEnabled(boolean);
+    method public void setAutoSoundQualityEnabled(boolean);
     method public void setPictureProfileAllowList(@NonNull java.util.List<java.lang.String>);
+    method public void setSoundProfileAllowList(@NonNull java.util.List<java.lang.String>);
     method public void setSuperResolutionEnabled(boolean);
   }
 
@@ -8171,6 +8141,20 @@
     method @NonNull public android.media.quality.PictureProfile.Builder setProfileType(int);
   }
 
+  @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public final class PictureProfileHandle implements android.os.Parcelable {
+    method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public int describeContents();
+    method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public long getId();
+    method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @FlaggedApi("android.media.tv.flags.apply_picture_profiles") @NonNull public static final android.os.Parcelable.Creator<android.media.quality.PictureProfileHandle> CREATOR;
+    field @NonNull public static final android.media.quality.PictureProfileHandle NONE;
+  }
+
+  public static final class SoundProfile.Builder {
+    method @NonNull public android.media.quality.SoundProfile.Builder setInputId(@NonNull String);
+    method @NonNull public android.media.quality.SoundProfile.Builder setPackageName(@NonNull String);
+    method @NonNull public android.media.quality.SoundProfile.Builder setProfileType(int);
+  }
+
 }
 
 package android.media.session {
@@ -11141,6 +11125,7 @@
     method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setDynamicAidGroup(@NonNull android.nfc.cardemulation.AidGroup);
     method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setOffHostSecureElement(@NonNull String);
     method @FlaggedApi("android.nfc.nfc_observe_mode") public void setShouldDefaultToObserveMode(boolean);
+    method @FlaggedApi("android.nfc.nfc_associated_role_services") public boolean shareRolePriority();
     method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean shouldDefaultToObserveMode();
     method @FlaggedApi("android.nfc.enable_nfc_mainline") public void writeToParcel(@NonNull android.os.Parcel, int);
     field @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.ApduServiceInfo> CREATOR;
@@ -12848,8 +12833,8 @@
 
   @FlaggedApi("android.security.aapm_api") public final class AdvancedProtectionManager {
     method @NonNull public android.content.Intent createSupportIntent(@NonNull String, @Nullable String);
-    method @NonNull @RequiresPermission(android.Manifest.permission.SET_ADVANCED_PROTECTION_MODE) public java.util.List<android.security.advancedprotection.AdvancedProtectionFeature> getAdvancedProtectionFeatures();
-    method @RequiresPermission(android.Manifest.permission.SET_ADVANCED_PROTECTION_MODE) public void setAdvancedProtectionEnabled(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) public java.util.List<android.security.advancedprotection.AdvancedProtectionFeature> getAdvancedProtectionFeatures();
+    method @RequiresPermission(android.Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) public void setAdvancedProtectionEnabled(boolean);
     field @FlaggedApi("android.security.aapm_api") public static final String ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG = "android.security.advancedprotection.action.SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG";
     field public static final String EXTRA_SUPPORT_DIALOG_FEATURE = "android.security.advancedprotection.extra.SUPPORT_DIALOG_FEATURE";
     field public static final String EXTRA_SUPPORT_DIALOG_TYPE = "android.security.advancedprotection.extra.SUPPORT_DIALOG_TYPE";
@@ -12896,6 +12881,30 @@
 
 package android.security.intrusiondetection {
 
+  @FlaggedApi("android.security.afl_api") public final class IntrusionDetectionEvent implements android.os.Parcelable {
+    ctor public IntrusionDetectionEvent(@NonNull android.app.admin.SecurityLog.SecurityEvent);
+    ctor public IntrusionDetectionEvent(@NonNull android.app.admin.DnsEvent);
+    ctor public IntrusionDetectionEvent(@NonNull android.app.admin.ConnectEvent);
+    method @FlaggedApi("android.security.afl_api") public int describeContents();
+    method @NonNull public android.app.admin.ConnectEvent getConnectEvent();
+    method @NonNull public android.app.admin.DnsEvent getDnsEvent();
+    method @NonNull public android.app.admin.SecurityLog.SecurityEvent getSecurityEvent();
+    method @NonNull public int getType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.security.intrusiondetection.IntrusionDetectionEvent> CREATOR;
+    field public static final int NETWORK_EVENT_CONNECT = 2; // 0x2
+    field public static final int NETWORK_EVENT_DNS = 1; // 0x1
+    field public static final int SECURITY_EVENT = 0; // 0x0
+  }
+
+  @FlaggedApi("android.security.afl_api") public class IntrusionDetectionEventTransport {
+    ctor public IntrusionDetectionEventTransport();
+    method public boolean addData(@NonNull java.util.List<android.security.intrusiondetection.IntrusionDetectionEvent>);
+    method @NonNull public android.os.IBinder getBinder();
+    method public boolean initialize();
+    method public boolean release();
+  }
+
   @FlaggedApi("android.security.afl_api") public class IntrusionDetectionManager {
     method @RequiresPermission(android.Manifest.permission.READ_INTRUSION_DETECTION_STATE) public void addStateCallback(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @RequiresPermission(android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE) public void disable(@NonNull java.util.concurrent.Executor, @NonNull android.security.intrusiondetection.IntrusionDetectionManager.CommandCallback);
@@ -14582,7 +14591,7 @@
     method @BinderThread public abstract void onDataStreamProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @BinderThread public abstract void onQueryServiceStatus(@NonNull java.util.Set<java.lang.Integer>, @NonNull String, @NonNull java.util.function.Consumer<android.service.ambientcontext.AmbientContextDetectionServiceStatus>);
     method @FlaggedApi("android.app.wearable.enable_provide_read_only_pfd") @BinderThread public void onReadOnlyParcelFileDescriptorProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull android.os.PersistableBundle, @NonNull java.util.function.Consumer<java.lang.Integer>);
-    method @BinderThread public void onSecureConnectionProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @Deprecated @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @BinderThread public void onSecureConnectionProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @BinderThread public void onSecureConnectionProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull android.os.PersistableBundle, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @BinderThread public abstract void onStartDetection(@NonNull android.app.ambientcontext.AmbientContextEventRequest, @NonNull String, @NonNull java.util.function.Consumer<android.service.ambientcontext.AmbientContextDetectionServiceStatus>, @NonNull java.util.function.Consumer<android.service.ambientcontext.AmbientContextDetectionResult>);
     method @FlaggedApi("android.app.wearable.enable_hotword_wearable_sensing_api") @BinderThread public void onStartHotwordRecognition(@NonNull java.util.function.Consumer<android.service.voice.HotwordAudioStream>, @NonNull java.util.function.Consumer<java.lang.Integer>);
@@ -16227,6 +16236,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallForwarding(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CallForwardingInfoCallback);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallWaitingStatus(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @FlaggedApi("com.android.internal.telephony.flags.carrier_id_from_carrier_identifier") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getCarrierIdFromCarrierIdentifier(@NonNull android.service.carrier.CarrierIdentifier);
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -18999,6 +19009,10 @@
 
 package android.view {
 
+  public static class SurfaceControl.Transaction implements java.io.Closeable android.os.Parcelable {
+    method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") @NonNull public android.view.SurfaceControl.Transaction setPictureProfileHandle(@NonNull android.view.SurfaceControl, @NonNull android.media.quality.PictureProfileHandle);
+  }
+
   @UiThread public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
     method @NonNull public final java.util.List<android.graphics.Rect> getUnrestrictedPreferKeepClearRects();
     method @RequiresPermission(android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS) public final void setUnrestrictedPreferKeepClearRects(@NonNull java.util.List<android.graphics.Rect>);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index bc2bc89..3a62ac9 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -541,7 +541,9 @@
     method @Nullable public android.graphics.Rect peekBitmapDimensions();
     method @Nullable public android.graphics.Rect peekBitmapDimensions(int);
     method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithCrops(@Nullable android.graphics.Bitmap, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException;
+    method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithDescription(@Nullable android.graphics.Bitmap, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException;
     method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithCrops(@NonNull java.io.InputStream, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException;
+    method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithDescription(@NonNull java.io.InputStream, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException;
     method public void setWallpaperZoomOut(@NonNull android.os.IBinder, float);
     method public boolean shouldEnableWideColorGamut();
     method public boolean wallpaperSupportsWcg(int);
@@ -907,6 +909,15 @@
 
 }
 
+package android.app.wallpaper {
+
+  public static final class WallpaperDescription.Builder {
+    method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>);
+    method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull android.util.SparseArray<android.graphics.Rect>);
+  }
+
+}
+
 package android.appwidget {
 
   public class AppWidgetManager {
@@ -2783,6 +2794,17 @@
 
 package android.os.vibrator {
 
+  @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public final class BasicPwleSegment extends android.os.vibrator.VibrationEffectSegment {
+    method public int describeContents();
+    method public long getDuration();
+    method public float getEndIntensity();
+    method public float getEndSharpness();
+    method public float getStartIntensity();
+    method public float getStartSharpness();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.BasicPwleSegment> CREATOR;
+  }
+
   public final class PrebakedSegment extends android.os.vibrator.VibrationEffectSegment {
     method public int describeContents();
     method public long getDuration();
@@ -3284,7 +3306,7 @@
 package android.service.settings.preferences {
 
   @FlaggedApi("com.android.settingslib.flags.settings_catalyst") public class SettingsPreferenceServiceClient implements java.lang.AutoCloseable {
-    ctor public SettingsPreferenceServiceClient(@NonNull android.content.Context, @NonNull String, boolean, @Nullable android.content.ServiceConnection);
+    ctor public SettingsPreferenceServiceClient(@NonNull android.content.Context, @NonNull String, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.SettingsPreferenceServiceClient,java.lang.Exception>);
   }
 
 }
@@ -3719,6 +3741,7 @@
     method @NonNull public android.view.Display.Mode getDefaultMode();
     method public int getRemoveMode();
     method @NonNull public int[] getReportedHdrTypes();
+    method @NonNull public float[] getSupportedRefreshRatesLegacy();
     method @NonNull public android.graphics.ColorSpace[] getSupportedWideColorGamut();
     method @Nullable public android.view.Display.Mode getSystemPreferredDisplayMode();
     method public int getType();
@@ -3741,6 +3764,7 @@
 
   public static final class Display.Mode implements android.os.Parcelable {
     ctor public Display.Mode(int, int, float);
+    method public float getVsyncRate();
     method public boolean isSynthetic();
     method public boolean matches(int, int, float);
   }
diff --git a/core/java/Android.bp b/core/java/Android.bp
index bc38294..ce767f4 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -236,6 +236,7 @@
         "android/os/GpuHeadroomParamsInternal.aidl",
         "android/os/IHintManager.aidl",
         "android/os/IHintSession.aidl",
+        "android/os/SessionCreationConfig.aidl",
     ],
     unstable: true,
     backend: {
@@ -689,43 +690,8 @@
 
 // protolog end
 
-// Whether to enable read-only system feature codegen.
-gen_readonly_feature_apis = select(release_flag("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS"), {
-    true: "true",
-    false: "false",
-    default: "false",
-})
-
-// Generates com.android.internal.pm.RoSystemFeatures, optionally compiling in
-// details about fixed system features defined by build flags. When disabled,
-// the APIs are simply passthrough stubs with no meaningful side effects.
-// TODO(b/203143243): Implement the `--feature=` aggregation  directly with a native soong module.
-genrule {
+java_system_features_srcs {
     name: "systemfeatures-gen-srcs",
-    cmd: "$(location systemfeatures-gen-tool) com.android.internal.pm.RoSystemFeatures " +
-        // --readonly=false (default) makes the codegen an effective no-op passthrough API.
-        " --readonly=" + gen_readonly_feature_apis +
-        " --feature=AUTOMOTIVE:" + select(release_flag("RELEASE_SYSTEM_FEATURE_AUTOMOTIVE"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=EMBEDDED:" + select(release_flag("RELEASE_SYSTEM_FEATURE_EMBEDDED"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=LEANBACK:" + select(release_flag("RELEASE_SYSTEM_FEATURE_LEANBACK"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=PC:" + select(release_flag("RELEASE_SYSTEM_FEATURE_PC"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=TELEVISION:" + select(release_flag("RELEASE_SYSTEM_FEATURE_TELEVISION"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=WATCH:" + select(release_flag("RELEASE_SYSTEM_FEATURE_WATCH"), {
-            any @ value: value,
-            default: "",
-        }) + " > $(out)",
-    out: [
-        "RoSystemFeatures.java",
-    ],
-    tools: ["systemfeatures-gen-tool"],
+    full_class_name: "com.android.internal.pm.RoSystemFeatures",
+    visibility: ["//visibility:private"],
 }
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 76098db..78566d2 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -1227,7 +1227,7 @@
         }
 
         if (finished) {
-            endAnimation();
+            endAnimation(true /* fromLastFrame */);
             return true;
         }
         return false;
@@ -1442,8 +1442,12 @@
     }
 
     private void endAnimation() {
+        endAnimation(false /* fromLastFrame */);
+    }
+
+    private void endAnimation(boolean fromLastFrame) {
         final boolean postNotifyEndListener = sPostNotifyEndListenerEnabled && mListeners != null
-                && mLastFrameTime > 0;
+                && fromLastFrame && mTotalDuration > 0;
         mStarted = false;
         mLastFrameTime = -1;
         mFirstFrame = -1;
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index e849aba..492c2ff 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -1281,16 +1281,20 @@
         return true;
     }
 
+    private void endAnimation() {
+        endAnimation(false /* fromLastFrame */);
+    }
+
     /**
      * Called internally to end an animation by removing it from the animations list. Must be
      * called on the UI thread.
      */
-    private void endAnimation() {
+    private void endAnimation(boolean fromLastFrame) {
         if (mAnimationEndRequested) {
             return;
         }
         final boolean postNotifyEndListener = sPostNotifyEndListenerEnabled && mListeners != null
-                && mLastFrameTime > 0;
+                && fromLastFrame && getScaledDuration() > 0;
         removeAnimationCallback();
 
         mAnimationEndRequested = true;
@@ -1570,7 +1574,7 @@
         boolean finished = animateBasedOnTime(currentTime);
 
         if (finished) {
-            endAnimation();
+            endAnimation(true /* fromLastFrame */);
         }
         return finished;
     }
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index d9f8d33..eccb6ff 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -1164,6 +1164,19 @@
             @UserIdInt int userId, int notificationId);
 
     /**
+     * Notifies that a media service associated with a media session has transitioned to a
+     * "user-engaged" state. Upon receiving this notification, service will transition to the
+     * foreground state. It should only be called by
+     * {@link com.android.server.media.MediaSessionService}
+     *
+     * @param packageName The package name of the app running the media service.
+     * @param userId The user ID associated with the service.
+     * @param notificationId The ID of the media notification associated with the service.
+     */
+    public abstract void notifyActiveMediaForegroundService(@NonNull String packageName,
+            @UserIdInt int userId, int notificationId);
+
+    /**
      * Same as {@link android.app.IActivityManager#startProfile(int userId)}, but it would succeed
      * even if the profile is disabled - it should only be called by
      * {@link com.android.server.devicepolicy.DevicePolicyManagerService} when starting a profile
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index cb7b115..f8186d6 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -8843,10 +8843,10 @@
         // Call per-process mainline module initialization.
         initializeMainlineModules();
 
-        Process.setArgV0("<pre-initialized>");
-
         Looper.prepareMainLooper();
 
+        Process.setArgV0("<pre-initialized>");
+
         // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
         // It will be in the format "seq=114"
         long startSeq = 0;
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 7e0a9b6..3cbea87 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -130,7 +130,6 @@
 import android.util.Xml;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.Immutable;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.pm.RoSystemFeatures;
@@ -1020,6 +1019,33 @@
         }
     }
 
+    @Override
+    public void setPageSizeAppCompatFlagsSettingsOverride(String packageName, boolean enabled) {
+        try {
+            mPM.setPageSizeAppCompatFlagsSettingsOverride(packageName, enabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @Override
+    public boolean isPageSizeCompatEnabled(String packageName) {
+        try {
+            return mPM.isPageSizeCompatEnabled(packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @Override
+    public String getPageSizeCompatWarningMessage(String packageName) {
+        try {
+            return mPM.getPageSizeCompatWarningMessage(packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private static List<byte[]> encodeCertificates(List<Certificate> certs) throws
             CertificateEncodingException {
         if (certs == null) {
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 9bb16ae..a6c1a57 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -270,4 +270,6 @@
 
     int[] getAllowedAdjustmentKeyTypes();
     void setAssistantAdjustmentKeyTypeState(int type, boolean enabled);
+    String[] getTypeAdjustmentDeniedPackages();
+    void setTypeAdjustmentForPackageState(String pkg, boolean enabled);
 }
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index f2228f9..4a9a286 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -178,6 +178,11 @@
     void onRecentTaskListFrozenChanged(boolean frozen);
 
     /**
+     *  Called when a task is removed from the recent tasks list as a result of adding a new task.
+     */
+    void onRecentTaskRemovedForAddTask(int taskId);
+
+    /**
      * Called when a task gets or loses focus.
      *
      * @param taskId id of the task.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b78f111..8735bf9 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -441,8 +441,8 @@
 
     /**
      * A large-format version of {@link #contentView}, giving the Notification an
-     * opportunity to show more detail. The system UI may choose to show this
-     * instead of the normal content view at its discretion.
+     * opportunity to show more detail when expanded. The system UI may choose
+     * to show this instead of the normal content view at its discretion.
      *
      * As of N, this field may be null. The expanded notification view is determined by the
      * inputs to {@link Notification.Builder}; a custom RemoteViews can optionally be
@@ -814,19 +814,19 @@
         if (Flags.notificationsRedesignTemplates()) {
             return switch (layoutId) {
                 case R.layout.notification_2025_template_collapsed_base,
+                     R.layout.notification_2025_template_expanded_base,
                      R.layout.notification_2025_template_heads_up_base,
                      R.layout.notification_2025_template_header,
-                     R.layout.notification_template_material_big_base,
+                     R.layout.notification_2025_template_conversation,
+                     R.layout.notification_2025_template_collapsed_call,
+                     R.layout.notification_2025_template_expanded_call,
+                     R.layout.notification_2025_template_collapsed_messaging,
+                     R.layout.notification_2025_template_collapsed_media,
                      R.layout.notification_template_material_big_picture,
                      R.layout.notification_template_material_big_text,
                      R.layout.notification_template_material_inbox,
-                     R.layout.notification_template_material_messaging,
                      R.layout.notification_template_material_big_messaging,
-                     R.layout.notification_template_material_conversation,
-                     R.layout.notification_template_material_media,
                      R.layout.notification_template_material_big_media,
-                     R.layout.notification_template_material_call,
-                     R.layout.notification_template_material_big_call,
                      R.layout.notification_template_header -> true;
                 case R.layout.notification_template_material_progress -> Flags.apiRichOngoing();
                 default -> false;
@@ -1337,7 +1337,7 @@
     public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
 
     /**
-     * {@link #extras} key: this is the longer text shown in the big form of a
+     * {@link #extras} key: this is the longer text shown in the expanded form of a
      * {@link BigTextStyle} notification, as supplied to
      * {@link BigTextStyle#bigText(CharSequence)}.
      */
@@ -3160,12 +3160,16 @@
                 callPerson.visitUris(visitor);
             }
             visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON, Icon.class));
-        }
 
-        if (Flags.apiRichOngoing()) {
-            visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_TRACKER_ICON, Icon.class));
-            visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_START_ICON, Icon.class));
-            visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_END_ICON, Icon.class));
+
+            if (Flags.apiRichOngoing()) {
+                visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_TRACKER_ICON,
+                    Icon.class));
+                visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_START_ICON,
+                    Icon.class));
+                visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_END_ICON,
+                    Icon.class));
+            }
         }
 
         if (mBubbleMetadata != null) {
@@ -3259,6 +3263,7 @@
     public boolean hasPromotableCharacteristics() {
         return isColorizedRequested()
                 && hasTitle()
+                && !isGroupSummary()
                 && !containsCustomViews()
                 && hasPromotableStyle();
     }
@@ -5914,12 +5919,12 @@
 
         private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p,
                 TemplateBindResult result) {
-            p.headerless(resId == getBaseLayoutResource()
+            p.headerless(resId == getCollapsedBaseLayoutResource()
                     || resId == getHeadsUpBaseLayoutResource()
                     || resId == getCompactHeadsUpBaseLayoutResource()
                     || resId == getMessagingCompactHeadsUpLayoutResource()
-                    || resId == getMessagingLayoutResource()
-                    || resId == R.layout.notification_template_material_media);
+                    || resId == getCollapsedMessagingLayoutResource()
+                    || resId == getCollapsedMediaLayoutResource());
             RemoteViews contentView = new BuilderRemoteViews(mContext.getApplicationInfo(), resId);
 
             resetStandardTemplate(contentView);
@@ -6373,7 +6378,7 @@
             boolean hideSnoozeButton = mN.isFgsOrUij()
                     || mN.fullScreenIntent != null
                     || isBackgroundColorized(p)
-                    || p.mViewType != StandardTemplateParams.VIEW_TYPE_BIG;
+                    || p.mViewType != StandardTemplateParams.VIEW_TYPE_EXPANDED;
             big.setBoolean(R.id.snooze_button, "setEnabled", !hideSnoozeButton);
             if (hideSnoozeButton) {
                 // Only hide; NotificationContentView will show it when it adds the click listener
@@ -6578,19 +6583,21 @@
                     .decorationType(StandardTemplateParams.DECORATION_MINIMAL)
                     .fillTextsFrom(this);
             TemplateBindResult result = new TemplateBindResult();
-            RemoteViews standard = applyStandardTemplate(getBaseLayoutResource(), p, result);
+            RemoteViews standard = applyStandardTemplate(getCollapsedBaseLayoutResource(),
+                    p, result);
             buildCustomContentIntoTemplate(mContext, standard, customContent,
                     p, result);
             return standard;
         }
 
-        private RemoteViews minimallyDecoratedBigContentView(@NonNull RemoteViews customContent) {
+        private RemoteViews minimallyDecoratedExpandedContentView(
+                @NonNull RemoteViews customContent) {
             StandardTemplateParams p = mParams.reset()
-                    .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
+                    .viewType(StandardTemplateParams.VIEW_TYPE_EXPANDED)
                     .decorationType(StandardTemplateParams.DECORATION_MINIMAL)
                     .fillTextsFrom(this);
             TemplateBindResult result = new TemplateBindResult();
-            RemoteViews standard = applyStandardTemplateWithActions(getBigBaseLayoutResource(),
+            RemoteViews standard = applyStandardTemplateWithActions(getExpandedBaseLayoutResource(),
                     p, result);
             buildCustomContentIntoTemplate(mContext, standard, customContent,
                     p, result);
@@ -6636,7 +6643,7 @@
             StandardTemplateParams p = mParams.reset()
                     .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL)
                     .fillTextsFrom(this);
-            return applyStandardTemplate(getBaseLayoutResource(), p, null /* result */);
+            return applyStandardTemplate(getCollapsedBaseLayoutResource(), p, null /* result */);
         }
 
         private boolean useExistingRemoteView(RemoteViews customContent) {
@@ -6674,24 +6681,29 @@
          */
         @Deprecated
         public RemoteViews createBigContentView() {
+            return createExpandedContentView();
+        }
+
+        private RemoteViews createExpandedContentView() {
             RemoteViews result = null;
             if (useExistingRemoteView(mN.bigContentView)) {
                 return fullyCustomViewRequiresDecoration(false /* fromStyle */)
-                        ? minimallyDecoratedBigContentView(mN.bigContentView) : mN.bigContentView;
+                        ? minimallyDecoratedExpandedContentView(mN.bigContentView)
+                        : mN.bigContentView;
             }
             if (mStyle != null) {
-                result = mStyle.makeBigContentView();
+                result = mStyle.makeExpandedContentView();
                 if (fullyCustomViewRequiresDecoration(true /* fromStyle */)) {
-                    result = minimallyDecoratedBigContentView(result);
+                    result = minimallyDecoratedExpandedContentView(result);
                 }
             }
             if (result == null) {
-                if (bigContentViewRequired()) {
+                if (expandedContentViewRequired()) {
                     StandardTemplateParams p = mParams.reset()
-                            .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
+                            .viewType(StandardTemplateParams.VIEW_TYPE_EXPANDED)
                             .allowTextWithProgress(true)
                             .fillTextsFrom(this);
-                    result = applyStandardTemplateWithActions(getBigBaseLayoutResource(), p,
+                    result = applyStandardTemplateWithActions(getExpandedBaseLayoutResource(), p,
                             null /* result */);
                 }
             }
@@ -6705,7 +6717,7 @@
         // apps can detect the change, it's most likely that the changes will simply result in
         // visual regressions.
         @SuppressWarnings("AndroidFrameworkCompatChange")
-        private boolean bigContentViewRequired() {
+        private boolean expandedContentViewRequired() {
             if (Flags.notificationExpansionOptional()) {
                 // Notifications without a bigContentView, style, or actions do not need to expand
                 boolean exempt = mN.bigContentView == null
@@ -7134,7 +7146,9 @@
          */
         public CharSequence ensureColorSpanContrastOrStripStyling(CharSequence cs,
                 int buttonFillColor) {
-            if (Flags.cleanUpSpansAndNewLines()) {
+            // Ongoing promoted notifications are allowed to have styling.
+            final boolean isPromotedOngoing = mN.isPromotedOngoing();
+            if (!isPromotedOngoing && Flags.cleanUpSpansAndNewLines()) {
                 return stripStyling(cs);
             }
 
@@ -7514,7 +7528,7 @@
         }
 
         @UnsupportedAppUsage
-        private int getBaseLayoutResource() {
+        private int getCollapsedBaseLayoutResource() {
             if (Flags.notificationsRedesignTemplates()) {
                 return R.layout.notification_2025_template_collapsed_base;
             } else {
@@ -7538,8 +7552,12 @@
             return R.layout.notification_template_material_messaging_compact_heads_up;
         }
 
-        private int getBigBaseLayoutResource() {
-            return R.layout.notification_template_material_big_base;
+        private int getExpandedBaseLayoutResource() {
+            if (Flags.notificationsRedesignTemplates()) {
+                return R.layout.notification_2025_template_expanded_base;
+            } else {
+                return R.layout.notification_template_material_big_base;
+            }
         }
 
         private int getBigPictureLayoutResource() {
@@ -7554,16 +7572,48 @@
             return R.layout.notification_template_material_inbox;
         }
 
-        private int getMessagingLayoutResource() {
-            return R.layout.notification_template_material_messaging;
+        private int getCollapsedMessagingLayoutResource() {
+            if (Flags.notificationsRedesignTemplates()) {
+                return R.layout.notification_2025_template_collapsed_messaging;
+            } else {
+                return R.layout.notification_template_material_messaging;
+            }
         }
 
-        private int getBigMessagingLayoutResource() {
+        private int getExpandedMessagingLayoutResource() {
             return R.layout.notification_template_material_big_messaging;
         }
 
+        private int getCollapsedMediaLayoutResource() {
+            if (Flags.notificationsRedesignTemplates()) {
+                return R.layout.notification_2025_template_collapsed_media;
+            } else {
+                return R.layout.notification_template_material_media;
+            }
+        }
+
         private int getConversationLayoutResource() {
-            return R.layout.notification_template_material_conversation;
+            if (Flags.notificationsRedesignTemplates()) {
+                return R.layout.notification_2025_template_conversation;
+            } else {
+                return R.layout.notification_template_material_conversation;
+            }
+        }
+
+        private int getCollapsedCallLayoutResource() {
+            if (Flags.notificationsRedesignTemplates()) {
+                return R.layout.notification_2025_template_collapsed_call;
+            } else {
+                return R.layout.notification_template_material_call;
+            }
+        }
+
+        private int getExpandedCallLayoutResource() {
+            if (Flags.notificationsRedesignTemplates()) {
+                return R.layout.notification_2025_template_expanded_call;
+            } else {
+                return R.layout.notification_template_material_big_call;
+            }
         }
 
         private int getProgressLayoutResource() {
@@ -8027,7 +8077,7 @@
         protected Builder mBuilder;
 
         /**
-         * Overrides ContentTitle in the big form of the template.
+         * Overrides ContentTitle in the expanded form of the template.
          * This defaults to the value passed to setContentTitle().
          */
         protected void internalSetBigContentTitle(CharSequence title) {
@@ -8035,7 +8085,7 @@
         }
 
         /**
-         * Set the first line of text after the detail section in the big form of the template.
+         * Set the first line of text after the detail section in the expanded form of the template.
          */
         protected void internalSetSummaryText(CharSequence cs) {
             mSummaryText = cs;
@@ -8098,10 +8148,10 @@
         }
 
         /**
-         * Construct a Style-specific RemoteViews for the final big notification layout.
+         * Construct a Style-specific RemoteViews for the final expanded notification layout.
          * @hide
          */
-        public RemoteViews makeBigContentView() {
+        public RemoteViews makeExpandedContentView() {
             return null;
         }
 
@@ -8265,7 +8315,7 @@
         }
 
         /**
-         * Overrides ContentTitle in the big form of the template.
+         * Overrides ContentTitle in the expanded form of the template.
          * This defaults to the value passed to setContentTitle().
          */
         @NonNull
@@ -8275,7 +8325,7 @@
         }
 
         /**
-         * Set the first line of text after the detail section in the big form of the template.
+         * Set the first line of text after the detail section in the expanded form of the template.
          */
         @NonNull
         public BigPictureStyle setSummaryText(@Nullable CharSequence cs) {
@@ -8334,7 +8384,7 @@
         }
 
         /**
-         * Override the large icon when the big notification is shown.
+         * Override the large icon when the expanded notification is shown.
          */
         @NonNull
         public BigPictureStyle bigLargeIcon(@Nullable Bitmap b) {
@@ -8342,7 +8392,7 @@
         }
 
         /**
-         * Override the large icon when the big notification is shown.
+         * Override the large icon when the expanded notification is shown.
          */
         @NonNull
         public BigPictureStyle bigLargeIcon(@Nullable Icon icon) {
@@ -8406,7 +8456,7 @@
                     .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL)
                     .fillTextsFrom(mBuilder)
                     .promotedPicture(mPictureIcon);
-            return getStandardView(mBuilder.getBaseLayoutResource(), p, null /* result */);
+            return getStandardView(mBuilder.getCollapsedBaseLayoutResource(), p, null /* result */);
         }
 
         /**
@@ -8428,7 +8478,7 @@
         /**
          * @hide
          */
-        public RemoteViews makeBigContentView() {
+        public RemoteViews makeExpandedContentView() {
             // Replace mN.mLargeIcon with mBigLargeIcon if mBigLargeIconSet
             // This covers the following cases:
             //   1. mBigLargeIconSet -> mBigLargeIcon (null or non-null) applies, overrides
@@ -8447,7 +8497,7 @@
             }
 
             StandardTemplateParams p = mBuilder.mParams.reset()
-                    .viewType(StandardTemplateParams.VIEW_TYPE_BIG).fillTextsFrom(mBuilder);
+                    .viewType(StandardTemplateParams.VIEW_TYPE_EXPANDED).fillTextsFrom(mBuilder);
             RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource(),
                     p, null /* result */);
             if (mSummaryTextSet) {
@@ -8594,7 +8644,7 @@
         }
 
         /**
-         * Overrides ContentTitle in the big form of the template.
+         * Overrides ContentTitle in the expanded form of the template.
          * This defaults to the value passed to setContentTitle().
          */
         public BigTextStyle setBigContentTitle(CharSequence title) {
@@ -8603,7 +8653,7 @@
         }
 
         /**
-         * Set the first line of text after the detail section in the big form of the template.
+         * Set the first line of text after the detail section in the expanded form of the template.
          */
         public BigTextStyle setSummaryText(CharSequence cs) {
             internalSetSummaryText(safeCharSequence(cs));
@@ -8611,7 +8661,7 @@
         }
 
         /**
-         * Provide the longer text to be displayed in the big form of the
+         * Provide the longer text to be displayed in the expanded form of the
          * template in place of the content text.
          */
         public BigTextStyle bigText(CharSequence cs) {
@@ -8655,7 +8705,7 @@
             if (increasedHeight) {
                 ArrayList<Action> originalActions = mBuilder.mActions;
                 mBuilder.mActions = new ArrayList<>();
-                RemoteViews remoteViews = makeBigContentView();
+                RemoteViews remoteViews = makeExpandedContentView();
                 mBuilder.mActions = originalActions;
                 return remoteViews;
             }
@@ -8669,7 +8719,7 @@
         public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
             if (increasedHeight && mBuilder.mActions.size() > 0) {
                 // TODO(b/163626038): pass VIEW_TYPE_HEADS_UP?
-                return makeBigContentView();
+                return makeExpandedContentView();
             }
             return super.makeHeadsUpContentView(increasedHeight);
         }
@@ -8677,16 +8727,18 @@
         /**
          * @hide
          */
-        public RemoteViews makeBigContentView() {
+        public RemoteViews makeExpandedContentView() {
             StandardTemplateParams p = mBuilder.mParams.reset()
-                    .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
+                    .viewType(StandardTemplateParams.VIEW_TYPE_EXPANDED)
                     .allowTextWithProgress(true)
                     .textViewId(R.id.big_text)
                     .fillTextsFrom(mBuilder);
 
             // Replace the text with the big text, but only if the big text is not empty.
             CharSequence bigTextText = mBuilder.processLegacyText(mBigText);
-            if (Flags.cleanUpSpansAndNewLines()) {
+            // Ongoing promoted notifications are allowed to have styling.
+            final boolean isPromotedOngoing = mBuilder.mN.isPromotedOngoing();
+            if (!isPromotedOngoing && Flags.cleanUpSpansAndNewLines()) {
                 bigTextText = normalizeBigText(stripStyling(bigTextText));
             }
             if (!TextUtils.isEmpty(bigTextText)) {
@@ -9349,20 +9401,20 @@
          * @hide
          */
         @Override
-        public RemoteViews makeBigContentView() {
-            return makeMessagingView(StandardTemplateParams.VIEW_TYPE_BIG);
+        public RemoteViews makeExpandedContentView() {
+            return makeMessagingView(StandardTemplateParams.VIEW_TYPE_EXPANDED);
         }
 
         /**
          * Create a messaging layout.
          *
-         * @param viewType one of StandardTemplateParams.VIEW_TYPE_NORMAL, VIEW_TYPE_BIG,
+         * @param viewType one of StandardTemplateParams.VIEW_TYPE_NORMAL, VIEW_TYPE_EXPANDEDIG,
          *                VIEW_TYPE_HEADS_UP
          * @return the created remoteView.
          */
         @NonNull
         private RemoteViews makeMessagingView(int viewType) {
-            boolean isCollapsed = viewType != StandardTemplateParams.VIEW_TYPE_BIG;
+            boolean isCollapsed = viewType != StandardTemplateParams.VIEW_TYPE_EXPANDED;
             boolean hideRightIcons = viewType != StandardTemplateParams.VIEW_TYPE_NORMAL;
             boolean isConversationLayout = mConversationType != CONVERSATION_TYPE_LEGACY;
             boolean isImportantConversation = mConversationType == CONVERSATION_TYPE_IMPORTANT;
@@ -9406,8 +9458,8 @@
                     isConversationLayout
                             ? mBuilder.getConversationLayoutResource()
                             : isCollapsed
-                                    ? mBuilder.getMessagingLayoutResource()
-                                    : mBuilder.getBigMessagingLayoutResource(),
+                                    ? mBuilder.getCollapsedMessagingLayoutResource()
+                                    : mBuilder.getExpandedMessagingLayoutResource(),
                     p,
                     bindResult);
             if (isConversationLayout) {
@@ -10030,7 +10082,7 @@
         }
 
         /**
-         * Overrides ContentTitle in the big form of the template.
+         * Overrides ContentTitle in the expanded form of the template.
          * This defaults to the value passed to setContentTitle().
          */
         public InboxStyle setBigContentTitle(CharSequence title) {
@@ -10039,7 +10091,7 @@
         }
 
         /**
-         * Set the first line of text after the detail section in the big form of the template.
+         * Set the first line of text after the detail section in the expanded form of the template.
          */
         public InboxStyle setSummaryText(CharSequence cs) {
             internalSetSummaryText(safeCharSequence(cs));
@@ -10087,9 +10139,9 @@
         /**
          * @hide
          */
-        public RemoteViews makeBigContentView() {
+        public RemoteViews makeExpandedContentView() {
             StandardTemplateParams p = mBuilder.mParams.reset()
-                    .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
+                    .viewType(StandardTemplateParams.VIEW_TYPE_EXPANDED)
                     .fillTextsFrom(mBuilder).text(null);
             TemplateBindResult result = new TemplateBindResult();
             RemoteViews contentView = getStandardView(mBuilder.getInboxLayoutResource(), p, result);
@@ -10344,8 +10396,8 @@
          * @hide
          */
         @Override
-        public RemoteViews makeBigContentView() {
-            return makeMediaBigContentView(null /* customContent */);
+        public RemoteViews makeExpandedContentView() {
+            return makeMediaExpandedContentView(null /* customContent */);
         }
 
         /**
@@ -10460,7 +10512,7 @@
                     .fillTextsFrom(mBuilder);
             TemplateBindResult result = new TemplateBindResult();
             RemoteViews template = mBuilder.applyStandardTemplate(
-                    R.layout.notification_template_material_media, p,
+                    mBuilder.getCollapsedMediaLayoutResource(), p,
                     null /* result */);
 
             for (int i = 0; i < MAX_MEDIA_BUTTONS_IN_COMPACT; i++) {
@@ -10481,10 +10533,10 @@
         }
 
         /** @hide */
-        protected RemoteViews makeMediaBigContentView(@Nullable RemoteViews customContent) {
+        protected RemoteViews makeMediaExpandedContentView(@Nullable RemoteViews customContent) {
             final int actionCount = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
             StandardTemplateParams p = mBuilder.mParams.reset()
-                    .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
+                    .viewType(StandardTemplateParams.VIEW_TYPE_EXPANDED)
                     .hideProgress(true)
                     .fillTextsFrom(mBuilder);
             TemplateBindResult result = new TemplateBindResult();
@@ -10790,8 +10842,8 @@
         /**
          * @hide
          */
-        public RemoteViews makeBigContentView() {
-            return makeCallLayout(StandardTemplateParams.VIEW_TYPE_BIG);
+        public RemoteViews makeExpandedContentView() {
+            return makeCallLayout(StandardTemplateParams.VIEW_TYPE_EXPANDED);
         }
 
         @NonNull
@@ -10912,10 +10964,10 @@
             final RemoteViews contentView;
             if (isCollapsed) {
                 contentView = mBuilder.applyStandardTemplate(
-                        R.layout.notification_template_material_call, p, null /* result */);
+                        mBuilder.getCollapsedCallLayoutResource(), p, null /* result */);
             } else {
                 contentView = mBuilder.applyStandardTemplateWithActions(
-                        R.layout.notification_template_material_big_call, p, null /* result */);
+                    mBuilder.getExpandedCallLayoutResource(), p, null /* result */);
             }
 
             // Bind some extra conversation-specific header fields.
@@ -11537,7 +11589,7 @@
                     .hideProgress(true)
                     .fillTextsFrom(mBuilder);
 
-            return getStandardView(mBuilder.getBaseLayoutResource(), p, null /* result */);
+            return getStandardView(mBuilder.getCollapsedBaseLayoutResource(), p, null /* result */);
         }
         /**
          * @hide
@@ -11555,9 +11607,9 @@
          * @hide
          */
         @Override
-        public RemoteViews makeBigContentView() {
+        public RemoteViews makeExpandedContentView() {
             StandardTemplateParams p = mBuilder.mParams.reset()
-                    .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
+                    .viewType(StandardTemplateParams.VIEW_TYPE_EXPANDED)
                     .allowTextWithProgress(true)
                     .hideProgress(true)
                     .fillTextsFrom(mBuilder);
@@ -12001,8 +12053,8 @@
          * @hide
          */
         @Override
-        public RemoteViews makeBigContentView() {
-            return makeDecoratedBigContentView();
+        public RemoteViews makeExpandedContentView() {
+            return makeDecoratedExpandedContentView();
         }
 
         /**
@@ -12045,13 +12097,13 @@
                     .decorationType(StandardTemplateParams.DECORATION_PARTIAL)
                     .fillTextsFrom(mBuilder);
             RemoteViews remoteViews = mBuilder.applyStandardTemplate(
-                    mBuilder.getBaseLayoutResource(), p, result);
+                    mBuilder.getCollapsedBaseLayoutResource(), p, result);
             buildCustomContentIntoTemplate(mBuilder.mContext, remoteViews, customContent,
                     p, result);
             return remoteViews;
         }
 
-        private RemoteViews makeDecoratedBigContentView() {
+        private RemoteViews makeDecoratedExpandedContentView() {
             RemoteViews bigContentView = mBuilder.mN.bigContentView == null
                     ? mBuilder.mN.contentView
                     : mBuilder.mN.bigContentView;
@@ -12060,11 +12112,11 @@
             }
             TemplateBindResult result = new TemplateBindResult();
             StandardTemplateParams p = mBuilder.mParams.reset()
-                    .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
+                    .viewType(StandardTemplateParams.VIEW_TYPE_EXPANDED)
                     .decorationType(StandardTemplateParams.DECORATION_PARTIAL)
                     .fillTextsFrom(mBuilder);
             RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions(
-                    mBuilder.getBigBaseLayoutResource(), p, result);
+                    mBuilder.getExpandedBaseLayoutResource(), p, result);
             buildCustomContentIntoTemplate(mBuilder.mContext, remoteViews, bigContentView,
                     p, result);
             return remoteViews;
@@ -12137,11 +12189,11 @@
          * @hide
          */
         @Override
-        public RemoteViews makeBigContentView() {
+        public RemoteViews makeExpandedContentView() {
             RemoteViews customContent = mBuilder.mN.bigContentView != null
                     ? mBuilder.mN.bigContentView
                     : mBuilder.mN.contentView;
-            return makeMediaBigContentView(customContent);
+            return makeMediaExpandedContentView(customContent);
         }
 
         /**
@@ -12152,7 +12204,7 @@
             RemoteViews customContent = mBuilder.mN.headsUpContentView != null
                     ? mBuilder.mN.headsUpContentView
                     : mBuilder.mN.contentView;
-            return makeMediaBigContentView(customContent);
+            return makeMediaExpandedContentView(customContent);
         }
 
         /**
@@ -14478,7 +14530,7 @@
 
         public static int VIEW_TYPE_UNSPECIFIED = 0;
         public static int VIEW_TYPE_NORMAL = 1;
-        public static int VIEW_TYPE_BIG = 2;
+        public static int VIEW_TYPE_EXPANDED = 2;
         public static int VIEW_TYPE_HEADS_UP = 3;
         public static int VIEW_TYPE_MINIMIZED = 4;    // header only for minimized state
         public static int VIEW_TYPE_PUBLIC = 5;       // header only for automatic public version
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index c310f95..87c8619 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1868,6 +1868,19 @@
     /**
      * @hide
      */
+    @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) {
+        INotificationManager service = getService();
+        try {
+            service.setTypeAdjustmentForPackageState(pkg, enabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
     public List<String> getEnabledNotificationListenerPackages() {
         INotificationManager service = getService();
         try {
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index e218418..3973c58 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -61,6 +61,8 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -680,12 +682,17 @@
         @GuardedBy("mLock")
         private boolean mTestMode = false;
 
-        /**
-         * The local value of the handler, used during testing but also used directly by the
-         * NonceLocal handler.
-         */
+        // This is the local value of the nonce, as last set by the NonceHandler.  It is always
+        // updated by the setNonce() operation.  The getNonce() operation returns this value in
+        // NonceLocal handlers and handlers in test mode.
         @GuardedBy("mLock")
-        protected long mTestNonce = NONCE_UNSET;
+        protected long mShadowNonce = NONCE_UNSET;
+
+        // A list of watchers to be notified of changes.  This is null until at least one watcher
+        // registers.  Checking for null is meant to be the fastest way the handler can determine
+        // that there are no watchers to be notified.
+        @GuardedBy("mLock")
+        private ArrayList<Semaphore> mWatchers;
 
         /**
          * The methods to get and set a nonce from whatever storage is being used.  mLock may be
@@ -701,27 +708,60 @@
 
         /**
          * Get a nonce from storage.  If the handler is in test mode, the nonce is returned from
-         * the local mTestNonce.
+         * the local mShadowNonce.
          */
         long getNonce() {
             synchronized (mLock) {
-                if (mTestMode) return mTestNonce;
+                if (mTestMode) return mShadowNonce;
             }
             return getNonceInternal();
         }
 
         /**
-         * Write a nonce to storage.  If the handler is in test mode, the nonce is written to the
-         * local mTestNonce and storage is not affected.
+         * Write a nonce to storage.  The nonce is always written to the local mShadowNonce.  If
+         * the handler is not in test mode the nonce is also written to storage.
          */
         void setNonce(long val) {
             synchronized (mLock) {
-                if (mTestMode) {
-                    mTestNonce = val;
-                    return;
+                mShadowNonce = val;
+                if (!mTestMode) {
+                    setNonceInternal(val);
+                }
+                wakeAllWatchersLocked();
+            }
+        }
+
+        @GuardedBy("mLock")
+        private void wakeAllWatchersLocked() {
+            if (mWatchers != null) {
+                for (int i = 0; i < mWatchers.size(); i++) {
+                    mWatchers.get(i).release();
                 }
             }
-            setNonceInternal(val);
+        }
+
+        /**
+         * Register a watcher to be notified when a nonce changes.  There is no check for
+         * duplicates.  In general, this method is called only from {@link NonceWatcher}.
+         */
+        void registerWatcher(Semaphore s) {
+            synchronized (mLock) {
+                if (mWatchers == null) {
+                    mWatchers = new ArrayList<>();
+                }
+                mWatchers.add(s);
+            }
+        }
+
+        /**
+         * Unregister a watcher.  Nothing happens if the watcher is not registered.
+         */
+        void unregisterWatcher(Semaphore s) {
+            synchronized (mLock) {
+                if (mWatchers != null) {
+                    mWatchers.remove(s);
+                }
+            }
         }
 
         /**
@@ -854,7 +894,7 @@
         void setTestMode(boolean mode) {
             synchronized (mLock) {
                 mTestMode = mode;
-                mTestNonce = NONCE_UNSET;
+                mShadowNonce = NONCE_UNSET;
             }
         }
 
@@ -1028,7 +1068,7 @@
     /**
      * SystemProperties and shared storage are protected and cannot be written by random
      * processes.  So, for testing purposes, the NonceLocal handler stores the nonce locally.  The
-     * NonceLocal uses the mTestNonce in the superclass, regardless of test mode.
+     * NonceLocal uses the mShadowNonce in the superclass, regardless of test mode.
      */
     private static class NonceLocal extends NonceHandler {
         // The saved nonce.
@@ -1040,16 +1080,130 @@
 
         @Override
         long getNonceInternal() {
-            return mTestNonce;
+            return mShadowNonce;
         }
 
         @Override
         void setNonceInternal(long value) {
-            mTestNonce = value;
+            mShadowNonce = value;
         }
     }
 
     /**
+     * A NonceWatcher lets an external client test if a nonce value has changed from the last time
+     * the watcher was checked.
+     * @hide
+     */
+    public static class NonceWatcher implements AutoCloseable {
+        // The handler for the key.
+        private final NonceHandler mHandler;
+
+        // The last-seen value.  This is initialized to "unset".
+        private long mLastSeen = NONCE_UNSET;
+
+        // The semaphore that the watcher waits on.  A permit is released every time the nonce
+        // changes.  Permits are acquired in the wait method.
+        private final Semaphore mSem = new Semaphore(0);
+
+        /**
+         * Create a watcher for a handler.  The last-seen value is not set here and will be
+         * "unset".  Therefore, a call to isChanged() will return true if the nonce has ever been
+         * set, no matter when the watcher is first created.  Clients may want to flush that
+         * change by calling isChanged() immediately after constructing the object.
+         */
+        private NonceWatcher(@NonNull NonceHandler handler) {
+            mHandler = handler;
+            mHandler.registerWatcher(mSem);
+        }
+
+        /**
+         * Unregister to be notified when a nonce changes.  NonceHandler allows a call to
+         * unregisterWatcher with a semaphore that is not registered, so there is no check inside
+         * this method to guard against multiple closures.
+         */
+        @Override
+        public void close() {
+            mHandler.unregisterWatcher(mSem);
+        }
+
+        /**
+         * Return the last seen value of the nonce.  This does not update that value.  Only
+         * {@link #isChanged()} updates the value.
+         */
+        public long lastSeen() {
+            return mLastSeen;
+        }
+
+        /**
+         * Return true if the nonce has changed from the last time isChanged() was called.  The
+         * method is not thread safe.
+         * @hide
+         */
+        public boolean isChanged() {
+            long current = mHandler.getNonce();
+            if (current != mLastSeen) {
+                mLastSeen = current;
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Wait for the nonce value to change.  It is not guaranteed that the nonce has changed when
+         * this returns: clients must confirm with {@link #isChanged}. The wait operation is only
+         * effective in a process that writes the nonces.  The function returns the number of times
+         * the nonce had changed since the last call to the method.
+         * @hide
+         */
+        public int waitForChange() throws InterruptedException {
+            mSem.acquire(1);
+            return 1 + mSem.drainPermits();
+        }
+
+        /**
+         * Wait for the nonce value to change.  It is not guaranteed that the nonce has changed when
+         * this returns: clients must confirm with {@link #isChanged}. The wait operation is only
+         * effective in a process that writes the nonces.  The function returns the number of times
+         * the nonce changed since the last call to the method.  A return value of zero means the
+         * timeout expired.  Beware that a timeout of 0 means the function will not wait at all.
+         * @hide
+         */
+        public int waitForChange(long timeout, TimeUnit timeUnit) throws InterruptedException {
+            if (mSem.tryAcquire(1, timeout, timeUnit)) {
+                return 1 + mSem.drainPermits();
+            } else {
+                return 0;
+            }
+        }
+
+        /**
+         * Wake the watcher by releasing the semaphore.  This can be used to wake clients that are
+         * blocked in {@link #waitForChange} without affecting the underlying nonce.
+         * @hide
+         */
+        public void wakeUp() {
+            mSem.release();
+        }
+    }
+
+    /**
+     * Return a NonceWatcher for the cache.
+     * @hide
+     */
+    public NonceWatcher getNonceWatcher() {
+        return new NonceWatcher(mNonce);
+    }
+
+    /**
+     * Return a NonceWatcher for the given property.  If a handler does not exist for the
+     * property, one is created.  This throws if the property name is not a valid cache key.
+     * @hide
+     */
+    public static NonceWatcher getNonceWatcher(@NonNull String propertyName) {
+        return new NonceWatcher(getNonceHandler(propertyName));
+    }
+
+    /**
      * Complete key prefixes.
      */
     private static final String PREFIX_TEST = CACHE_KEY_PREFIX + "." + MODULE_TEST + ".";
@@ -1663,6 +1817,26 @@
     }
 
     /**
+     * Non-static version of corkInvalidations() for situations in which the cache instance is
+     * available.  This is slightly faster than than the static versions because it does not have
+     * to look up the NonceHandler for a given property name.
+     * @hide
+     */
+    public void corkInvalidations() {
+        mNonce.cork();
+    }
+
+    /**
+     * Non-static version of uncorkInvalidations() for situations in which the cache instance is
+     * available.  This is slightly faster than than the static versions because it does not have
+     * to look up the NonceHandler for a given property name.
+     * @hide
+     */
+    public void uncorkInvalidations() {
+        mNonce.uncork();
+    }
+
+    /**
      * Invalidate caches in all processes that are keyed for the module and api.
      * @hide
      */
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 36f61fd..b9b582a 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -198,6 +198,10 @@
     }
 
     @Override
+    public void onRecentTaskRemovedForAddTask(int taskId) {
+    }
+
+    @Override
     public void onTaskFocusChanged(int taskId, boolean focused) {
     }
 
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index abb2dd4..a8671cf 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -2491,6 +2491,27 @@
         return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
     }
 
+    /**
+     * Version of setBitmap that allows specification of wallpaper metadata including how the
+     * wallpaper will be positioned for different display sizes.
+     *
+     * @param fullImage   A bitmap that will supply the wallpaper imagery.
+     * @param description Wallpaper metadata including desired cropping
+     * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
+     *                    image for restore to a future device; {@code false} otherwise.
+     * @param which       Flags indicating which wallpaper(s) to configure with the new imagery.
+     * @hide
+     */
+    @FlaggedApi(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
+    public int setBitmapWithDescription(@Nullable Bitmap fullImage,
+            @NonNull WallpaperDescription description, boolean allowBackup,
+            @SetWallpaperFlags int which) throws IOException {
+        return setBitmapWithCrops(fullImage, description.getCropHints(), allowBackup, which,
+                mContext.getUserId());
+    }
+
     private final void validateRect(Rect rect) {
         if (rect != null && rect.isEmpty()) {
             throw new IllegalArgumentException("visibleCrop rectangle must be valid and non-empty");
@@ -2700,6 +2721,27 @@
     }
 
     /**
+     * Version of setStream that allows specification of wallpaper metadata including how the
+     * wallpaper will be positioned for different display sizes.
+     *
+     * @param bitmapData  A stream containing the raw data to install as a wallpaper. This
+     *                    data can be in any format handled by {@link BitmapRegionDecoder}.
+     * @param description Wallpaper metadata including desired cropping
+     * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
+     *                    image for restore to a future device; {@code false} otherwise.
+     * @param which       Flags indicating which wallpaper(s) to configure with the new imagery.
+     * @hide
+     */
+    @FlaggedApi(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
+    public int setStreamWithDescription(@NonNull InputStream bitmapData,
+            @NonNull WallpaperDescription description, boolean allowBackup,
+            @SetWallpaperFlags int which) throws IOException {
+        return setStreamWithCrops(bitmapData, description.getCropHints(), allowBackup, which);
+    }
+
+    /**
      * Return whether any users are currently set to use the wallpaper
      * with the given resource ID.  That is, their wallpaper has been
      * set through {@link #setResource(int)} with the same resource id.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e766ae2..74d7298 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -4177,6 +4177,35 @@
         }
     }
 
+
+    /**
+     * Similar to the public variant of {@link #setMtePolicy} but for use by the system.
+     *
+     * <p>Called by a system service only, meaning that the caller's UID must be equal to
+     * {@link Process#SYSTEM_UID}.
+     *
+     * @throws SecurityException if caller is not permitted to set Mte policy
+     * @throws UnsupportedOperationException if the device does not support MTE
+     * @param systemEntity  The service entity that adds the restriction. A user restriction set by
+     *                       a service entity can only be cleared by the same entity. This can be
+     *                       just the calling package name, or any string of the caller's choice
+     *                       can be used.
+     * @param policy the MTE policy to be set
+     * @hide
+     */
+    public void setMtePolicy(@NonNull String systemEntity, @MtePolicy int policy) {
+        throwIfParentInstance("setMtePolicyForUser");
+        if (mService != null) {
+            try {
+                mService.setMtePolicyBySystem(systemEntity, policy);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+
+
     /**
      * Called by a device owner, profile owner of an organization-owned device to
      * get the Memory Tagging Extension (MTE) policy
@@ -14453,7 +14482,7 @@
      * </ul>
      * <p>
      * The following methods are supported for the parent instance but can only be called by the
-     * profile owner of a managed profile that was created during the device provisioning flow:
+     * profile owner on an <a href="#organization-owned">organization owned</a> managed profile:
      * <ul>
      * <li>{@link #getPasswordComplexity}</li>
      * <li>{@link #setCameraDisabled}</li>
@@ -14461,11 +14490,6 @@
      * <li>{@link #setAccountManagementDisabled(ComponentName, String, boolean)}</li>
      * <li>{@link #setPermittedInputMethods}</li>
      * <li>{@link #getPermittedInputMethods}</li>
-     * </ul>
-     *
-     * <p>The following methods can be called by the profile owner of a managed profile
-     * on an organization-owned device:
-     * <ul>
      * <li>{@link #wipeData}</li>
      * </ul>
      *
@@ -18177,4 +18201,4 @@
         }
         return HEADLESS_DEVICE_OWNER_MODE_UNSUPPORTED;
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index d048b53..e7be822 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -617,6 +617,7 @@
     int[] getApplicationExemptions(String packageName);
 
     void setMtePolicy(int flag, String callerPackageName);
+    void setMtePolicyBySystem(in String systemEntity, int policy);
     int getMtePolicy(String callerPackageName);
 
     void setManagedSubscriptionsPolicy(in ManagedSubscriptionsPolicy policy);
diff --git a/core/java/android/app/background_install_control_manager.aconfig b/core/java/android/app/background_install_control_manager.aconfig
index d29c5b5..39f10dc 100644
--- a/core/java/android/app/background_install_control_manager.aconfig
+++ b/core/java/android/app/background_install_control_manager.aconfig
@@ -9,3 +9,10 @@
      is_fixed_read_only: true
      bug: "287507984"
 }
+
+flag {
+    name: "background_install_control_callback_api"
+    namespace: "preload_safety"
+    description: "Feature flag to enable the use of push API in background install control service"
+    bug: "369382811"
+}
\ No newline at end of file
diff --git a/core/java/android/app/ondeviceintelligence/InferenceInfo.java b/core/java/android/app/ondeviceintelligence/InferenceInfo.java
index 5557a81..cae8db2 100644
--- a/core/java/android/app/ondeviceintelligence/InferenceInfo.java
+++ b/core/java/android/app/ondeviceintelligence/InferenceInfo.java
@@ -16,6 +16,12 @@
 
 package android.app.ondeviceintelligence;
 
+import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE;
+
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -25,7 +31,9 @@
  *
  * @hide
  */
-public class InferenceInfo implements Parcelable {
+@SystemApi
+@FlaggedApi(FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE)
+public final class InferenceInfo implements Parcelable {
 
     /**
      * Uid for the caller app.
@@ -55,7 +63,7 @@
      * @param endTimeMs       Inference end time (milliseconds from the epoch time).
      * @param suspendedTimeMs Suspended time in milliseconds.
      */
-    public InferenceInfo(int uid, long startTimeMs, long endTimeMs,
+    InferenceInfo(int uid, long startTimeMs, long endTimeMs,
             long suspendedTimeMs) {
         this.uid = uid;
         this.startTimeMs = startTimeMs;
@@ -68,7 +76,7 @@
      *
      * @param in The Parcel to read the object's data from.
      */
-    protected InferenceInfo(Parcel in) {
+    private InferenceInfo(@NonNull Parcel in) {
         uid = in.readInt();
         startTimeMs = in.readLong();
         endTimeMs = in.readLong();
@@ -79,11 +87,11 @@
     /**
      * Writes the object's data to the provided Parcel.
      *
-     * @param dest The Parcel to write the object's data to.
+     * @param dest  The Parcel to write the object's data to.
      * @param flags Additional flags about how the object should be written.
      */
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(uid);
         dest.writeLong(startTimeMs);
         dest.writeLong(endTimeMs);
@@ -104,7 +112,8 @@
      *
      * @return the inference start time in milliseconds from the epoch time.
      */
-    public long getStartTimeMs() {
+    @CurrentTimeMillisLong
+    public long getStartTimeMillis() {
         return startTimeMs;
     }
 
@@ -113,7 +122,8 @@
      *
      * @return the inference end time in milliseconds from the epoch time.
      */
-    public long getEndTimeMs() {
+    @CurrentTimeMillisLong
+    public long getEndTimeMillis() {
         return endTimeMs;
     }
 
@@ -122,7 +132,8 @@
      *
      * @return the suspended time in milliseconds.
      */
-    public long getSuspendedTimeMs() {
+    @CurrentTimeMillisLong
+    public long getSuspendedTimeMillis() {
         return suspendedTimeMs;
     }
 
@@ -148,21 +159,19 @@
     /**
      * Builder class for creating instances of {@link InferenceInfo}.
      */
-    public static class Builder {
-        private int uid;
+    public static final class Builder {
+        private final int uid;
         private long startTimeMs;
         private long endTimeMs;
         private long suspendedTimeMs;
 
         /**
-         * Sets the UID for the caller app.
+         * Provides a builder instance to create a InferenceInfo for given caller uid.
          *
-         * @param uid the UID for the caller app.
-         * @return the Builder instance.
+         * @param uid the caller uid associated with the inference info.
          */
-        public Builder setUid(int uid) {
+        public Builder(int uid) {
             this.uid = uid;
-            return this;
         }
 
         /**
@@ -171,7 +180,7 @@
          * @param startTimeMs the inference start time in milliseconds from the epoch time.
          * @return the Builder instance.
          */
-        public Builder setStartTimeMs(long startTimeMs) {
+        public @NonNull Builder setStartTimeMillis(@CurrentTimeMillisLong long startTimeMs) {
             this.startTimeMs = startTimeMs;
             return this;
         }
@@ -182,7 +191,7 @@
          * @param endTimeMs the inference end time in milliseconds from the epoch time.
          * @return the Builder instance.
          */
-        public Builder setEndTimeMs(long endTimeMs) {
+        public @NonNull Builder setEndTimeMillis(@CurrentTimeMillisLong long endTimeMs) {
             this.endTimeMs = endTimeMs;
             return this;
         }
@@ -193,7 +202,7 @@
          * @param suspendedTimeMs the suspended time in milliseconds.
          * @return the Builder instance.
          */
-        public Builder setSuspendedTimeMs(long suspendedTimeMs) {
+        public @NonNull Builder setSuspendedTimeMillis(@CurrentTimeMillisLong long suspendedTimeMs) {
             this.suspendedTimeMs = suspendedTimeMs;
             return this;
         }
@@ -203,7 +212,7 @@
          *
          * @return an instance of {@link InferenceInfo}.
          */
-        public InferenceInfo build() {
+        public @NonNull InferenceInfo build() {
             return new InferenceInfo(uid, startTimeMs, endTimeMs,
                     suspendedTimeMs);
         }
diff --git a/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java b/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
index 937a9cd..91651e3 100644
--- a/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
+++ b/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
@@ -17,9 +17,11 @@
 package android.app.ondeviceintelligence;
 
 import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
+import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE;
 
 import android.Manifest;
 import android.annotation.CallbackExecutor;
+import android.annotation.CurrentTimeMillisLong;
 import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -502,11 +504,10 @@
      *
      * @param startTimeEpochMillis epoch millis used to filter the InferenceInfo events.
      * @return InferenceInfo events since the passed in startTimeEpochMillis.
-     *
-     * @hide
      */
     @RequiresPermission(Manifest.permission.DUMP)
-    public List<InferenceInfo> getLatestInferenceInfo(long startTimeEpochMillis) {
+    @FlaggedApi(FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE)
+    public @NonNull List<InferenceInfo> getLatestInferenceInfo(@CurrentTimeMillisLong long startTimeEpochMillis) {
         try {
             return mService.getLatestInferenceInfo(startTimeEpochMillis);
         } catch (RemoteException e) {
diff --git a/core/java/android/app/wallpaper/WallpaperDescription.java b/core/java/android/app/wallpaper/WallpaperDescription.java
index 4a142bb..3ee00ca 100644
--- a/core/java/android/app/wallpaper/WallpaperDescription.java
+++ b/core/java/android/app/wallpaper/WallpaperDescription.java
@@ -19,8 +19,14 @@
 import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
 
 import android.annotation.FlaggedApi;
+import android.annotation.SuppressLint;
+import android.annotation.TestApi;
 import android.app.WallpaperInfo;
+import android.app.WallpaperManager;
+import android.app.WallpaperManager.ScreenOrientation;
 import android.content.ComponentName;
+import android.graphics.Point;
+import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -29,6 +35,8 @@
 import android.text.Spanned;
 import android.text.SpannedString;
 import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -43,6 +51,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -71,12 +80,15 @@
     @Nullable private final Uri mContextUri;
     @Nullable private final CharSequence mContextDescription;
     @NonNull private final PersistableBundle mContent;
+    @NonNull private final SparseArray<Rect> mCropHints;
+    private final float mSampleSize;
 
     private WallpaperDescription(@Nullable ComponentName component,
             @Nullable String id, @Nullable Uri thumbnail, @Nullable CharSequence title,
             @Nullable List<CharSequence> description, @Nullable Uri contextUri,
             @Nullable CharSequence contextDescription,
-            @Nullable PersistableBundle content) {
+            @Nullable PersistableBundle content, @NonNull SparseArray<Rect> cropHints,
+            float sampleSize) {
         this.mComponent = component;
         this.mId = id;
         this.mThumbnail = thumbnail;
@@ -85,6 +97,8 @@
         this.mContextUri = contextUri;
         this.mContextDescription = contextDescription;
         this.mContent = (content != null) ? content : new PersistableBundle();
+        this.mCropHints = cropHints;
+        this.mSampleSize = sampleSize;
     }
 
     /** @return the component for this wallpaper, or {@code null} for a static wallpaper */
@@ -134,6 +148,24 @@
         return mContent;
     }
 
+    /**
+     * @return the cropping for the current image as described in
+     * {@link Builder#setCropHints(SparseArray)}
+     * @hide
+     */
+    @NonNull
+    public SparseArray<Rect> getCropHints() {
+        return mCropHints;
+    }
+
+    /**
+     * @return the subsamling size as described in {@link Builder#setSampleSize(float)}.
+     * @hide
+     */
+    public float getSampleSize() {
+        return mSampleSize;
+    }
+
     ////// Comparison overrides
 
     @Override
@@ -163,9 +195,23 @@
         if (mContextDescription != null) {
             out.attribute(null, "contextdescription", toHtml(mContextDescription));
         }
+
+        for (Pair<Integer, String> pair : screenDimensionPairs()) {
+            @ScreenOrientation int orientation = pair.first;
+            String attrName = pair.second;
+            Rect cropHint = mCropHints.get(orientation);
+            if (cropHint == null) continue;
+            out.attributeInt(null, "cropLeft" + attrName, cropHint.left);
+            out.attributeInt(null, "cropTop" + attrName, cropHint.top);
+            out.attributeInt(null, "cropRight" + attrName, cropHint.right);
+            out.attributeInt(null, "cropBottom" + attrName, cropHint.bottom);
+        }
+        out.attributeFloat(null, "sampleSize", mSampleSize);
+
         out.startTag(null, XML_TAG_DESCRIPTION);
         for (CharSequence s : mDescription) out.attribute(null, "descriptionline", toHtml(s));
         out.endTag(null, XML_TAG_DESCRIPTION);
+
         try {
             out.startTag(null, XML_TAG_CONTENT);
             mContent.saveToXml(out);
@@ -194,6 +240,19 @@
         CharSequence contextDescription = fromHtml(
                 in.getAttributeValue(null, "contextdescription"));
 
+        SparseArray<Rect> cropHints = new SparseArray<>();
+        screenDimensionPairs().forEach(pair -> {
+            @ScreenOrientation int orientation = pair.first;
+            String attrName = pair.second;
+            Rect crop = new Rect(
+                    in.getAttributeInt(null, "cropLeft" + attrName, 0),
+                    in.getAttributeInt(null, "cropTop" + attrName, 0),
+                    in.getAttributeInt(null, "cropRight" + attrName, 0),
+                    in.getAttributeInt(null, "cropBottom" + attrName, 0));
+            if (!crop.isEmpty()) cropHints.put(orientation, crop);
+        });
+        float sampleSize = in.getAttributeFloat(null, "sampleSize", 1f);
+
         List<CharSequence> description = new ArrayList<>();
         PersistableBundle content = null;
         int type;
@@ -213,7 +272,7 @@
         }
 
         return new WallpaperDescription(componentName, id, thumbnail, title, description,
-                contextUri, contextDescription, content);
+                contextUri, contextDescription, content, cropHints, sampleSize);
     }
 
     private static String toHtml(@NonNull CharSequence c) {
@@ -253,6 +312,13 @@
         mContextUri = Uri.CREATOR.createFromParcel(in);
         mContextDescription = in.readCharSequence();
         mContent = PersistableBundle.CREATOR.createFromParcel(in);
+        mCropHints = new SparseArray<>();
+        screenDimensionPairs().forEach(pair -> {
+            int orientation = pair.first;
+            Rect crop = in.readTypedObject(Rect.CREATOR);
+            if (crop != null) mCropHints.put(orientation, crop);
+        });
+        mSampleSize = in.readFloat();
     }
 
     @NonNull
@@ -283,6 +349,11 @@
         Uri.writeToParcel(dest, mContextUri);
         dest.writeCharSequence(mContextDescription);
         dest.writePersistableBundle(mContent);
+        screenDimensionPairs().forEach(pair -> {
+            int orientation = pair.first;
+            dest.writeTypedObject(mCropHints.get(orientation), flags);
+        });
+        dest.writeFloat(mSampleSize);
     }
 
     ////// Builder
@@ -293,9 +364,17 @@
      */
     @NonNull
     public Builder toBuilder() {
-        return new Builder().setComponent(mComponent).setId(mId).setThumbnail(mThumbnail).setTitle(
-                mTitle).setDescription(mDescription).setContextUri(
-                mContextUri).setContextDescription(mContextDescription).setContent(mContent);
+        return new Builder()
+                .setComponent(mComponent)
+                .setId(mId)
+                .setThumbnail(mThumbnail)
+                .setTitle(mTitle)
+                .setDescription(mDescription)
+                .setContextUri(mContextUri)
+                .setContextDescription(mContextDescription)
+                .setContent(mContent)
+                .setCropHints(mCropHints)
+                .setSampleSize(mSampleSize);
     }
 
     /** Builder for the immutable {@link WallpaperDescription} class */
@@ -308,6 +387,9 @@
         @Nullable private Uri mContextUri;
         @Nullable private CharSequence mContextDescription;
         @NonNull private PersistableBundle mContent = new PersistableBundle();
+        @NonNull
+        private SparseArray<Rect> mCropHints = new SparseArray<>();
+        private float mSampleSize = 1f;
 
         /** Creates a new, empty {@link Builder}. */
         public Builder() {}
@@ -416,11 +498,69 @@
             return this;
         }
 
+        /**
+         * Defines which part of the source wallpaper image is in the stored crop file.
+         *
+         * @param cropHints map from screen dimensions to a sub-region of the image to display
+         *                  for those dimensions. The {@code Rect} sub-region may have a larger
+         *                  width/height ratio than the screen dimensions to apply a horizontal
+         *                  parallax effect. If the map is empty or some entries are missing, the
+         *                  system will apply a default strategy to position the wallpaper for
+         *                  any unspecified screen dimensions.
+         * @hide
+         */
+        @NonNull
+        @TestApi
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setCropHints(@NonNull Map<Point, Rect> cropHints) {
+            mCropHints = new SparseArray<>();
+            cropHints.forEach(
+                    (point, rect) -> mCropHints.put(WallpaperManager.getOrientation(point), rect));
+            return this;
+        }
+
+        /**
+         * Defines which part of the source wallpaper image is in the stored crop file.
+         *
+         * @param cropHints map from {@link ScreenOrientation} to a sub-region of the image to
+         *                  display for that screen orientation.
+         * @hide
+         */
+        @NonNull
+        @TestApi
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setCropHints(@NonNull SparseArray<Rect> cropHints) {
+            mCropHints = cropHints;
+            return this;
+        }
+
+        /**
+         * How much the crop is sub-sampled. A value > 1 means that the image quality was reduced.
+         * This is the ratio between the cropHint height and the actual stored crop file height.
+         * height.
+         *
+         * @param sampleSize Sub-sampling value
+         * @hide
+         */
+        @NonNull
+        public Builder setSampleSize(float sampleSize) {
+            mSampleSize = sampleSize;
+            return this;
+        }
+
         /** Creates and returns the {@link WallpaperDescription} represented by this builder. */
         @NonNull
         public WallpaperDescription build() {
             return new WallpaperDescription(mComponent, mId, mThumbnail, mTitle, mDescription,
-                    mContextUri, mContextDescription, mContent);
+                    mContextUri, mContextDescription, mContent, mCropHints, mSampleSize);
         }
     }
+
+    private static List<Pair<Integer, String>> screenDimensionPairs() {
+        return List.of(
+                new Pair<>(WallpaperManager.ORIENTATION_PORTRAIT, "Portrait"),
+                new Pair<>(WallpaperManager.ORIENTATION_LANDSCAPE, "Landscape"),
+                new Pair<>(WallpaperManager.ORIENTATION_SQUARE_PORTRAIT, "SquarePortrait"),
+                new Pair<>(WallpaperManager.ORIENTATION_SQUARE_LANDSCAPE, "SquareLandscape"));
+    }
 }
diff --git a/core/java/android/app/wearable/WearableSensingManager.java b/core/java/android/app/wearable/WearableSensingManager.java
index f076375..5b14b03 100644
--- a/core/java/android/app/wearable/WearableSensingManager.java
+++ b/core/java/android/app/wearable/WearableSensingManager.java
@@ -55,6 +55,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
@@ -248,7 +249,11 @@
      * @param executor Executor on which to run the consumer callback
      * @param statusConsumer A consumer that handles the status codes for providing the connection
      *     and errors in the encrypted channel.
+     * @deprecated Use {@link #provideConnection(WearableConnection, Executor)} instead to provide a
+     *     remote wearable device connection to the WearableSensingService
      */
+    @FlaggedApi(Flags.FLAG_ENABLE_CONCURRENT_WEARABLE_CONNECTIONS)
+    @Deprecated
     @RequiresPermission(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE)
     public void provideConnection(
             @NonNull ParcelFileDescriptor wearableConnection,
@@ -348,9 +353,7 @@
                             wearableConnection.getMetadata(),
                             createWearableSensingCallback(executor),
                             statusCallback);
-            if (connectionId != CONNECTION_ID_INVALID) {
-                mWearableConnectionIdMap.put(wearableConnection, connectionId);
-            }
+            mWearableConnectionIdMap.put(wearableConnection, connectionId);
             // For invalid connection IDs, the status callback will remove the connection from
             // mWearableConnectionIdMap
         } catch (RemoteException e) {
@@ -367,36 +370,37 @@
      * <p>After this method returns, there will be no new invocation to callback methods in the
      * removed {@link WearableConnection}. Ongoing invocations will continue to run.
      *
-     * <p>This method does nothing if the provided {@code wearableConnection} does not match any
-     * open connection.
+     * <p>This method throws a {@link NoSuchElementException} if the provided {@code
+     * wearableConnection} does not match any open connection.
      *
      * <p>This method should not be called before the corresponding {@link
      * #provideConnection(WearableConnection, Executor)} invocation returns. Otherwise, the
-     * connection may not be removed.
+     * connection may not be removed, and an {@link IllegalStateException} may be thrown.
      *
      * @param wearableConnection The WearableConnection instance previously provided to {@link
      *     #provideConnection(WearableConnection, Executor)}.
-     * @return true if a concurrent connection quota has been freed due to this method invocation.
-     *     Returns false otherwise.
+     * @throws NoSuchElementException if the connection was never provided or was already removed.
+     * @throws IllegalStateException if the {@link #provideConnection(WearableConnection, Executor)}
+     *     invocation for the given connection has not returned.
      */
     @RequiresPermission(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE)
     @FlaggedApi(Flags.FLAG_ENABLE_CONCURRENT_WEARABLE_CONNECTIONS)
-    public boolean removeConnection(@NonNull WearableConnection wearableConnection) {
-        int connectionId =
-                mWearableConnectionIdMap.getOrDefault(wearableConnection, CONNECTION_ID_INVALID);
-        if (connectionId == CONNECTION_ID_INVALID) {
-            return false;
+    public void removeConnection(@NonNull WearableConnection wearableConnection) {
+        Integer connectionId = mWearableConnectionIdMap.remove(wearableConnection);
+        if (connectionId == null || connectionId == CONNECTION_ID_INVALID) {
+            throw new NoSuchElementException(
+                    "The provided connection was never provided or was already removed.");
         }
         if (connectionId == CONNECTION_ID_PLACEHOLDER) {
-            Slog.w(
-                    TAG,
+            throw new IllegalStateException(
                     "Attempt to remove connection before provideConnection returns. The connection"
                             + " will not be removed.");
-            return false;
         }
-        mWearableConnectionIdMap.remove(wearableConnection);
         try {
-            return mService.removeConnection(connectionId);
+            if (!mService.removeConnection(connectionId)) {
+                throw new NoSuchElementException(
+                        "The provided connection was never provided or was already removed.");
+            }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 8f20ea0..40de298 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -31,6 +31,7 @@
 import android.annotation.UserIdInt;
 import android.app.IServiceConnection;
 import android.app.PendingIntent;
+import android.app.usage.UsageStatsManager;
 import android.appwidget.flags.Flags;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
@@ -41,12 +42,14 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ShortcutInfo;
+import android.graphics.Rect;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.HandlerThread;
 import android.os.Looper;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -485,6 +488,67 @@
     public static final String ACTION_APPWIDGET_HOST_RESTORED
             = "android.appwidget.action.APPWIDGET_HOST_RESTORED";
 
+    /**
+     * This is the value of {@link UsageStatsManager.EXTRA_EVENT_ACTION} in the event bundle for
+     * widget user interaction events.
+     *
+     * A single widget interaction event describes what user interactions happened during a single
+     * impression of the widget.
+     */
+    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+    public static final String EVENT_TYPE_WIDGET_INTERACTION = "widget_interaction";
+
+    /**
+     * This is the value of {@link UsageStatsManager.EXTRA_EVENT_CATEGORY} in the event bundle for
+     * widget user interaction events.
+     */
+    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+    public static final String EVENT_CATEGORY_APPWIDGET = "android.appwidget";
+
+    /**
+     * This bundle extra describes which views have been clicked during a single impression of the
+     * widget. It is an integer array of view IDs of the clicked views.
+     *
+     * Widget providers may set a different ID for event purposes by setting the
+     * {@link android.R.id.remoteViewsMetricsId} int tag on the view.
+     *
+     * @see android.views.RemoteViews.setIntTag
+     */
+    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+    public static final String EXTRA_EVENT_CLICKED_VIEWS =
+            "android.appwidget.extra.EVENT_CLICKED_VIEWS";
+
+    /**
+     * This bundle extra describes which views have been scrolled during a single impression of the
+     * widget. It is an integer array of view IDs of the scrolled views.
+     *
+     * Widget providers may set a different ID for event purposes by setting the
+     * {@link android.R.id.remoteViewsMetricsId} int tag on the view.
+     *
+     * @see android.views.RemoteViews.setIntTag
+     */
+    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+    public static final String EXTRA_EVENT_SCROLLED_VIEWS =
+            "android.appwidget.extra.EVENT_SCROLLED_VIEWS";
+
+    /**
+     * This bundle extra contains a long that represents the duration of time in milliseconds
+     * during which the widget was visible.
+     */
+    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+    public static final String EXTRA_EVENT_DURATION_MS =
+            "android.appwidget.extra.EVENT_DURATION_MS";
+
+    /**
+     * This bundle extra contains an integer array with 4 elements that describe the left, top,
+     * right, and bottom coordinates of the widget at the end of the interaction event.
+     *
+     * This Rect indicates the current position and size of the widget.
+     */
+    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+    public static final String EXTRA_EVENT_POSITION_RECT =
+            "android.appwidget.extra.EVENT_POSITION_RECT";
+
     private static final String TAG = "AppWidgetManager";
 
     private static Executor sUpdateExecutor;
@@ -1516,6 +1580,39 @@
         }
     }
 
+    /**
+     * Create a {@link PersistableBundle} that represents a single widget interaction event.
+     *
+     * @param appWidgetId App Widget ID of the widget.
+     * @param durationMs Duration of the impression in milliseconds
+     * @param position Current position of the widget.
+     * @param clickedIds IDs of views clicked during this event.
+     * @param scrolledIds IDs of views scrolled during this event.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+    @NonNull
+    public static PersistableBundle createWidgetInteractionEvent(int appWidgetId, long durationMs,
+            @Nullable Rect position, @Nullable int[] clickedIds, @Nullable int[] scrolledIds) {
+        PersistableBundle extras = new PersistableBundle();
+        extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, EVENT_TYPE_WIDGET_INTERACTION);
+        extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, EVENT_CATEGORY_APPWIDGET);
+        extras.putInt(EXTRA_APPWIDGET_ID, appWidgetId);
+        extras.putLong(EXTRA_EVENT_DURATION_MS, durationMs);
+        if (position != null) {
+            extras.putIntArray(EXTRA_EVENT_POSITION_RECT,
+                    new int[]{position.left, position.top, position.right, position.bottom});
+        }
+        if (clickedIds != null && clickedIds.length > 0) {
+            extras.putIntArray(EXTRA_EVENT_CLICKED_VIEWS, clickedIds);
+        }
+        if (scrolledIds != null && scrolledIds.length > 0) {
+            extras.putIntArray(EXTRA_EVENT_SCROLLED_VIEWS, scrolledIds);
+        }
+        return extras;
+    }
+
 
     @UiThread
     private static @NonNull Executor createUpdateExecutorIfNull() {
diff --git a/core/java/android/appwidget/flags.aconfig b/core/java/android/appwidget/flags.aconfig
index fb33348..17bcdb0 100644
--- a/core/java/android/appwidget/flags.aconfig
+++ b/core/java/android/appwidget/flags.aconfig
@@ -76,12 +76,15 @@
 }
 
 flag {
-  name: "use_smaller_app_widget_radius"
+  name: "use_smaller_app_widget_system_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
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
 }
 
 flag {
@@ -102,3 +105,10 @@
     purpose: PURPOSE_BUGFIX
   }
 }
+
+flag {
+  name: "engagement_metrics"
+  namespace: "app_widgets"
+  description: "Enable collection of widget engagement metrics"
+  bug: "364655296"
+}
diff --git a/core/java/android/companion/CompanionDeviceService.java b/core/java/android/companion/CompanionDeviceService.java
index 5ad2348..db080fc 100644
--- a/core/java/android/companion/CompanionDeviceService.java
+++ b/core/java/android/companion/CompanionDeviceService.java
@@ -249,7 +249,7 @@
 
     // TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
     /**
-     * Called by system whenever a device associated with this app is connected.
+     * Called by the system when an associated device is nearby or connected.
      *
      * @param associationInfo A record for the companion device.
      */
@@ -262,7 +262,7 @@
 
     // TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
     /**
-     * Called by system whenever a device associated with this app is disconnected.
+     * Called by the system when an associated device is out of range or disconnected.
      *
      * @param associationInfo A record for the companion device.
      */
@@ -274,7 +274,7 @@
     }
 
     /**
-     * Called by the system during device events.
+     * Called by the system when an associated device's presence state changes.
      *
      * @see CompanionDeviceManager#startObservingDevicePresence(ObservingDevicePresenceRequest)
      */
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl
index d3a1c25..367f1af 100644
--- a/core/java/android/companion/virtual/IVirtualDevice.aidl
+++ b/core/java/android/companion/virtual/IVirtualDevice.aidl
@@ -90,11 +90,6 @@
      */
     boolean hasCustomAudioInputSupport();
 
-    /**
-     * Returns whether this device is allowed to create mirror displays.
-     */
-    boolean canCreateMirrorDisplays();
-
     /*
      * Turns off all trusted non-mirror displays of the virtual device.
      */
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index 3e6919b..46da4a3 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -81,14 +81,3 @@
   description: "Enable virtual stylus input"
   bug: "304829446"
 }
-
-flag {
-  name: "impulse_velocity_strategy_for_touch_navigation"
-  is_exported: true
-  namespace: "virtual_devices"
-  description: "Use impulse velocity strategy during conversion of touch navigation flings into Dpad events"
-  bug: "338426241"
-  metadata {
-    purpose: PURPOSE_BUGFIX
-  }
-}
\ No newline at end of file
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index acad92c9..6e2ca2c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4250,6 +4250,7 @@
             //@hide: WIFI_RTT_SERVICE,
             //@hide: ETHERNET_SERVICE,
             WIFI_RTT_RANGING_SERVICE,
+            WIFI_USD_SERVICE,
             NSD_SERVICE,
             AUDIO_SERVICE,
             AUDIO_DEVICE_VOLUME_SERVICE,
@@ -5096,6 +5097,19 @@
      */
     public static final String WIFI_RTT_RANGING_SERVICE = "wifirtt";
 
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a {@link
+     * android.net.wifi.usd.UsdManager} for Unsynchronized Service Discovery (USD) operation.
+     *
+     * @see #getSystemService(String)
+     * @see android.net.wifi.usd.UsdManager
+     * @hide
+     */
+    @FlaggedApi(android.net.wifi.flags.Flags.FLAG_USD)
+    @SystemApi
+    public static final String WIFI_USD_SERVICE = "wifi_usd";
+
     /**
      * Use with {@link #getSystemService(String)} to retrieve a {@link
      * android.net.lowpan.LowpanManager} for handling management of
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 8853304..02eed1a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1211,8 +1211,8 @@
      * {@link android.telecom.TelecomManager#placeCall(Uri, Bundle)} to place calls rather than
      * relying on this intent.
      *
-     * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M}
-     * and above and declares as using the {@link android.Manifest.permission#CALL_PHONE}
+     * <p>Note: If your app targets {@link android.os.Build.VERSION_CODES#M M}
+     * or higher and declares as using the {@link android.Manifest.permission#CALL_PHONE}
      * permission which is not granted, then attempting to use this action will
      * result in a {@link java.lang.SecurityException}.
      */
@@ -7720,6 +7720,7 @@
     @IntDef(flag = true, prefix = { "EXTENDED_FLAG_" }, value = {
             EXTENDED_FLAG_FILTER_MISMATCH,
             EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN,
+            EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ExtendedFlags {}
@@ -7740,6 +7741,13 @@
      */
     public static final int EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN = 1 << 1;
 
+    /**
+     * This flag indicates this intent called {@link #collectExtraIntentKeys()}.
+     *
+     * @hide
+     */
+    public static final int EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED = 1 << 2;
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // toUri() and parseUri() options.
@@ -12328,7 +12336,8 @@
     }
 
     private void collectNestedIntentKeysRecur(Set<Intent> visited) {
-        if (mExtras != null && !mExtras.isParcelled() && !mExtras.isEmpty()) {
+        addExtendedFlags(EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED);
+        if (mExtras != null && !mExtras.isEmpty()) {
             for (String key : mExtras.keySet()) {
                 Object value = mExtras.get(key);
 
diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java
index ed965b3..6db7dfe 100644
--- a/core/java/android/content/om/OverlayManager.java
+++ b/core/java/android/content/om/OverlayManager.java
@@ -78,7 +78,8 @@
 
     /**
      * Applications can use OverlayManager to create overlays to overlay on itself resources. The
-     * overlay target is itself and the work range is only in caller application.
+     * overlay target is itself, or the Android package, and the work range is only in caller
+     * application.
      *
      * <p>In {@link android.content.Context#getSystemService(String)}, it crashes because of {@link
      * java.lang.NullPointerException} if the parameter is OverlayManager. if the self-targeting is
@@ -401,7 +402,7 @@
     }
 
     /**
-     * Get the related information of overlays for {@code targetPackageName}.
+     * Get the related information of self-targeting overlays for {@code targetPackageName}.
      *
      * @param targetPackageName the target package name
      * @return a list of overlay information
diff --git a/core/java/android/content/om/OverlayManagerTransaction.java b/core/java/android/content/om/OverlayManagerTransaction.java
index becd0ea..87b2e93 100644
--- a/core/java/android/content/om/OverlayManagerTransaction.java
+++ b/core/java/android/content/om/OverlayManagerTransaction.java
@@ -209,6 +209,7 @@
      */
     public static final class Builder {
         private final List<Request> mRequests = new ArrayList<>();
+        private boolean mSelfTargeting = false;
 
         /**
          * Request that an overlay package be enabled and change its loading
@@ -246,6 +247,18 @@
         }
 
         /**
+         * Request that an overlay package be self-targeting. Self-targeting overlays enable
+         * applications to overlay on itself resources. The overlay target is itself, or the Android
+         * package, and the work range is only in caller application.
+         * @param selfTargeting whether the overlay is self-targeting, the default is false.
+         * @hide
+         */
+        public Builder setSelfTargeting(boolean selfTargeting) {
+            mSelfTargeting = selfTargeting;
+            return this;
+        }
+
+        /**
          * Registers the fabricated overlay with the overlay manager so it can be enabled and
          * disabled for any user.
          *
@@ -286,7 +299,7 @@
          */
         @NonNull
         public OverlayManagerTransaction build() {
-            return new OverlayManagerTransaction(mRequests, false /* selfTargeting */);
+            return new OverlayManagerTransaction(mRequests, mSelfTargeting);
         }
     }
 
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index b10f5e4..37f3f17 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -453,6 +453,13 @@
      * Value of {@link #colorMode} indicating that the activity should use a
      * high dynamic range if the presentation display supports it.
      *
+     * <p>Note: This does not impact SurfaceViews or SurfaceControls, as those have their own
+     * independent HDR support.</p>
+     *
+     * <p><b>Important:</b> Although this value was added in API 26, it is strongly recommended
+     * to avoid using it until API 34 which is when HDR support for the UI toolkit was officially
+     * added.</p>
+     *
      * @see android.R.attr#colorMode
      */
     public static final int COLOR_MODE_HDR = 2;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index cccfdb0..9478422 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1449,6 +1449,97 @@
         }
     }
 
+    /**
+     * Use this to report any errors during alignment checks
+     *
+     * @hide
+     */
+    public static final int PAGE_SIZE_APP_COMPAT_FLAG_ERROR = -1;
+
+    /**
+     * Initial value for mPageSizeAppCompatFlags
+     *
+     * @hide
+     */
+    public static final int PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED = 0;
+
+    /**
+     * if set, extract libs forcefully for 16 KB device and show warning dialog.
+     *
+     * @hide
+     */
+    public static final int PAGE_SIZE_APP_COMPAT_FLAG_UNCOMPRESSED_LIBS_NOT_ALIGNED = 1 << 1;
+
+    /**
+     * if set, load 4 KB aligned ELFs on 16 KB device in compat mode and show warning dialog.
+     *
+     * @hide
+     */
+    public static final int PAGE_SIZE_APP_COMPAT_FLAG_ELF_NOT_ALIGNED = 1 << 2;
+
+    /**
+     * Run in 16 KB app compat mode. This flag will be set explicitly through settings. If set, 16
+     * KB app compat warning dialogs will still show up.
+     *
+     * @hide
+     */
+    public static final int PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_ENABLED = 1 << 3;
+
+    /**
+     * Disable 16 KB app compat mode through settings. It should only affect ELF loading as app is
+     * already installed.
+     *
+     * @hide
+     */
+    public static final int PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_DISABLED = 1 << 4;
+
+    /**
+     * Run in 16 KB app compat mode. This flag will be set explicitly through manifest. If set, hide
+     * the 16 KB app compat warning dialogs. This has the highest priority to enable compat mode.
+     *
+     * @hide
+     */
+    public static final int PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_ENABLED = 1 << 5;
+
+    /**
+     * Disable 16 KB app compat mode. This has the highest priority to disable compat mode.
+     *
+     * @hide
+     */
+    public static final int PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_DISABLED = 1 << 6;
+
+    /**
+     * Max value for page size app compat
+     *
+     * @hide
+     */
+    public static final int PAGE_SIZE_APP_COMPAT_FLAG_MAX = 1 << 7;
+
+    /**
+     * 16 KB app compat status for the app. App can have native shared libs which are not page
+     * aligned, LOAD segments inside the shared libs have to be page aligned. Apps can specify the
+     * override in manifest file as well.
+     */
+    private @PageSizeAppCompatFlags int mPageSizeAppCompatFlags =
+            ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED;
+
+    /** {@hide} */
+    @IntDef(
+            prefix = {"PAGE_SIZE_APP_COMPAT_FLAG_"},
+            value = {
+                PAGE_SIZE_APP_COMPAT_FLAG_ERROR,
+                PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED,
+                PAGE_SIZE_APP_COMPAT_FLAG_UNCOMPRESSED_LIBS_NOT_ALIGNED,
+                PAGE_SIZE_APP_COMPAT_FLAG_ELF_NOT_ALIGNED,
+                PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_ENABLED,
+                PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_DISABLED,
+                PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_ENABLED,
+                PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_DISABLED,
+                PAGE_SIZE_APP_COMPAT_FLAG_MAX,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PageSizeAppCompatFlags {}
+
     /** @hide */
     public String classLoaderName;
 
@@ -1777,7 +1868,7 @@
             pw.println(prefix + "enableOnBackInvokedCallback=" + isOnBackInvokedCallbackEnabled());
             pw.println(prefix + "allowCrossUidActivitySwitchFromBelow="
                     + allowCrossUidActivitySwitchFromBelow);
-
+            pw.println(prefix + "mPageSizeAppCompatFlags=" + mPageSizeAppCompatFlags);
         }
         pw.println(prefix + "createTimestamp=" + createTimestamp);
         if (mKnownActivityEmbeddingCerts != null) {
@@ -1897,6 +1988,10 @@
             }
             proto.write(ApplicationInfoProto.Detail.ALLOW_CROSS_UID_ACTIVITY_SWITCH_FROM_BELOW,
                     allowCrossUidActivitySwitchFromBelow);
+
+            proto.write(ApplicationInfoProto.Detail.ENABLE_PAGE_SIZE_APP_COMPAT,
+                        mPageSizeAppCompatFlags);
+
             proto.end(detailToken);
         }
         if (!ArrayUtils.isEmpty(mKnownActivityEmbeddingCerts)) {
@@ -2024,6 +2119,7 @@
         localeConfigRes = orig.localeConfigRes;
         allowCrossUidActivitySwitchFromBelow = orig.allowCrossUidActivitySwitchFromBelow;
         createTimestamp = SystemClock.uptimeMillis();
+        mPageSizeAppCompatFlags = orig.mPageSizeAppCompatFlags;
     }
 
     public String toString() {
@@ -2128,6 +2224,7 @@
         }
         dest.writeInt(localeConfigRes);
         dest.writeInt(allowCrossUidActivitySwitchFromBelow ? 1 : 0);
+        dest.writeInt(mPageSizeAppCompatFlags);
 
         sForStringSet.parcel(mKnownActivityEmbeddingCerts, dest, flags);
     }
@@ -2228,6 +2325,7 @@
         }
         localeConfigRes = source.readInt();
         allowCrossUidActivitySwitchFromBelow = source.readInt() != 0;
+        mPageSizeAppCompatFlags = source.readInt();
 
         mKnownActivityEmbeddingCerts = sForStringSet.unparcel(source);
         if (mKnownActivityEmbeddingCerts.isEmpty()) {
@@ -2765,6 +2863,11 @@
         requestRawExternalStorageAccess = value;
     }
 
+    /** {@hide} */
+    public void setPageSizeAppCompatFlags(@PageSizeAppCompatFlags int value) {
+        mPageSizeAppCompatFlags |= value;
+    }
+
     /**
      * Replaces {@link #mAppClassNamesByProcess}. This takes over the ownership of the passed map.
      * Do not modify the argument at the callsite.
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index 4fdbf1e9e..451c0e5 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -93,10 +93,4 @@
 
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES,android.Manifest.permission.REQUEST_INSTALL_PACKAGES})")
     void reportUnarchivalStatus(int unarchiveId, int status, long requiredStorageBytes, in PendingIntent userActionIntent, in UserHandle userHandle);
-
-    @EnforcePermission("VERIFICATION_AGENT")
-    int getVerificationPolicy(int userId);
-
-    @EnforcePermission("VERIFICATION_AGENT")
-    boolean setVerificationPolicy(int policy, int userId);
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 5d4babb..9f898b8 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -848,4 +848,12 @@
     int getAppMetadataSource(String packageName, int userId);
 
     ComponentName getDomainVerificationAgent(int userId);
+
+    void setPageSizeAppCompatFlagsSettingsOverride(in String packageName, boolean enabled);
+
+    boolean isPageSizeCompatEnabled(in String packageName);
+
+    String getPageSizeCompatWarningMessage(in String packageName);
+
+    List<String> getAllApexDirectories();
 }
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 63279af..cd62573 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -62,8 +62,6 @@
 import android.content.pm.parsing.result.ParseResult;
 import android.content.pm.parsing.result.ParseTypeImpl;
 import android.content.pm.verify.domain.DomainSet;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerificationStatus;
 import android.graphics.Bitmap;
 import android.icu.util.ULocale;
 import android.net.Uri;
@@ -220,6 +218,17 @@
             "android.content.pm.action.CONFIRM_PRE_APPROVAL";
 
     /**
+     * Intent action to be sent to the implementer of
+     * {@link android.content.pm.dependencyinstaller.DependencyInstallerService}.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
+    @SystemApi
+    public static final String ACTION_INSTALL_DEPENDENCY =
+            "android.content.pm.action.INSTALL_DEPENDENCY";
+
+    /**
      * An integer session ID that an operation is working with.
      *
      * @see Intent#getIntExtra(String, int)
@@ -420,21 +429,6 @@
     public static final String EXTRA_WARNINGS = "android.content.pm.extra.WARNINGS";
 
     /**
-     * When verification is blocked as part of the installation, additional reason for the block
-     * will be provided to the installer with a {@link VerificationFailedReason} as part of the
-     * installation result returned via the {@link IntentSender} in
-     * {@link Session#commit(IntentSender)}. This extra is provided only when the installation has
-     * failed. Installers can use this extra to check if the installation failure was caused by a
-     * verification failure.
-     *
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    public static final String EXTRA_VERIFICATION_FAILURE_REASON =
-            "android.content.pm.extra.VERIFICATION_FAILURE_REASON";
-
-    /**
      * Streaming installation pending.
      * Caller should make sure DataLoader is able to prepare image and reinitiate the operation.
      *
@@ -777,90 +771,6 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface UnarchivalStatus {}
 
-    /**
-     * Verification failed because of unknown reasons, such as when the verifier times out or cannot
-     * be connected. It can also corresponds to the status of
-     * {@link VerificationSession#VERIFICATION_INCOMPLETE_UNKNOWN} reported by the verifier via
-     * {@link VerificationSession#reportVerificationIncomplete(int)}.
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    public static final int VERIFICATION_FAILED_REASON_UNKNOWN = 0;
-
-    /**
-     * Verification failed because the network is unavailable. This corresponds to the status of
-     * {@link VerificationSession#VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE} reported by the
-     * verifier via {@link VerificationSession#reportVerificationIncomplete(int)}.
-     *
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    public static final int VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE = 1;
-
-    /**
-     * Verification failed because the package is blocked, as reported by the verifier via
-     * {@link VerificationSession#reportVerificationComplete(VerificationStatus)} or
-     * {@link VerificationSession#reportVerificationComplete(VerificationStatus, PersistableBundle)}
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    public static final int VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED = 2;
-
-    /**
-     * @hide
-     */
-    @IntDef(value = {
-            VERIFICATION_FAILED_REASON_UNKNOWN,
-            VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE,
-            VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED,
-    })
-    public @interface VerificationFailedReason {
-    }
-
-    /**
-     * Do not block installs, regardless of verification status.
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    public static final int VERIFICATION_POLICY_NONE = 0; // platform default
-    /**
-     * Only block installations on {@link #VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED}.
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    public static final int VERIFICATION_POLICY_BLOCK_FAIL_OPEN = 1;
-    /**
-     * Only block installations on {@link #VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED} and ask the
-     * user if they'd like to install anyway when the verification is blocked for other reason.
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    public static final int VERIFICATION_POLICY_BLOCK_FAIL_WARN = 2;
-    /**
-     * Block installations whose verification status is blocked for any reason.
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    public static final int VERIFICATION_POLICY_BLOCK_FAIL_CLOSED = 3;
-    /**
-     * @hide
-     */
-    @IntDef(value = {
-            VERIFICATION_POLICY_NONE,
-            VERIFICATION_POLICY_BLOCK_FAIL_OPEN,
-            VERIFICATION_POLICY_BLOCK_FAIL_WARN,
-            VERIFICATION_POLICY_BLOCK_FAIL_CLOSED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface VerificationPolicy {
-    }
 
     /** Default set of checksums - includes all available checksums.
      * @see Session#requestChecksums  */
@@ -1604,40 +1514,6 @@
     }
 
     /**
-     * Return the current verification enforcement policy. This may only be called by the
-     * package currently set by the system as the verifier agent.
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
-    public final @VerificationPolicy int getVerificationPolicy() {
-        try {
-            return mInstaller.getVerificationPolicy(mUserId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Set the current verification enforcement policy which will be applied to all the future
-     * installation sessions. This may only be called by the package currently set by the system as
-     * the verifier agent.
-     * @hide
-     * @return whether the new policy was successfully set.
-     */
-    @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
-    public final boolean setVerificationPolicy(@VerificationPolicy int policy) {
-        try {
-            return mInstaller.setVerificationPolicy(policy, mUserId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * An installation that is being actively staged. For an install to succeed,
      * all existing and new packages must have identical package names, version
      * codes, and signing certificates.
@@ -2935,8 +2811,6 @@
         /** {@hide} */
         public @Nullable String dexoptCompilerFilter = null;
         /** {@hide} */
-        public boolean forceVerification;
-        /** {@hide} */
         public boolean isAutoInstallDependenciesEnabled = true;
 
         private final ArrayMap<String, Integer> mPermissionStates;
@@ -2992,7 +2866,6 @@
             developmentInstallFlags = source.readInt();
             unarchiveId = source.readInt();
             dexoptCompilerFilter = source.readString();
-            forceVerification = source.readBoolean();
             isAutoInstallDependenciesEnabled = source.readBoolean();
         }
 
@@ -3030,7 +2903,6 @@
             ret.developmentInstallFlags = developmentInstallFlags;
             ret.unarchiveId = unarchiveId;
             ret.dexoptCompilerFilter = dexoptCompilerFilter;
-            ret.forceVerification = forceVerification;
             ret.isAutoInstallDependenciesEnabled = isAutoInstallDependenciesEnabled;
             return ret;
         }
@@ -3741,14 +3613,6 @@
         }
 
         /**
-         * Used by adb installations to force enable the verification for this install.
-         * {@hide}
-         */
-        public void setForceVerification() {
-            this.forceVerification = true;
-        }
-
-        /**
          * Optionally indicate whether missing SDK or static shared library dependencies should be
          * automatically fetched and installed when installing an app that wants to use these
          * dependencies.
@@ -3761,7 +3625,7 @@
          *                                      dependencies aren't already installed.
          */
         @FlaggedApi(Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
-        public void setEnableAutoInstallDependencies(boolean enableAutoInstallDependencies) {
+        public void setAutoInstallDependenciesEnabled(boolean enableAutoInstallDependencies) {
             isAutoInstallDependenciesEnabled = enableAutoInstallDependencies;
         }
 
@@ -3800,7 +3664,6 @@
             pw.printHexPair("developmentInstallFlags", developmentInstallFlags);
             pw.printPair("unarchiveId", unarchiveId);
             pw.printPair("dexoptCompilerFilter", dexoptCompilerFilter);
-            pw.printPair("forceVerification", forceVerification);
             pw.printPair("isAutoInstallDependenciesEnabled", isAutoInstallDependenciesEnabled);
             pw.println();
         }
@@ -3848,7 +3711,6 @@
             dest.writeInt(developmentInstallFlags);
             dest.writeInt(unarchiveId);
             dest.writeString(dexoptCompilerFilter);
-            dest.writeBoolean(forceVerification);
             dest.writeBoolean(isAutoInstallDependenciesEnabled);
         }
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 5b305b4..23d3693 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -804,7 +804,6 @@
         @Deprecated
         private void __metadata() {}
 
-
         //@formatter:on
         // End of generated code
 
@@ -5182,25 +5181,6 @@
             "android.content.pm.action.REQUEST_PERMISSIONS_FOR_OTHER";
 
     /**
-     * Used by the system to query a {@link android.content.pm.verify.pkg.VerifierService} provider,
-     * which registers itself via an intent-filter handling this action.
-     *
-     * <p class="note">Only the system can bind to such a verifier service. This is protected by the
-     * {@link android.Manifest.permission#BIND_VERIFICATION_AGENT} permission. The verifier service
-     * app should protect the service by adding this permission in the service declaration in its
-     * manifest.
-     * <p>
-     * A verifier service must be a privileged app and hold the
-     * {@link android.Manifest.permission#VERIFICATION_AGENT} permission.
-     *
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(android.content.pm.Flags.FLAG_VERIFICATION_SERVICE)
-    @SdkConstant(SdkConstantType.SERVICE_ACTION)
-    public static final String ACTION_VERIFY_PACKAGE = "android.content.pm.action.VERIFY_PACKAGE";
-
-    /**
      * The names of the requested permissions.
      * <p>
      * <strong>Type:</strong> String[]
@@ -6748,6 +6728,11 @@
      * If the given permission already exists, the info you supply here
      * will be used to update it.
      *
+     * @deprecated Support for dynamic permissions is going to be removed, and apps that use dynamic
+     * permissions should declare their permissions statically inside their app manifest instead.
+     * This method will become a no-op in a future Android release and eventually be removed from
+     * the SDK.
+     *
      * @param info Description of the permission to be added.
      *
      * @return Returns true if a new permission was created, false if an
@@ -6758,7 +6743,9 @@
      *
      * @see #removePermission(String)
      */
-    //@Deprecated
+    @SuppressWarnings("HiddenAbstractMethod")
+    @FlaggedApi(android.permission.flags.Flags.FLAG_PERMISSION_TREE_APIS_DEPRECATED)
+    @Deprecated
     public abstract boolean addPermission(@NonNull PermissionInfo info);
 
     /**
@@ -6767,8 +6754,15 @@
      * allowing it to return quicker and batch a series of adds at the
      * expense of no guarantee the added permission will be retained if
      * the device is rebooted before it is written.
+     *
+     * @deprecated Support for dynamic permissions is going to be removed, and apps that use dynamic
+     * permissions should declare their permissions statically inside their app manifest instead.
+     * This method will become a no-op in a future Android release and eventually be removed from
+     * the SDK.
      */
-    //@Deprecated
+    @SuppressWarnings("HiddenAbstractMethod")
+    @FlaggedApi(android.permission.flags.Flags.FLAG_PERMISSION_TREE_APIS_DEPRECATED)
+    @Deprecated
     public abstract boolean addPermissionAsync(@NonNull PermissionInfo info);
 
     /**
@@ -6777,6 +6771,11 @@
      * -- you are only allowed to remove permissions that you are allowed
      * to add.
      *
+     * @deprecated Support for dynamic permissions is going to be removed, and apps that use dynamic
+     * permissions should declare their permissions statically inside their app manifest instead.
+     * This method will become a no-op in a future Android release and eventually be removed from
+     * the SDK.
+     *
      * @param permName The name of the permission to remove.
      *
      * @throws SecurityException if you are not allowed to remove the
@@ -6784,7 +6783,9 @@
      *
      * @see #addPermission(PermissionInfo)
      */
-    //@Deprecated
+    @SuppressWarnings("HiddenAbstractMethod")
+    @FlaggedApi(android.permission.flags.Flags.FLAG_PERMISSION_TREE_APIS_DEPRECATED)
+    @Deprecated
     public abstract void removePermission(@NonNull String permName);
 
     /**
@@ -11006,6 +11007,41 @@
     }
 
     /**
+     * Set the page compat mode override for given package
+     *
+     * @hide
+     */
+    @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB)
+    public void setPageSizeAppCompatFlagsSettingsOverride(@NonNull String packageName,
+            boolean enabled) {
+        throw new UnsupportedOperationException(
+                "setPageSizeAppCompatFlagsSettingsOverride not implemented in subclass");
+    }
+
+    /**
+     * Check whether page size app compat mode is enabled for given package
+     *
+     * @hide
+     */
+    @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB)
+    public boolean isPageSizeCompatEnabled(@NonNull String packageName) {
+        throw new UnsupportedOperationException(
+                "isPageSizeCompatEnabled not implemented in subclass");
+    }
+
+    /**
+     * Get the page size app compat warning dialog to show at app launch time
+     *
+     * @hide
+     */
+    @Nullable
+    @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB)
+    public String getPageSizeCompatWarningMessage(@NonNull String packageName) {
+        throw new UnsupportedOperationException(
+                "getPageSizeCompatWarningMessage not implemented in subclass");
+    }
+
+     /**
      * Returns the harmful app warning string for the given app, or null if there is none set.
      *
      * @param packageName The full name of the desired package.
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index e181ae8..fbe581c 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -312,14 +312,6 @@
 }
 
 flag {
-    name: "verification_service"
-    namespace: "package_manager_service"
-    description: "Feature flag to enable the new verification service."
-    bug: "360129103"
-    is_fixed_read_only: true
-}
-
-flag {
     name: "sdk_dependency_installer"
     is_exported: true
     namespace: "package_manager_service"
@@ -364,7 +356,7 @@
     name: "support_minor_versions_in_minsdkversion"
     namespace: "package_manager_service"
     description: "Block app installations that specify an incompatible minor SDK version"
-    bug: "377474232"
+    bug: "377302905"
 }
 
 flag {
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 813208d..833260a 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -341,6 +341,28 @@
   is_fixed_read_only: true
 }
 
+flag {
+    name: "cache_user_start_realtime_read_only"
+    namespace: "multiuser"
+    description: "Cache getUserStartRealtime to avoid unnecessary binder calls"
+    bug: "350416205"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+  }
+  is_fixed_read_only: true
+}
+
+flag {
+    name: "cache_user_unlock_realtime_read_only"
+    namespace: "multiuser"
+    description: "Cache getUserUnlockRealtime to avoid unnecessary binder calls"
+    bug: "350421407"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+  }
+  is_fixed_read_only: true
+}
+
 # This flag guards the private space feature and all its implementations excluding the APIs. APIs are guarded by android.os.Flags.allow_private_profile.
 flag {
     name: "enable_private_space_features"
diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java
index c83cf96..1d8209d 100644
--- a/core/java/android/content/pm/parsing/ApkLite.java
+++ b/core/java/android/content/pm/parsing/ApkLite.java
@@ -142,6 +142,11 @@
     private final boolean mIsSdkLibrary;
 
     /**
+     * Indicates if this apk is a static library.
+     */
+    private final boolean mIsStaticLibrary;
+
+    /**
      * List of SDK names used by this apk.
      */
     private final @NonNull List<String> mUsesSdkLibraries;
@@ -191,7 +196,7 @@
             Set<String> requiredSplitTypes, Set<String> splitTypes,
             boolean hasDeviceAdminReceiver, boolean isSdkLibrary,
             List<String> usesSdkLibraries, long[] usesSdkLibrariesVersionsMajor,
-            String[][] usesSdkLibrariesCertDigests,
+            String[][] usesSdkLibrariesCertDigests, boolean isStaticLibrary,
             List<String> usesStaticLibraries, long[] usesStaticLibrariesVersionsMajor,
             String[][] usesStaticLibrariesCertDigests,
             boolean updatableSystem,
@@ -229,6 +234,7 @@
         mRollbackDataPolicy = rollbackDataPolicy;
         mHasDeviceAdminReceiver = hasDeviceAdminReceiver;
         mIsSdkLibrary = isSdkLibrary;
+        mIsStaticLibrary = isStaticLibrary;
         mUsesSdkLibraries = usesSdkLibraries;
         mUsesSdkLibrariesVersionsMajor = usesSdkLibrariesVersionsMajor;
         mUsesSdkLibrariesCertDigests = usesSdkLibrariesCertDigests;
@@ -275,6 +281,7 @@
         mRollbackDataPolicy = 0;
         mHasDeviceAdminReceiver = false;
         mIsSdkLibrary = false;
+        mIsStaticLibrary = false;
         mUsesSdkLibraries = Collections.emptyList();
         mUsesSdkLibrariesVersionsMajor = null;
         mUsesSdkLibrariesCertDigests = null;
@@ -594,6 +601,14 @@
     }
 
     /**
+     * Indicates if this apk is a static library.
+     */
+    @DataClass.Generated.Member
+    public boolean isIsStaticLibrary() {
+        return mIsStaticLibrary;
+    }
+
+    /**
      * List of SDK names used by this apk.
      */
     @DataClass.Generated.Member
@@ -662,10 +677,10 @@
     }
 
     @DataClass.Generated(
-            time = 1730202160705L,
+            time = 1731589363302L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\nprivate final  boolean mIsSdkLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final  boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\nprivate final  boolean mIsSdkLibrary\nprivate final  boolean mIsStaticLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final  boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 5981cbe..18a45d8d 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -44,6 +44,7 @@
 
 import com.android.internal.pm.pkg.component.flags.Flags;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.XmlUtils;
 
 import libcore.io.IoUtils;
 import libcore.util.HexEncoding;
@@ -465,6 +466,7 @@
         boolean hasDeviceAdminReceiver = false;
 
         boolean isSdkLibrary = false;
+        boolean isStaticLibrary = false;
         List<String> usesSdkLibraries = new ArrayList<>();
         long[] usesSdkLibrariesVersionsMajor = new long[0];
         String[][] usesSdkLibrariesCertDigests = new String[0][0];
@@ -542,8 +544,13 @@
                             }
                             String usesSdkLibName = parser.getAttributeValue(
                                     ANDROID_RES_NAMESPACE, "name");
-                            long usesSdkLibVersionMajor = parser.getAttributeIntValue(
-                                    ANDROID_RES_NAMESPACE, "versionMajor", -1);
+                            // TODO(b/379219371): Due to a bug in bundletool, some apps can use
+                            //  versionMajor as string. Until it is resolved, we are adding a
+                            //  workaround here.
+                            String usesSdkLibVersionMajorString = parser.getAttributeValue(
+                                    ANDROID_RES_NAMESPACE, "versionMajor");
+                            long usesSdkLibVersionMajor = XmlUtils.convertValueToInt(
+                                    usesSdkLibVersionMajorString, -1);
                             String usesSdkCertDigest = parser.getAttributeValue(
                                      ANDROID_RES_NAMESPACE, "certDigest");
 
@@ -588,9 +595,6 @@
                                     /*allowDuplicates=*/ true);
                             break;
                         case TAG_USES_STATIC_LIBRARY:
-                            if (!android.content.pm.Flags.sdkDependencyInstaller()) {
-                                break;
-                            }
                             String usesStaticLibName = parser.getAttributeValue(
                                     ANDROID_RES_NAMESPACE, "name");
                             long usesStaticLibVersion = parser.getAttributeIntValue(
@@ -659,6 +663,7 @@
                                     SharedLibraryInfo.TYPE_SDK_PACKAGE));
                             break;
                         case TAG_STATIC_LIBRARY:
+                            isStaticLibrary = true;
                             // Mirrors ParsingPackageUtils#parseStaticLibrary until lite and full
                             // parsing are combined
                             String staticLibName = parser.getAttributeValue(
@@ -812,7 +817,7 @@
                         requiredSystemPropertyValue, minSdkVersion, targetSdkVersion,
                         rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second,
                         hasDeviceAdminReceiver, isSdkLibrary, usesSdkLibraries,
-                        usesSdkLibrariesVersionsMajor, usesSdkLibrariesCertDigests,
+                        usesSdkLibrariesVersionsMajor, usesSdkLibrariesCertDigests, isStaticLibrary,
                         usesStaticLibraries, usesStaticLibrariesVersions,
                         usesStaticLibrariesCertDigests, updatableSystem, emergencyInstaller,
                         declaredLibraries));
diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java
index 76b25fe..0e11eec 100644
--- a/core/java/android/content/pm/parsing/PackageLite.java
+++ b/core/java/android/content/pm/parsing/PackageLite.java
@@ -114,6 +114,10 @@
      * Indicates if this package is a sdk.
      */
     private final boolean mIsSdkLibrary;
+    /**
+     * Indicates if this package is a static library.
+     */
+    private final boolean mIsStaticLibrary;
 
     private final @NonNull List<String> mUsesSdkLibraries;
 
@@ -164,6 +168,7 @@
         mUsesSdkLibraries = baseApk.getUsesSdkLibraries();
         mUsesSdkLibrariesVersionsMajor = baseApk.getUsesSdkLibrariesVersionsMajor();
         mUsesSdkLibrariesCertDigests = baseApk.getUsesSdkLibrariesCertDigests();
+        mIsStaticLibrary = baseApk.isIsStaticLibrary();
         mUsesStaticLibraries = baseApk.getUsesStaticLibraries();
         mUsesStaticLibrariesVersions = baseApk.getUsesStaticLibrariesVersions();
         mUsesStaticLibrariesCertDigests = baseApk.getUsesStaticLibrariesCertDigests();
@@ -455,6 +460,14 @@
         return mIsSdkLibrary;
     }
 
+    /**
+     * Indicates if this package is a static library.
+     */
+    @DataClass.Generated.Member
+    public boolean isIsStaticLibrary() {
+        return mIsStaticLibrary;
+    }
+
     @DataClass.Generated.Member
     public @NonNull List<String> getUsesSdkLibraries() {
         return mUsesSdkLibraries;
@@ -499,10 +512,10 @@
     }
 
     @DataClass.Generated(
-            time = 1730203707341L,
+            time = 1731591578587L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\nprivate final  boolean mIsSdkLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\nprivate final  boolean mIsSdkLibrary\nprivate final  boolean mIsStaticLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/verify/pkg/IVerificationSessionInterface.aidl b/core/java/android/content/pm/verify/pkg/IVerificationSessionInterface.aidl
deleted file mode 100644
index 2ab7452..0000000
--- a/core/java/android/content/pm/verify/pkg/IVerificationSessionInterface.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.os.PersistableBundle;
-
-/**
- * Non-oneway interface that allows the verifier to communicate with the system.
- * @hide
- */
-interface IVerificationSessionInterface {
-    long getTimeoutTime(int verificationId);
-    long extendTimeRemaining(int verificationId, long additionalMs);
-    boolean setVerificationPolicy(int verificationId, int policy);
-    void reportVerificationIncomplete(int verificationId, int reason);
-    void reportVerificationComplete(int verificationId, in VerificationStatus status, in @nullable PersistableBundle extensionResponse);
-}
\ No newline at end of file
diff --git a/core/java/android/content/pm/verify/pkg/IVerifierService.aidl b/core/java/android/content/pm/verify/pkg/IVerifierService.aidl
deleted file mode 100644
index d3071fd..0000000
--- a/core/java/android/content/pm/verify/pkg/IVerifierService.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-import android.content.pm.verify.pkg.VerificationSession;
-
-/**
- * Oneway interface that allows the system to communicate to the verifier service agent.
- * @hide
- */
-oneway interface IVerifierService {
-    void onPackageNameAvailable(in String packageName);
-    void onVerificationCancelled(in String packageName);
-    void onVerificationRequired(in VerificationSession session);
-    void onVerificationRetry(in VerificationSession session);
-    void onVerificationTimeout(int verificationId);
-}
\ No newline at end of file
diff --git a/core/java/android/content/pm/verify/pkg/VerificationSession.java b/core/java/android/content/pm/verify/pkg/VerificationSession.java
deleted file mode 100644
index 97f78e0..0000000
--- a/core/java/android/content/pm/verify/pkg/VerificationSession.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.content.pm.Flags;
-import android.content.pm.PackageInstaller;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningInfo;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * This class is used by the system to describe the details about a verification request sent to the
- * verification agent, aka the verifier. It includes the interfaces for the verifier to communicate
- * back to the system.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-@SystemApi
-public final class VerificationSession implements Parcelable {
-    /**
-     * The verification cannot be completed because of unknown reasons.
-     */
-    public static final int VERIFICATION_INCOMPLETE_UNKNOWN = 0;
-    /**
-     * The verification cannot be completed because the network is unavailable.
-     */
-    public static final int VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE = 1;
-
-    /**
-     * @hide
-     */
-    @IntDef(prefix = {"VERIFICATION_INCOMPLETE_"}, value = {
-            VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE,
-            VERIFICATION_INCOMPLETE_UNKNOWN,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface VerificationIncompleteReason {
-    }
-
-    private final int mId;
-    private final int mInstallSessionId;
-    @NonNull
-    private final String mPackageName;
-    @NonNull
-    private final Uri mStagedPackageUri;
-    @NonNull
-    private final SigningInfo mSigningInfo;
-    @NonNull
-    private final List<SharedLibraryInfo> mDeclaredLibraries;
-    @NonNull
-    private final PersistableBundle mExtensionParams;
-    @NonNull
-    private final IVerificationSessionInterface mSession;
-    /**
-     * The current policy that is active for the session. It might not be
-     * the same as the original policy that was initially assigned for this verification session,
-     * because the active policy can be overridden by {@link #setVerificationPolicy(int)}.
-     * <p>To improve the latency, store the original policy value and any changes made to it,
-     * so that {@link #getVerificationPolicy()} does not need to make a binder call to retrieve the
-     * currently active policy.</p>
-     */
-    private volatile @PackageInstaller.VerificationPolicy int mVerificationPolicy;
-
-    /**
-     * Constructor used by the system to describe the details of a verification session.
-     * @hide
-     */
-    public VerificationSession(int id, int installSessionId, @NonNull String packageName,
-            @NonNull Uri stagedPackageUri, @NonNull SigningInfo signingInfo,
-            @NonNull List<SharedLibraryInfo> declaredLibraries,
-            @NonNull PersistableBundle extensionParams,
-            @PackageInstaller.VerificationPolicy int defaultPolicy,
-            @NonNull IVerificationSessionInterface session) {
-        mId = id;
-        mInstallSessionId = installSessionId;
-        mPackageName = packageName;
-        mStagedPackageUri = stagedPackageUri;
-        mSigningInfo = signingInfo;
-        mDeclaredLibraries = declaredLibraries;
-        mExtensionParams = extensionParams;
-        mVerificationPolicy = defaultPolicy;
-        mSession = session;
-    }
-
-    /**
-     * A unique identifier tied to this specific verification session.
-     */
-    public int getId() {
-        return mId;
-    }
-
-    /**
-     * The package name of the app that is to be verified.
-     */
-    public @NonNull String getPackageName() {
-        return mPackageName;
-    }
-
-    /**
-     * The id of the installation session associated with the verification.
-     */
-    public int getInstallSessionId() {
-        return mInstallSessionId;
-    }
-
-    /**
-     * The Uri of the path where the package's code files are located.
-     */
-    public @NonNull Uri getStagedPackageUri() {
-        return mStagedPackageUri;
-    }
-
-    /**
-     * Signing info of the package to be verified.
-     */
-    public @NonNull SigningInfo getSigningInfo() {
-        return mSigningInfo;
-    }
-
-    /**
-     * Returns a mapping of any shared libraries declared in the manifest
-     * to the {@link SharedLibraryInfo.Type} that is declared. This will be an empty
-     * map if no shared libraries are declared by the package.
-     */
-    @NonNull
-    public List<SharedLibraryInfo> getDeclaredLibraries() {
-        return Collections.unmodifiableList(mDeclaredLibraries);
-    }
-
-    /**
-     * Returns any extension params associated with the verification request.
-     */
-    @NonNull
-    public PersistableBundle getExtensionParams() {
-        return mExtensionParams;
-    }
-
-    /**
-     * Get the value of Clock.elapsedRealtime() at which time this verification
-     * will timeout as incomplete if no other verification response is provided.
-     * @throws SecurityException if the caller is not the current verifier bound by the system.
-     */
-    public long getTimeoutTime() {
-        try {
-            return mSession.getTimeoutTime(mId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return the current policy that is active for this session.
-     * <p>If the policy for this session has been changed by {@link #setVerificationPolicy},
-     * the return value of this method is the current policy that is active for this session.
-     * Otherwise, the return value is the same as the initial policy that was assigned to the
-     * session when it was first created.</p>
-     */
-    public @PackageInstaller.VerificationPolicy int getVerificationPolicy() {
-        return mVerificationPolicy;
-    }
-
-    /**
-     * Override the verification policy for this session.
-     * @return True if the override was successful, False otherwise.
-     * @throws SecurityException if the caller is not the current verifier bound by the system.
-     */
-    public boolean setVerificationPolicy(@PackageInstaller.VerificationPolicy int policy) {
-        if (mVerificationPolicy == policy) {
-            // No effective policy change
-            return true;
-        }
-        try {
-            if (mSession.setVerificationPolicy(mId, policy)) {
-                mVerificationPolicy = policy;
-                return true;
-            } else {
-                return false;
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Extend the timeout for this session by the provided additionalMs to
-     * fetch relevant information over the network or wait for the network.
-     * This may be called multiple times. If the request would bypass any max
-     * duration by the system, the method will return a lower value than the
-     * requested amount that indicates how much the time was extended.
-     * @throws SecurityException if the caller is not the current verifier bound by the system.
-     */
-    public long extendTimeRemaining(long additionalMs) {
-        try {
-            return mSession.extendTimeRemaining(mId, additionalMs);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Report to the system that verification could not be completed along
-     * with an approximate reason to pass on to the installer.]
-     * @throws SecurityException if the caller is not the current verifier bound by the system.
-     */
-    public void reportVerificationIncomplete(@VerificationIncompleteReason int reason) {
-        try {
-            mSession.reportVerificationIncomplete(mId, reason);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Report to the system that the verification has completed and the
-     * install process may act on that status to either block in the case
-     * of failure or continue to process the install in the case of success.
-     * @throws SecurityException if the caller is not the current verifier bound by the system.
-     */
-    public void reportVerificationComplete(@NonNull VerificationStatus status) {
-        try {
-            mSession.reportVerificationComplete(mId, status,  /* extensionResponse= */ null);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Same as {@link #reportVerificationComplete(VerificationStatus)}, but also provide
-     * a result to the extension params provided in the request, which will be passed to the
-     * installer in the installation result.
-     * @throws SecurityException if the caller is not the current verifier bound by the system.
-     */
-    public void reportVerificationComplete(@NonNull VerificationStatus status,
-            @NonNull PersistableBundle extensionResponse) {
-        try {
-            mSession.reportVerificationComplete(mId, status, extensionResponse);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    private VerificationSession(@NonNull Parcel in) {
-        mId = in.readInt();
-        mInstallSessionId = in.readInt();
-        mPackageName = in.readString8();
-        mStagedPackageUri = Uri.CREATOR.createFromParcel(in);
-        mSigningInfo = SigningInfo.CREATOR.createFromParcel(in);
-        mDeclaredLibraries = in.createTypedArrayList(SharedLibraryInfo.CREATOR);
-        mExtensionParams = in.readPersistableBundle(getClass().getClassLoader());
-        mVerificationPolicy = in.readInt();
-        mSession = IVerificationSessionInterface.Stub.asInterface(in.readStrongBinder());
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mId);
-        dest.writeInt(mInstallSessionId);
-        dest.writeString8(mPackageName);
-        Uri.writeToParcel(dest, mStagedPackageUri);
-        mSigningInfo.writeToParcel(dest, flags);
-        dest.writeTypedList(mDeclaredLibraries);
-        dest.writePersistableBundle(mExtensionParams);
-        dest.writeInt(mVerificationPolicy);
-        dest.writeStrongBinder(mSession.asBinder());
-    }
-
-    @NonNull
-    public static final Creator<VerificationSession> CREATOR = new Creator<>() {
-        @Override
-        public VerificationSession createFromParcel(@NonNull Parcel in) {
-            return new VerificationSession(in);
-        }
-
-        @Override
-        public VerificationSession[] newArray(int size) {
-            return new VerificationSession[size];
-        }
-    };
-}
diff --git a/core/java/android/content/pm/verify/pkg/VerificationStatus.aidl b/core/java/android/content/pm/verify/pkg/VerificationStatus.aidl
deleted file mode 100644
index 6a1cb4f..0000000
--- a/core/java/android/content/pm/verify/pkg/VerificationStatus.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-/** @hide */
-parcelable VerificationStatus;
diff --git a/core/java/android/content/pm/verify/pkg/VerificationStatus.java b/core/java/android/content/pm/verify/pkg/VerificationStatus.java
deleted file mode 100644
index 4d0379d7..0000000
--- a/core/java/android/content/pm/verify/pkg/VerificationStatus.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.content.pm.Flags;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class is used by the verifier to describe the status of the verification request, whether
- * it's successful or it has failed along with any relevant details.
- * @hide
- */
-@SystemApi
-@FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-public final class  VerificationStatus implements Parcelable {
-    /**
-     * The ASL status has not been determined.  This happens in situations where the verification
-     * service is not monitoring ASLs, and means the ASL data in the app is not necessarily bad but
-     * can't be trusted.
-     */
-    public static final int VERIFIER_STATUS_ASL_UNDEFINED = 0;
-
-    /**
-     * The app's ASL data is considered to be in a good state.
-     */
-    public static final int VERIFIER_STATUS_ASL_GOOD = 1;
-
-    /**
-     * There is something bad in the app's ASL data; the user should be warned about this when shown
-     * the ASL data and/or appropriate decisions made about the use of this data by the platform.
-     */
-    public static final int VERIFIER_STATUS_ASL_BAD = 2;
-
-    /** @hide */
-    @IntDef(prefix = {"VERIFIER_STATUS_ASL_"}, value = {
-            VERIFIER_STATUS_ASL_UNDEFINED,
-            VERIFIER_STATUS_ASL_GOOD,
-            VERIFIER_STATUS_ASL_BAD,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface VerifierStatusAsl {}
-
-    private boolean mIsVerified;
-    private @VerifierStatusAsl int mAslStatus;
-    @NonNull
-    private String mFailuresMessage = "";
-
-    private VerificationStatus() {}
-
-    /**
-     * @return whether the status is set to verified or not.
-     */
-    public boolean isVerified() {
-        return mIsVerified;
-    }
-
-    /**
-     * @return the failure message associated with the failure status.
-     */
-    @NonNull
-    public String getFailureMessage() {
-        return mFailuresMessage;
-    }
-
-    /**
-     * @return the asl status.
-     */
-    public @VerifierStatusAsl int getAslStatus() {
-        return mAslStatus;
-    }
-
-    /**
-     * Builder to construct a {@link VerificationStatus} object.
-     */
-    public static final class Builder {
-        final VerificationStatus mStatus = new VerificationStatus();
-
-        /**
-         * Set in the status whether the verification has succeeded or failed.
-         */
-        @NonNull
-        public Builder setVerified(boolean verified) {
-            mStatus.mIsVerified = verified;
-            return this;
-        }
-
-        /**
-         * Set a developer-facing failure message to include in the verification failure status.
-         */
-        @NonNull
-        public Builder setFailureMessage(@NonNull String failureMessage) {
-            mStatus.mFailuresMessage = failureMessage;
-            return this;
-        }
-
-        /**
-         * Set the ASL status, as defined in {@link VerifierStatusAsl}.
-         */
-        @NonNull
-        public Builder setAslStatus(@VerifierStatusAsl int aslStatus) {
-            mStatus.mAslStatus = aslStatus;
-            return this;
-        }
-
-        /**
-         * Build the status object.
-         */
-        @NonNull
-        public VerificationStatus build() {
-            return mStatus;
-        }
-    }
-
-    private VerificationStatus(Parcel in) {
-        mIsVerified = in.readBoolean();
-        mAslStatus = in.readInt();
-        mFailuresMessage = in.readString8();
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeBoolean(mIsVerified);
-        dest.writeInt(mAslStatus);
-        dest.writeString8(mFailuresMessage);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @NonNull
-    public static final Creator<VerificationStatus> CREATOR = new Creator<>() {
-        @Override
-        public VerificationStatus createFromParcel(@NonNull Parcel in) {
-            return new VerificationStatus(in);
-        }
-
-        @Override
-        public VerificationStatus[] newArray(int size) {
-            return new VerificationStatus[size];
-        }
-    };
-}
diff --git a/core/java/android/content/pm/verify/pkg/VerifierService.java b/core/java/android/content/pm/verify/pkg/VerifierService.java
deleted file mode 100644
index ccf2119..0000000
--- a/core/java/android/content/pm/verify/pkg/VerifierService.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.Flags;
-import android.content.pm.PackageManager;
-import android.os.IBinder;
-
-/**
- * A base service implementation for the verifier agent to implement.
- *
- * @hide
- */
-@SystemApi
-@FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-public abstract class VerifierService extends Service {
-    /**
-     * Called when a package name is available for a pending verification,
-     * giving the verifier opportunity to pre-fetch any relevant information
-     * that may be needed should a verification for the package be required.
-     */
-    public abstract void onPackageNameAvailable(@NonNull String packageName);
-
-    /**
-     * Called when a package recently provided via {@link #onPackageNameAvailable}
-     * is no longer expected to be installed. This is a hint that any pre-fetch or
-     * cache created as a result of the previous call may be be cleared.
-     * <p>This method will never be called after {@link #onVerificationRequired} is called for the
-     * same package. Once a verification is officially requested by
-     * {@link #onVerificationRequired}, it cannot be cancelled.
-     * </p>
-     */
-    public abstract void onVerificationCancelled(@NonNull String packageName);
-
-    /**
-     * Called when an application needs to be verified. Details about the
-     * verification and actions that can be taken on it will be encapsulated in
-     * the provided {@link VerificationSession} parameter.
-     */
-    public abstract void onVerificationRequired(@NonNull VerificationSession session);
-
-    /**
-     * Called when a verification needs to be retried. This can be encountered
-     * when a prior verification was marked incomplete and the user has indicated
-     * that they've resolved the issue, or when a timeout is reached, but the
-     * the system is attempting to retry. Details about the
-     * verification and actions that can be taken on it will be encapsulated in
-     * the provided {@link VerificationSession} parameter.
-     */
-    public abstract void onVerificationRetry(@NonNull VerificationSession session);
-
-    /**
-     * Called in the case that an active verification has failed. Any APIs called
-     * on the {@link VerificationSession} instance associated with this {@code verificationId} will
-     * throw an {@link IllegalStateException}.
-     */
-    public abstract void onVerificationTimeout(int verificationId);
-
-    /**
-     * Called when the verifier service is bound to the system.
-     */
-    public @Nullable IBinder onBind(@Nullable Intent intent) {
-        if (intent == null || !PackageManager.ACTION_VERIFY_PACKAGE.equals(intent.getAction())) {
-            return null;
-        }
-        return new IVerifierService.Stub() {
-            @Override
-            public void onPackageNameAvailable(@NonNull String packageName) {
-                VerifierService.this.onPackageNameAvailable(packageName);
-            }
-
-            @Override
-            public void onVerificationCancelled(@NonNull String packageName) {
-                VerifierService.this.onVerificationCancelled(packageName);
-            }
-
-            @Override
-            public void onVerificationRequired(@NonNull VerificationSession session) {
-                VerifierService.this.onVerificationRequired(session);
-            }
-
-            @Override
-            public void onVerificationRetry(@NonNull VerificationSession session) {
-                VerifierService.this.onVerificationRetry(session);
-            }
-
-            @Override
-            public void onVerificationTimeout(int verificationId) {
-                VerifierService.this.onVerificationTimeout(verificationId);
-            }
-        };
-    }
-}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 4551bd5..bbfae81 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -75,7 +75,10 @@
     private static final String TAG = "AssetManager";
     private static final boolean DEBUG_REFS = false;
 
-    private static final String FRAMEWORK_APK_PATH = getFrameworkApkPath();
+    /**
+     * @hide
+     */
+    public static final String FRAMEWORK_APK_PATH = getFrameworkApkPath();
     private static final String FRAMEWORK_APK_PATH_DEVICE = "/system/framework/framework-res.apk";
     private static final String FRAMEWORK_APK_PATH_RAVENWOOD = "ravenwood-data/framework-res.apk";
 
diff --git a/core/java/android/content/res/loader/ResourcesProvider.java b/core/java/android/content/res/loader/ResourcesProvider.java
index b097bc0..830b7e0 100644
--- a/core/java/android/content/res/loader/ResourcesProvider.java
+++ b/core/java/android/content/res/loader/ResourcesProvider.java
@@ -90,8 +90,6 @@
             throws IOException {
         Objects.requireNonNull(overlayInfo);
         Preconditions.checkArgument(overlayInfo.isFabricated(), "Not accepted overlay");
-        Preconditions.checkStringNotEmpty(
-                overlayInfo.getTargetOverlayableName(), "Without overlayable name");
         final String overlayName =
                 OverlayManagerImpl.checkOverlayNameValid(overlayInfo.getOverlayName());
         final String path =
diff --git a/core/java/android/hardware/DisplayLuts.java b/core/java/android/hardware/DisplayLuts.java
index 6343ba1..0abb30f 100644
--- a/core/java/android/hardware/DisplayLuts.java
+++ b/core/java/android/hardware/DisplayLuts.java
@@ -177,6 +177,8 @@
                     return "SAMPLING_KEY_RGB";
                 case LutProperties.SAMPLING_KEY_MAX_RGB:
                     return "SAMPLING_KEY_MAX_RGB";
+                case LutProperties.SAMPLING_KEY_CIE_Y:
+                    return "SAMPLING_KEY_CIE_Y";
                 default:
                     return "";
             }
diff --git a/core/java/android/hardware/LutProperties.java b/core/java/android/hardware/LutProperties.java
index bf40a41..abb303a 100644
--- a/core/java/android/hardware/LutProperties.java
+++ b/core/java/android/hardware/LutProperties.java
@@ -44,7 +44,8 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"SAMPLING_KEY_"}, value = {
         SAMPLING_KEY_RGB,
-        SAMPLING_KEY_MAX_RGB
+        SAMPLING_KEY_MAX_RGB,
+        SAMPLING_KEY_CIE_Y
     })
     public @interface SamplingKey {
     }
@@ -57,6 +58,10 @@
     @FlaggedApi(Flags.FLAG_LUTS_API)
     public static final int SAMPLING_KEY_MAX_RGB = 1;
 
+    /** use y of CIE XYZ as the gain value of a lut */
+    @FlaggedApi(Flags.FLAG_LUTS_API)
+    public static final int SAMPLING_KEY_CIE_Y = 2;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(value = {
diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
index 3cf508a..58fe477 100644
--- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
@@ -1066,6 +1066,7 @@
                     case ImageFormat.YUV_420_888:
                     case ImageFormat.JPEG:
                     case ImageFormat.JPEG_R:
+                    case ImageFormat.DEPTH_JPEG:
                     case ImageFormat.YCBCR_P010:
                         break;
                     default:
@@ -1096,9 +1097,10 @@
                     // processed YUV_420 buffers.
                     return getSupportedSizes(
                             extenders.second.getSupportedPostviewResolutions(sz), format);
-                }  else if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010) {
-                    // Jpeg_R/UltraHDR + YCBCR_P010 is currently not supported in the basic
-                    // extension case
+                }  else if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010 ||
+                        (Flags.depthJpegExtensions() && (format == ImageFormat.DEPTH_JPEG))) {
+                    // DepthJpeg/Jpeg_R/UltraHDR + YCBCR_P010 is currently not supported in the
+                    // basic extension case
                     return new ArrayList<>();
                 } else {
                     throw new IllegalArgumentException("Unsupported format: " + format);
@@ -1194,8 +1196,8 @@
      *
      * <p>Device-specific extensions currently support at most three
      * multi-frame capture surface formats. ImageFormat.JPEG will be supported by all
-     * extensions while ImageFormat.YUV_420_888, ImageFormat.JPEG_R, or ImageFormat.YCBCR_P010
-     * may or may not be supported.</p>
+     * extensions while ImageFormat.YUV_420_888, ImageFormat.JPEG_R, ImageFormat.YCBCR_P010 or
+     * ImageFormat.DEPTH_JPEG may or may not be supported.</p>
      *
      * @param extension the extension type
      * @param format    device-specific extension output format
@@ -1203,7 +1205,8 @@
      * supported.
      * @throws IllegalArgumentException in case of format different from ImageFormat.JPEG,
      *                                  ImageFormat.YUV_420_888, ImageFormat.JPEG_R,
-     *                                  ImageFormat.YCBCR_P010; or unsupported extension.
+     *                                  ImageFormat.DEPTH_JPEG, ImageFormat.YCBCR_P010; or
+     *                                  unsupported extension.
      */
     public @NonNull
     List<Size> getExtensionSupportedSizes(@Extension int extension, int format) {
@@ -1227,6 +1230,7 @@
                         case ImageFormat.YUV_420_888:
                         case ImageFormat.JPEG:
                         case ImageFormat.JPEG_R:
+                        case ImageFormat.DEPTH_JPEG:
                         case ImageFormat.YCBCR_P010:
                             break;
                         default:
@@ -1260,8 +1264,9 @@
                         } else {
                             return generateSupportedSizes(null, format, streamMap);
                         }
-                    } else if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010) {
-                        // Jpeg_R/UltraHDR + YCBCR_P010 is currently not supported in the
+                    } else if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010 ||
+                            (Flags.depthJpegExtensions() && (format == ImageFormat.DEPTH_JPEG))) {
+                        // DepthJpeg/Jpeg_R/UltraHDR + YCBCR_P010 is currently not supported in the
                         // basic extension case
                         return new ArrayList<>();
                     } else {
@@ -1292,7 +1297,8 @@
      * or null if no capture latency info can be provided
      * @throws IllegalArgumentException in case of format different from {@link ImageFormat#JPEG},
      *                                  {@link ImageFormat#YUV_420_888}, {@link ImageFormat#JPEG_R}
-     *                                  {@link ImageFormat#YCBCR_P010};
+     *                                  {@link ImageFormat#YCBCR_P010},
+     *                                  {@link ImageFormat#DEPTH_JPEG};
      *                                  or unsupported extension.
      */
     public @Nullable Range<Long> getEstimatedCaptureLatencyRangeMillis(@Extension int extension,
@@ -1301,6 +1307,7 @@
             case ImageFormat.YUV_420_888:
             case ImageFormat.JPEG:
             case ImageFormat.JPEG_R:
+            case ImageFormat.DEPTH_JPEG:
             case ImageFormat.YCBCR_P010:
                 //No op
                 break;
@@ -1349,8 +1356,9 @@
                     // specific and cannot be estimated accurately enough.
                     return  null;
                 }
-                if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010) {
-                    // JpegR/UltraHDR + YCBCR_P010 is not supported for basic extensions
+                if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010 ||
+                        (Flags.depthJpegExtensions() && (format == ImageFormat.DEPTH_JPEG))) {
+                    // DepthJpeg/JpegR/UltraHDR + YCBCR_P010 is not supported for basic extensions
                     return null;
                 }
 
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index fc03b51..d511e9f 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -186,12 +186,12 @@
 
         HashMap<Integer, List<Size>> supportedCaptureSizes = new HashMap<>();
 
-        IntArray supportedCaptureOutputFormats =
-                new IntArray(CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.length);
-        supportedCaptureOutputFormats.addAll(
-                CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS);
-        supportedCaptureOutputFormats.add(ImageFormat.YCBCR_P010);
-        for (int format : supportedCaptureOutputFormats.toArray()) {
+        Integer[] supportedCaptureOutputFormats =
+                new Integer[CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.size()];
+        supportedCaptureOutputFormats =
+                CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.toArray(
+                        supportedCaptureOutputFormats);
+        for (int format : supportedCaptureOutputFormats) {
             List<Size> supportedSizes = extensionChars.getExtensionSupportedSizes(
                     config.getExtension(), format);
             if (supportedSizes != null) {
@@ -230,7 +230,7 @@
             Size burstCaptureSurfaceSize =
                     new Size(burstCaptureSurfaceInfo.mWidth, burstCaptureSurfaceInfo.mHeight);
             HashMap<Integer, List<Size>> supportedPostviewSizes = new HashMap<>();
-            for (int format : supportedCaptureOutputFormats.toArray()) {
+            for (int format : supportedCaptureOutputFormats) {
                 List<Size> supportedSizesPostview = extensionChars.getPostviewSupportedSizes(
                         config.getExtension(), burstCaptureSurfaceSize, format);
                 if (supportedSizesPostview != null) {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index ce1609d..ed73e62 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -186,12 +186,12 @@
         }
 
         HashMap<Integer, List<Size>> supportedCaptureSizes = new HashMap<>();
-        IntArray supportedCaptureOutputFormats =
-                new IntArray(CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.length);
-        supportedCaptureOutputFormats.addAll(
-                CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS);
-        supportedCaptureOutputFormats.add(ImageFormat.YCBCR_P010);
-        for (int format : supportedCaptureOutputFormats.toArray()) {
+        Integer[] supportedCaptureOutputFormats =
+                new Integer[CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.size()];
+        supportedCaptureOutputFormats =
+                CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.toArray(
+                        supportedCaptureOutputFormats);
+        for (int format : supportedCaptureOutputFormats) {
             List<Size> supportedSizes = extensionChars.getExtensionSupportedSizes(
                     config.getExtension(), format);
             if (supportedSizes != null) {
@@ -223,7 +223,7 @@
             Size burstCaptureSurfaceSize =
                     new Size(burstCaptureSurfaceInfo.mWidth, burstCaptureSurfaceInfo.mHeight);
             HashMap<Integer, List<Size>> supportedPostviewSizes = new HashMap<>();
-            for (int format : supportedCaptureOutputFormats.toArray()) {
+            for (int format : supportedCaptureOutputFormats) {
                 List<Size> supportedSizesPostview = extensionChars.getPostviewSupportedSizes(
                         config.getExtension(), burstCaptureSurfaceSize, format);
                 if (supportedSizesPostview != null) {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java b/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java
index f91d277..212c909 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java
@@ -32,11 +32,14 @@
 import android.util.IntArray;
 import android.util.Log;
 import android.util.Size;
+import android.util.SparseIntArray;
 import android.view.Surface;
 
 import com.android.internal.camera.flags.Flags;
 
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
@@ -48,11 +51,16 @@
     public final static int JPEG_DEFAULT_QUALITY = 100;
     public final static int JPEG_DEFAULT_ROTATION = 0;
 
-    public static final int[] SUPPORTED_CAPTURE_OUTPUT_FORMATS = {
-            CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT,
-            ImageFormat.JPEG,
-            ImageFormat.JPEG_R
-    };
+    public static HashSet<Integer> SUPPORTED_CAPTURE_OUTPUT_FORMATS = new HashSet<>();
+
+    static {
+        SUPPORTED_CAPTURE_OUTPUT_FORMATS.addAll(Arrays.asList(
+                CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT, ImageFormat.JPEG,
+                ImageFormat.YCBCR_P010, ImageFormat.JPEG_R ));
+        if (Flags.depthJpegExtensions()) {
+            SUPPORTED_CAPTURE_OUTPUT_FORMATS.add(ImageFormat.DEPTH_JPEG);
+        }
+    }
 
     public static class SurfaceInfo {
         public int mWidth = 0;
@@ -101,6 +109,13 @@
             surfaceInfo.mFormat = ImageFormat.JPEG_R;
             return surfaceInfo;
         }
+        if (Flags.depthJpegExtensions()) {
+            if ((nativeFormat == StreamConfigurationMap.HAL_PIXEL_FORMAT_BLOB)
+                    && (dataspace == StreamConfigurationMap.HAL_DATASPACE_DYNAMIC_DEPTH)) {
+                surfaceInfo.mFormat = ImageFormat.DEPTH_JPEG;
+                return surfaceInfo;
+            }
+        }
 
         return surfaceInfo;
     }
@@ -125,14 +140,14 @@
     public static Surface getBurstCaptureSurface(
             @NonNull List<OutputConfiguration> outputConfigs,
             @NonNull HashMap<Integer, List<Size>> supportedCaptureSizes) {
-        IntArray supportedCaptureOutputFormats =
-                new IntArray(CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.length);
-        supportedCaptureOutputFormats.addAll(
-                CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS);
-        supportedCaptureOutputFormats.add(ImageFormat.YCBCR_P010);
+        Integer[] supportedCaptureOutputFormats =
+                new Integer[CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.size()];
+        supportedCaptureOutputFormats =
+                CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.toArray(
+                        supportedCaptureOutputFormats);
         for (OutputConfiguration config : outputConfigs) {
             SurfaceInfo surfaceInfo = querySurface(config.getSurface());
-            for (int supportedFormat : supportedCaptureOutputFormats.toArray()) {
+            for (int supportedFormat : supportedCaptureOutputFormats) {
                 if (surfaceInfo.mFormat == supportedFormat) {
                     Size captureSize = new Size(surfaceInfo.mWidth, surfaceInfo.mHeight);
                     if (supportedCaptureSizes.containsKey(supportedFormat)) {
diff --git a/core/java/android/hardware/contexthub/HubEndpoint.java b/core/java/android/hardware/contexthub/HubEndpoint.java
index 078b4d4..7efdd6d 100644
--- a/core/java/android/hardware/contexthub/HubEndpoint.java
+++ b/core/java/android/hardware/contexthub/HubEndpoint.java
@@ -18,6 +18,7 @@
 
 import android.annotation.CallbackExecutor;
 import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -31,6 +32,8 @@
 
 import androidx.annotation.GuardedBy;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -48,6 +51,46 @@
 public class HubEndpoint {
     private static final String TAG = "HubEndpoint";
 
+    /**
+     * Constants describing the outcome of operations through HubEndpoints (like opening/closing of
+     * sessions or stopping of endpoints).
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            prefix = {"REASON_"},
+            value = {
+                REASON_FAILURE,
+                REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED,
+                REASON_CLOSE_ENDPOINT_SESSION_REQUESTED,
+                REASON_ENDPOINT_INVALID,
+                REASON_ENDPOINT_STOPPED,
+            })
+    public @interface Reason {}
+
+    /** Unclassified failure */
+    public static final int REASON_FAILURE = 0;
+
+    // The values 1 and 2 are reserved at the Context Hub HAL but not exposed to apps.
+
+    /** The peer rejected the request to open this endpoint session. */
+    public static final int REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED = 3;
+
+    /** The peer closed this endpoint session. */
+    public static final int REASON_CLOSE_ENDPOINT_SESSION_REQUESTED = 4;
+
+    /** The peer endpoint is invalid. */
+    public static final int REASON_ENDPOINT_INVALID = 5;
+
+    /**
+     * The endpoint is now stopped. The app should retrieve the endpoint info using {@link
+     * android.hardware.location.ContextHubManager#findEndpoints} or register updates through
+     * {@link android.hardware.location.ContextHubManager#registerEndpointDiscoveryCallback}
+     * to get notified if the endpoint restarts.
+     */
+    public static final int REASON_ENDPOINT_STOPPED = 6;
+
     private final Object mLock = new Object();
     private final HubEndpointInfo mPendingHubEndpointInfo;
     @Nullable private final IHubEndpointLifecycleCallback mLifecycleCallback;
@@ -173,9 +216,7 @@
 
                     try {
                         mServiceToken.closeSession(
-                                sessionId,
-                                IHubEndpointLifecycleCallback
-                                        .REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED);
+                                sessionId, REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED);
                     } catch (RemoteException e) {
                         e.rethrowFromSystemServer();
                     }
@@ -396,9 +437,7 @@
 
         try {
             // Oneway notification to system service
-            serviceToken.closeSession(
-                    session.getId(),
-                    IHubEndpointLifecycleCallback.REASON_CLOSE_ENDPOINT_SESSION_REQUESTED);
+            serviceToken.closeSession(session.getId(), REASON_CLOSE_ENDPOINT_SESSION_REQUESTED);
         } catch (RemoteException e) {
             Log.e(TAG, "closeSession: failed to close session " + session, e);
             e.rethrowFromSystemServer();
diff --git a/core/java/android/hardware/contexthub/HubServiceInfo.java b/core/java/android/hardware/contexthub/HubServiceInfo.java
index c7fe77c..a1c52fb 100644
--- a/core/java/android/hardware/contexthub/HubServiceInfo.java
+++ b/core/java/android/hardware/contexthub/HubServiceInfo.java
@@ -17,12 +17,10 @@
 
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
-import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.chre.flags.Flags;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.ParcelableHolder;
 
 import androidx.annotation.NonNull;
 
@@ -76,15 +74,12 @@
     private final int mMajorVersion;
     private final int mMinorVersion;
 
-    @NonNull private final ParcelableHolder mExtendedInfo;
-
     /** @hide */
     public HubServiceInfo(android.hardware.contexthub.Service service) {
         mServiceDescriptor = service.serviceDescriptor;
         mFormat = service.format;
         mMajorVersion = service.majorVersion;
         mMinorVersion = service.minorVersion;
-        mExtendedInfo = service.extendedInfo;
     }
 
     private HubServiceInfo(Parcel in) {
@@ -92,20 +87,17 @@
         mFormat = in.readInt();
         mMajorVersion = in.readInt();
         mMinorVersion = in.readInt();
-        mExtendedInfo = ParcelableHolder.CREATOR.createFromParcel(in);
     }
 
     public HubServiceInfo(
             @NonNull String serviceDescriptor,
             @ServiceFormat int format,
             int majorVersion,
-            int minorVersion,
-            @NonNull ParcelableHolder extendedInfo) {
+            int minorVersion) {
         mServiceDescriptor = serviceDescriptor;
         mFormat = format;
         mMajorVersion = majorVersion;
         mMinorVersion = minorVersion;
-        mExtendedInfo = extendedInfo;
     }
 
     /** Get the unique identifier of this service. See {@link Builder} for more information. */
@@ -134,17 +126,10 @@
         return mMinorVersion;
     }
 
-    /** Get the {@link ParcelableHolder} for the extended information about the service. */
-    @NonNull
-    public ParcelableHolder getExtendedInfo() {
-        return mExtendedInfo;
-    }
-
     /** Parcel implementation details */
     @Override
     public int describeContents() {
-        // Passthrough describeContents flags for mExtendedInfo because we don't have FD otherwise.
-        return mExtendedInfo.describeContents();
+        return 0;
     }
 
     /** Parcel implementation details */
@@ -154,7 +139,6 @@
         dest.writeInt(mFormat);
         dest.writeInt(mMajorVersion);
         dest.writeInt(mMinorVersion);
-        mExtendedInfo.writeToParcel(dest, flags);
     }
 
     /** Builder for a {@link HubServiceInfo} object. */
@@ -165,9 +149,6 @@
         private final int mMajorVersion;
         private final int mMinorVersion;
 
-        private final ParcelableHolder mExtendedInfo =
-                new ParcelableHolder(Parcelable.PARCELABLE_STABILITY_VINTF);
-
         /**
          * Create a builder for {@link HubServiceInfo} with a service descriptor.
          *
@@ -220,20 +201,6 @@
         }
 
         /**
-         * Set the extended information of this service.
-         *
-         * @param extendedInfo Parcelable with extended information about this service. The
-         *     parcelable needs to have at least VINTF stability. Null can be used to clear a
-         *     previously set value.
-         * @throws android.os.BadParcelableException if the parcelable cannot be used.
-         */
-        @NonNull
-        public Builder setExtendedInfo(@Nullable Parcelable extendedInfo) {
-            mExtendedInfo.setParcelable(extendedInfo);
-            return this;
-        }
-
-        /**
          * Build the {@link HubServiceInfo} object.
          *
          * @throws IllegalStateException if the Builder is missing required info.
@@ -244,7 +211,7 @@
                 throw new IllegalStateException("Major and minor version must be set.");
             }
             return new HubServiceInfo(
-                    mServiceDescriptor, mFormat, mMajorVersion, mMinorVersion, mExtendedInfo);
+                    mServiceDescriptor, mFormat, mMajorVersion, mMinorVersion);
         }
     }
 
diff --git a/core/java/android/hardware/contexthub/IContextHubEndpointDiscoveryCallback.aidl b/core/java/android/hardware/contexthub/IContextHubEndpointDiscoveryCallback.aidl
new file mode 100644
index 0000000..245be93
--- /dev/null
+++ b/core/java/android/hardware/contexthub/IContextHubEndpointDiscoveryCallback.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.contexthub;
+
+import android.hardware.contexthub.HubEndpointInfo;
+
+/**
+ * @hide
+ */
+oneway interface IContextHubEndpointDiscoveryCallback {
+    /**
+     * Called when endpoint(s) start.
+     * @param hubEndpointInfoList The list of endpoints that started.
+     */
+    void onEndpointsStarted(in HubEndpointInfo[] hubEndpointInfoList);
+
+    /**
+     * Called when endpoint(s) stopped.
+     * @param hubEndpointInfoList The list of endpoints that started.
+     * @param reason The reason why the endpoints stopped.
+     */
+    void onEndpointsStopped(in HubEndpointInfo[] hubEndpointInfoList, int reason);
+}
diff --git a/core/java/android/hardware/contexthub/IHubEndpointDiscoveryCallback.java b/core/java/android/hardware/contexthub/IHubEndpointDiscoveryCallback.java
new file mode 100644
index 0000000..a61a7eb
--- /dev/null
+++ b/core/java/android/hardware/contexthub/IHubEndpointDiscoveryCallback.java
@@ -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 android.hardware.contexthub;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.chre.flags.Flags;
+
+import java.util.List;
+
+/**
+ * Interface for listening to updates about endpoint availability.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_OFFLOAD_API)
+public interface IHubEndpointDiscoveryCallback {
+    /**
+     * Called when a list of hub endpoints have started.
+     *
+     * @param discoveryInfoList The list containing hub discovery information.
+     */
+    void onEndpointsStarted(@NonNull List<HubDiscoveryInfo> discoveryInfoList);
+
+    /**
+     * Called when a list of hub endpoints have stopped.
+     *
+     * @param discoveryInfoList The list containing hub discovery information.
+     * @param reason The reason the endpoints stopped.
+     */
+    void onEndpointsStopped(
+            @NonNull List<HubDiscoveryInfo> discoveryInfoList, @HubEndpoint.Reason int reason);
+}
diff --git a/core/java/android/hardware/contexthub/IHubEndpointLifecycleCallback.java b/core/java/android/hardware/contexthub/IHubEndpointLifecycleCallback.java
index 4688439..fe449bb 100644
--- a/core/java/android/hardware/contexthub/IHubEndpointLifecycleCallback.java
+++ b/core/java/android/hardware/contexthub/IHubEndpointLifecycleCallback.java
@@ -17,15 +17,11 @@
 package android.hardware.contexthub;
 
 import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.chre.flags.Flags;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * Interface for listening to lifecycle events of a hub endpoint.
  *
@@ -34,24 +30,6 @@
 @SystemApi
 @FlaggedApi(Flags.FLAG_OFFLOAD_API)
 public interface IHubEndpointLifecycleCallback {
-    /** Unknown reason. */
-    int REASON_UNSPECIFIED = 0;
-
-    /** The peer rejected the request to open this endpoint session. */
-    int REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED = 3;
-
-    /** The peer closed this endpoint session. */
-    int REASON_CLOSE_ENDPOINT_SESSION_REQUESTED = 4;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        REASON_UNSPECIFIED,
-        REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED,
-        REASON_CLOSE_ENDPOINT_SESSION_REQUESTED,
-    })
-    @interface EndpointLifecycleReason {}
-
     /**
      * Called when an endpoint is requesting a session be opened with another endpoint.
      *
@@ -78,5 +56,5 @@
      *     used.
      * @param reason The reason why this session was closed.
      */
-    void onSessionClosed(@NonNull HubEndpointSession session, @EndpointLifecycleReason int reason);
+    void onSessionClosed(@NonNull HubEndpointSession session, @HubEndpoint.Reason int reason);
 }
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 71b60cf..114459e 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -31,7 +31,7 @@
 import static com.android.hardware.input.Flags.touchpadThreeFingerTapShortcut;
 import static com.android.hardware.input.Flags.touchpadVisualizer;
 import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
-import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiPressGestures;
+import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiKeyGestures;
 import static com.android.input.flags.Flags.FLAG_KEYBOARD_REPEAT_KEYS;
 import static com.android.input.flags.Flags.enableInputFilterRustImpl;
 import static com.android.input.flags.Flags.keyboardRepeatKeys;
@@ -522,8 +522,11 @@
      * @hide
      */
     public static boolean useTouchpadThreeFingerTapShortcut(@NonNull Context context) {
-        // TODO(b/365063048): determine whether to enable the shortcut based on the settings.
-        return isTouchpadThreeFingerTapShortcutFeatureFlagEnabled();
+        int customizedShortcut = Settings.System.getIntForUser(context.getContentResolver(),
+                Settings.System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION,
+                KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED, UserHandle.USER_CURRENT);
+        return customizedShortcut != KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED
+                && isTouchpadThreeFingerTapShortcutFeatureFlagEnabled();
     }
 
     /**
@@ -1155,6 +1158,6 @@
      * @hide
      */
     public static boolean doesKeyGestureEventHandlerSupportMultiKeyGestures() {
-        return useKeyGestureEventHandler() && useKeyGestureEventHandlerMultiPressGestures();
+        return useKeyGestureEventHandler() && useKeyGestureEventHandlerMultiKeyGestures();
     }
 }
diff --git a/core/java/android/hardware/input/KeyGlyphMap.java b/core/java/android/hardware/input/KeyGlyphMap.java
index f82d1cf..de5df91 100644
--- a/core/java/android/hardware/input/KeyGlyphMap.java
+++ b/core/java/android/hardware/input/KeyGlyphMap.java
@@ -133,6 +133,14 @@
             }
         };
 
+        public int getModifierState() {
+            return mModifierState;
+        }
+
+        public int getKeycode() {
+            return mKeycode;
+        }
+
         @Override
         public int describeContents() {
             return 0;
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index fee0749..0c89059 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -88,6 +88,17 @@
 }
 
 flag {
+    name: "input_manager_lifecycle_support"
+    namespace: "input"
+    description: "Add support for Lifecycle support in input manager"
+    bug: "362473586"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     namespace: "input_native"
     name: "manage_key_gestures"
     description: "Manage key gestures through Input APIs"
@@ -103,8 +114,8 @@
 }
 
 flag {
-    namespace: "input_native"
-    name: "use_key_gesture_event_handler_multi_press_gestures"
+    namespace: "input"
+    name: "use_key_gesture_event_handler_multi_key_gestures"
     description: "Use KeyGestureEvent handler APIs to control multi key press gestures"
     bug: "358569822"
 }
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 426cd69f..117d8fe 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -38,6 +38,8 @@
 import android.hardware.contexthub.HubEndpoint;
 import android.hardware.contexthub.HubEndpointInfo;
 import android.hardware.contexthub.HubServiceInfo;
+import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback;
+import android.hardware.contexthub.IHubEndpointDiscoveryCallback;
 import android.hardware.contexthub.IHubEndpointLifecycleCallback;
 import android.os.Handler;
 import android.os.HandlerExecutor;
@@ -49,7 +51,9 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 
 /**
@@ -202,6 +206,10 @@
     private Callback mCallback;
     private Handler mCallbackHandler;
 
+    /** A map of endpoint discovery callbacks currently registered */
+    private Map<IHubEndpointDiscoveryCallback, IContextHubEndpointDiscoveryCallback>
+            mDiscoveryCallbacks = new ConcurrentHashMap<>();
+
     /**
      * @deprecated Use {@code mCallback} instead.
      */
@@ -694,8 +702,6 @@
     @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @NonNull
     public List<HubDiscoveryInfo> findEndpoints(long endpointId) {
-        // TODO(b/379323274): Consider improving these getters to avoid racing with nano app load
-        //  timing.
         try {
             List<HubEndpointInfo> endpointInfos = mService.findEndpoints(endpointId);
             List<HubDiscoveryInfo> results = new ArrayList<>(endpointInfos.size());
@@ -720,8 +726,6 @@
     @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @NonNull
     public List<HubDiscoveryInfo> findEndpoints(@NonNull String serviceDescriptor) {
-        // TODO(b/379323274): Consider improving these getters to avoid racing with nano app load
-        //  timing.
         if (serviceDescriptor.isBlank()) {
             throw new IllegalArgumentException("Invalid service descriptor: " + serviceDescriptor);
         }
@@ -744,6 +748,188 @@
     }
 
     /**
+     * Creates an interface to invoke endpoint discovery callbacks to send down to the service.
+     *
+     * @param callback the callback to invoke at the client process
+     * @param executor the executor to invoke callbacks for this client
+     * @return the callback interface
+     */
+    private IContextHubEndpointDiscoveryCallback createDiscoveryCallback(
+            IHubEndpointDiscoveryCallback callback,
+            Executor executor,
+            @Nullable String serviceDescriptor) {
+        return new IContextHubEndpointDiscoveryCallback.Stub() {
+            @Override
+            public void onEndpointsStarted(HubEndpointInfo[] hubEndpointInfoList) {
+                if (hubEndpointInfoList.length == 0) {
+                    Log.w(TAG, "onEndpointsStarted: received empty discovery list");
+                    return;
+                }
+                executor.execute(
+                        () -> {
+                            // TODO(b/380293951): Refactor
+                            List<HubDiscoveryInfo> discoveryList =
+                                    new ArrayList<>(hubEndpointInfoList.length);
+                            for (HubEndpointInfo info : hubEndpointInfoList) {
+                                if (serviceDescriptor != null) {
+                                    for (HubServiceInfo sInfo : info.getServiceInfoCollection()) {
+                                        if (sInfo.getServiceDescriptor()
+                                                .equals(serviceDescriptor)) {
+                                            discoveryList.add(new HubDiscoveryInfo(info, sInfo));
+                                        }
+                                    }
+                                } else {
+                                    discoveryList.add(new HubDiscoveryInfo(info));
+                                }
+                            }
+                            if (discoveryList.isEmpty()) {
+                                Log.w(TAG, "onEndpointsStarted: no matching service descriptor");
+                            } else {
+                                callback.onEndpointsStarted(discoveryList);
+                            }
+                        });
+            }
+
+            @Override
+            public void onEndpointsStopped(HubEndpointInfo[] hubEndpointInfoList, int reason) {
+                if (hubEndpointInfoList.length == 0) {
+                    Log.w(TAG, "onEndpointsStopped: received empty discovery list");
+                    return;
+                }
+                executor.execute(
+                        () -> {
+                            List<HubDiscoveryInfo> discoveryList =
+                                    new ArrayList<>(hubEndpointInfoList.length);
+                            for (HubEndpointInfo info : hubEndpointInfoList) {
+                                if (serviceDescriptor != null) {
+                                    for (HubServiceInfo sInfo : info.getServiceInfoCollection()) {
+                                        if (sInfo.getServiceDescriptor()
+                                                .equals(serviceDescriptor)) {
+                                            discoveryList.add(new HubDiscoveryInfo(info, sInfo));
+                                        }
+                                    }
+                                } else {
+                                    discoveryList.add(new HubDiscoveryInfo(info));
+                                }
+                            }
+                            if (discoveryList.isEmpty()) {
+                                Log.w(TAG, "onEndpointsStopped: no matching service descriptor");
+                            } else {
+                                callback.onEndpointsStopped(discoveryList, reason);
+                            }
+                        });
+            }
+        };
+    }
+
+    /**
+     * Equivalent to {@link #registerEndpointDiscoveryCallback(long, IHubEndpointDiscoveryCallback,
+     * Executor)} with the default executor in the main thread.
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+    @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+    public void registerEndpointDiscoveryCallback(
+            long endpointId, @NonNull IHubEndpointDiscoveryCallback callback) {
+        registerEndpointDiscoveryCallback(
+                endpointId, callback, new HandlerExecutor(Handler.getMain()));
+    }
+
+    /**
+     * Registers a callback to be notified when the hub endpoint with the corresponding endpoint ID
+     * has started or stopped.
+     *
+     * @param endpointId The identifier of the hub endpoint.
+     * @param callback The callback to be invoked.
+     * @param executor The executor to invoke the callback on.
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+    @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+    public void registerEndpointDiscoveryCallback(
+            long endpointId,
+            @NonNull IHubEndpointDiscoveryCallback callback,
+            @NonNull Executor executor) {
+        Objects.requireNonNull(callback, "callback cannot be null");
+        Objects.requireNonNull(executor, "executor cannot be null");
+        IContextHubEndpointDiscoveryCallback iCallback =
+                createDiscoveryCallback(callback, executor, null);
+        try {
+            mService.registerEndpointDiscoveryCallbackId(endpointId, iCallback);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        mDiscoveryCallbacks.put(callback, iCallback);
+    }
+
+    /**
+     * Equivalent to {@link #registerEndpointDiscoveryCallback(String,
+     * IHubEndpointDiscoveryCallback, Executor)} with the default executor in the main thread.
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+    @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+    public void registerEndpointDiscoveryCallback(
+            @NonNull String serviceDescriptor, @NonNull IHubEndpointDiscoveryCallback callback) {
+        registerEndpointDiscoveryCallback(
+                serviceDescriptor, callback, new HandlerExecutor(Handler.getMain()));
+    }
+
+    /**
+     * Registers a callback to be notified when the hub endpoint with the corresponding service
+     * descriptor has started or stopped.
+     *
+     * @param serviceDescriptor The service descriptor of the hub endpoint.
+     * @param callback The callback to be invoked.
+     * @param executor The executor to invoke the callback on.
+     * @throws IllegalArgumentException if the serviceDescriptor is empty.
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+    @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+    public void registerEndpointDiscoveryCallback(
+            @NonNull String serviceDescriptor,
+            @NonNull IHubEndpointDiscoveryCallback callback,
+            @NonNull Executor executor) {
+        Objects.requireNonNull(serviceDescriptor, "serviceDescriptor cannot be null");
+        Objects.requireNonNull(callback, "callback cannot be null");
+        Objects.requireNonNull(executor, "executor cannot be null");
+        if (serviceDescriptor.isBlank()) {
+            throw new IllegalArgumentException("Invalid service descriptor: " + serviceDescriptor);
+        }
+
+        IContextHubEndpointDiscoveryCallback iCallback =
+                createDiscoveryCallback(callback, executor, serviceDescriptor);
+        try {
+            mService.registerEndpointDiscoveryCallbackDescriptor(serviceDescriptor, iCallback);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        mDiscoveryCallbacks.put(callback, iCallback);
+    }
+
+    /**
+     * Unregisters a previously registered endpoint discovery callback.
+     *
+     * @param callback The callback previously registered.
+     * @throws IllegalArgumentException If the callback was not previously registered.
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+    @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+    public void unregisterEndpointDiscoveryCallback(
+            @NonNull IHubEndpointDiscoveryCallback callback) {
+        Objects.requireNonNull(callback, "callback cannot be null");
+        IContextHubEndpointDiscoveryCallback iCallback = mDiscoveryCallbacks.remove(callback);
+        if (iCallback == null) {
+            throw new IllegalArgumentException("Callback not previously registered");
+        }
+
+        try {
+            mService.unregisterEndpointDiscoveryCallback(iCallback);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Set a callback to receive messages from the context hub
      *
      * @param callback Callback object
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index f9f41244..f14aadc 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -21,6 +21,7 @@
 import android.hardware.contexthub.HubEndpointInfo;
 import android.hardware.contexthub.IContextHubEndpoint;
 import android.hardware.contexthub.IContextHubEndpointCallback;
+import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback;
 import android.hardware.location.ContextHubInfo;
 import android.hardware.location.ContextHubMessage;
 import android.hardware.location.HubInfo;
@@ -137,4 +138,16 @@
     // Register an endpoint with the context hub
     @EnforcePermission("ACCESS_CONTEXT_HUB")
     IContextHubEndpoint registerEndpoint(in HubEndpointInfo pendingEndpointInfo, in IContextHubEndpointCallback callback);
+
+    // Register an endpoint discovery callback (id)
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
+    void registerEndpointDiscoveryCallbackId(long endpointId, in IContextHubEndpointDiscoveryCallback callback);
+
+    // Register an endpoint discovery callback (descriptor)
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
+    void registerEndpointDiscoveryCallbackDescriptor(String serviceDescriptor, in IContextHubEndpointDiscoveryCallback callback);
+
+    // Unregister an endpoint with the context hub
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
+    void unregisterEndpointDiscoveryCallback(in IContextHubEndpointDiscoveryCallback callback);
 }
diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java
index 4bc5bd2..26308f6 100644
--- a/core/java/android/inputmethodservice/AbstractInputMethodService.java
+++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java
@@ -16,6 +16,9 @@
 
 package android.inputmethodservice;
 
+import static android.view.inputmethod.Flags.FLAG_VERIFY_KEY_EVENT;
+
+import android.annotation.FlaggedApi;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -193,6 +196,12 @@
             }
         }
 
+        @FlaggedApi(FLAG_VERIFY_KEY_EVENT)
+        @Override
+        public boolean onShouldVerifyKeyEvent(@NonNull KeyEvent event) {
+            return AbstractInputMethodService.this.onShouldVerifyKeyEvent(event);
+        }
+
         /**
          * Take care of dispatching incoming trackball events to the appropriate
          * callbacks on the service, and tell the client when this is done.
@@ -308,6 +317,14 @@
         return false;
     }
 
+    /**
+     * @see InputMethodService#onShouldVerifyKeyEvent(KeyEvent)
+     */
+    @FlaggedApi(FLAG_VERIFY_KEY_EVENT)
+    public boolean onShouldVerifyKeyEvent(@NonNull KeyEvent event) {
+        return false;
+    }
+
     /** @hide */
     @Override
     public final int getWindowType() {
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 62b131a..9b37533 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -16,12 +16,16 @@
 
 package android.inputmethodservice;
 
+import static android.view.inputmethod.Flags.verifyKeyEvent;
+
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.graphics.Rect;
+import android.hardware.input.InputManager;
 import android.os.Bundle;
 import android.os.Looper;
 import android.os.Message;
+import android.os.SystemClock;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.InputChannel;
@@ -41,6 +45,8 @@
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.SomeArgs;
 
+import java.util.Objects;
+
 class IInputMethodSessionWrapper extends IInputMethodSession.Stub
         implements HandlerCaller.Callback {
     private static final String TAG = "InputMethodWrapper";
@@ -56,6 +62,7 @@
     private static final int DO_REMOVE_IME_SURFACE = 130;
     private static final int DO_FINISH_INPUT = 140;
     private static final int DO_INVALIDATE_INPUT = 150;
+    private final Context mContext;
 
 
     @UnsupportedAppUsage
@@ -66,6 +73,7 @@
 
     public IInputMethodSessionWrapper(Context context,
             InputMethodSession inputMethodSession, InputChannel channel) {
+        mContext = context;
         mCaller = new HandlerCaller(context, null,
                 this, true /*asyncHandler*/);
         mInputMethodSession = inputMethodSession;
@@ -233,6 +241,8 @@
     }
     private final class ImeInputEventReceiver extends InputEventReceiver
             implements InputMethodSession.EventCallback {
+        // Time after which a KeyEvent is invalid
+        private static final long KEY_EVENT_ALLOW_PERIOD_MS = 100L;
         private final SparseArray<InputEvent> mPendingEvents = new SparseArray<InputEvent>();
 
         public ImeInputEventReceiver(InputChannel inputChannel, Looper looper) {
@@ -247,10 +257,23 @@
                 return;
             }
 
+            if (event instanceof KeyEvent keyEvent && needsVerification(keyEvent)) {
+                // any KeyEvent with modifiers (e.g. Ctrl/Alt/Fn) must be verified that
+                // they originated from system.
+                InputManager im = mContext.getSystemService(InputManager.class);
+                Objects.requireNonNull(im);
+                final long age = SystemClock.uptimeMillis() - keyEvent.getEventTime();
+                if (age >= KEY_EVENT_ALLOW_PERIOD_MS && im.verifyInputEvent(keyEvent) == null) {
+                    Log.w(TAG, "Unverified or Invalid KeyEvent injected into IME. Dropping "
+                            + keyEvent);
+                    finishInputEvent(event, false /* handled */);
+                    return;
+                }
+            }
+
             final int seq = event.getSequenceNumber();
             mPendingEvents.put(seq, event);
-            if (event instanceof KeyEvent) {
-                KeyEvent keyEvent = (KeyEvent)event;
+            if (event instanceof KeyEvent keyEvent) {
                 mInputMethodSession.dispatchKeyEvent(seq, keyEvent, this);
             } else {
                 MotionEvent motionEvent = (MotionEvent)event;
@@ -271,5 +294,21 @@
                 finishInputEvent(event, handled);
             }
         }
+
+        private boolean hasKeyModifiers(KeyEvent event) {
+            if (event.hasNoModifiers()) {
+                return false;
+            }
+            return event.hasModifiers(KeyEvent.META_CTRL_ON)
+                    || event.hasModifiers(KeyEvent.META_ALT_ON)
+                    || event.hasModifiers(KeyEvent.KEYCODE_FUNCTION);
+        }
+
+        private boolean needsVerification(KeyEvent event) {
+            //TODO(b/331730488): Handle a11y events as well.
+            return verifyKeyEvent()
+                    && (hasKeyModifiers(event)
+                            || mInputMethodSession.onShouldVerifyKeyEvent(event));
+        }
     }
 }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 977c5bd..5f3c15d 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -56,6 +56,7 @@
 import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED;
 import static android.view.inputmethod.Flags.FLAG_CONNECTIONLESS_HANDWRITING;
 import static android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP_API;
+import static android.view.inputmethod.Flags.FLAG_VERIFY_KEY_EVENT;
 import static android.view.inputmethod.Flags.ctrlShiftShortcut;
 import static android.view.inputmethod.Flags.predictiveBackIme;
 
@@ -1198,6 +1199,11 @@
                     // when the stylus is not down.
                     mPrivOps.setHandwritingSurfaceNotTouchable(true);
                     break;
+                case MotionEvent.ACTION_OUTSIDE:
+                    // TODO(b/350047836): determine if there is use-case for simultaneous touch
+                    //  and stylus handwriting and we shouldn't finish for that.
+                    finishStylusHandwriting();
+                    break;
             }
         }
 
@@ -3206,6 +3212,7 @@
             Log.d(TAG, "Setting new handwriting region for stylus handwriting "
                     + handwritingRegion + " from last " + mLastHandwritingRegion);
         }
+        mPrivOps.setHandwritingTouchableRegion(handwritingRegion);
         mLastHandwritingRegion = handwritingRegion;
     }
 
@@ -3777,6 +3784,23 @@
     }
 
     /**
+     * Received by the IME before dispatch to {@link #onKeyDown(int, KeyEvent)} to let the system
+     * know if the {@link KeyEvent} needs to be verified that it originated from the system.
+     * {@link KeyEvent}s may originate from outside of the system and any sensitive keys should be
+     * marked for verification. One example of this could be using key shortcuts for switching to
+     * another IME.
+     *
+     * @param keyEvent the event that may need verification.
+     * @return {@code true} if {@link KeyEvent} should have its HMAC verified before dispatch,
+     * {@code false} otherwise.
+     */
+    @FlaggedApi(FLAG_VERIFY_KEY_EVENT)
+    @Override
+    public boolean onShouldVerifyKeyEvent(@NonNull KeyEvent keyEvent) {
+        return false;
+    }
+
+    /**
      * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
      * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
      * the event).
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
index 3219ce8..b270062 100644
--- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
+++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
@@ -789,11 +789,17 @@
         public Builder setMinUdpPort4500NatTimeoutSeconds(
                 @IntRange(from = MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS)
                         int minUdpPort4500NatTimeoutSeconds) {
-            Preconditions.checkArgument(
-                    minUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET
-                            || minUdpPort4500NatTimeoutSeconds
-                                    >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
-                    "Timeout must be at least 120s or MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET");
+            if (Flags.mainlineVcnModuleApi()) {
+                Preconditions.checkArgument(
+                        minUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET
+                                || minUdpPort4500NatTimeoutSeconds
+                                        >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
+                        "Timeout must be at least 120s or MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET");
+            } else {
+                Preconditions.checkArgument(
+                        minUdpPort4500NatTimeoutSeconds >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
+                        "Timeout must be at least 120s");
+            }
 
             mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
             return this;
diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig
index 1b2c575..b461f95 100644
--- a/core/java/android/net/vcn/flags.aconfig
+++ b/core/java/android/net/vcn/flags.aconfig
@@ -1,5 +1,5 @@
 package: "android.net.vcn"
-container: "system"
+container: "com.android.tethering"
 
 flag {
     name: "safe_mode_config"
@@ -15,14 +15,4 @@
      description: "Expose APIs from VCN for mainline migration"
      is_exported: true
      bug: "376339506"
-}
-
-flag {
-    name: "fix_config_garbage_collection"
-    namespace: "vcn"
-    description: "Handle race condition in subscription change"
-    bug: "370862489"
-    metadata {
-      purpose: PURPOSE_BUGFIX
-    }
 }
\ No newline at end of file
diff --git a/core/java/android/os/AggregateBatteryConsumer.java b/core/java/android/os/AggregateBatteryConsumer.java
index f0e12ca..f5fee4f 100644
--- a/core/java/android/os/AggregateBatteryConsumer.java
+++ b/core/java/android/os/AggregateBatteryConsumer.java
@@ -17,7 +17,6 @@
 package android.os;
 
 import android.annotation.NonNull;
-import android.util.proto.ProtoOutputStream;
 
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
@@ -100,19 +99,6 @@
         }
     }
 
-    void writePowerComponentModelProto(@NonNull ProtoOutputStream proto) {
-        for (int i = 0; i < POWER_COMPONENT_COUNT; i++) {
-            final int powerModel = getPowerModel(i);
-            if (powerModel == BatteryConsumer.POWER_MODEL_UNDEFINED) continue;
-
-            final long token = proto.start(BatteryUsageStatsAtomsProto.COMPONENT_MODELS);
-            proto.write(BatteryUsageStatsAtomsProto.PowerComponentModel.COMPONENT, i);
-            proto.write(BatteryUsageStatsAtomsProto.PowerComponentModel.POWER_MODEL,
-                    powerModelToProtoEnum(powerModel));
-            proto.end(token);
-        }
-    }
-
     /**
      * Builder for DeviceBatteryConsumer.
      */
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index 14b67f6..96ea168 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -161,18 +161,27 @@
 
     /**
      * Unspecified power model.
+     *
+     * @deprecated PowerModel is no longer supported
      */
+    @Deprecated
     public static final int POWER_MODEL_UNDEFINED = 0;
 
     /**
      * Power model that is based on average consumption rates that hardware components
      * consume in various states.
+     *
+     * @deprecated PowerModel is no longer supported
      */
+    @Deprecated
     public static final int POWER_MODEL_POWER_PROFILE = 1;
 
     /**
      * Power model that is based on energy consumption stats provided by PowerStats HAL.
+     *
+     * @deprecated PowerModel is no longer supported
      */
+    @Deprecated
     public static final int POWER_MODEL_ENERGY_CONSUMPTION = 2;
 
     /**
@@ -380,19 +389,17 @@
         public final @ScreenState int screenState;
         public final @PowerState int powerState;
 
-        final int mPowerModelColumnIndex;
         final int mPowerColumnIndex;
         final int mDurationColumnIndex;
 
         private Key(@PowerComponentId int powerComponentId, @ProcessState int processState,
-                @ScreenState int screenState, @PowerState int powerState, int powerModelColumnIndex,
+                @ScreenState int screenState, @PowerState int powerState,
                 int powerColumnIndex, int durationColumnIndex) {
             this.powerComponentId = powerComponentId;
             this.processState = processState;
             this.screenState = screenState;
             this.powerState = powerState;
 
-            mPowerModelColumnIndex = powerModelColumnIndex;
             mPowerColumnIndex = powerColumnIndex;
             mDurationColumnIndex = durationColumnIndex;
         }
@@ -577,11 +584,11 @@
      *
      * @param componentId The ID of the power component, e.g.
      *                    {@link BatteryConsumer#POWER_COMPONENT_CPU}.
+     * @deprecated PowerModel is no longer supported
      */
+    @Deprecated
     public @PowerModel int getPowerModel(@PowerComponentId int componentId) {
-        return mPowerComponents.getPowerModel(
-                mData.layout.getKeyOrThrow(componentId, PROCESS_STATE_UNSPECIFIED,
-                        SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED));
+        return POWER_MODEL_UNDEFINED;
     }
 
     /**
@@ -589,9 +596,11 @@
      *
      * @param key The key of the power component, obtained by calling {@link #getKey} or
      *            {@link #getKeys} method.
+     * @deprecated PowerModel is no longer supported
      */
+    @Deprecated
     public @PowerModel int getPowerModel(@NonNull BatteryConsumer.Key key) {
-        return mPowerComponents.getPowerModel(key);
+        return POWER_MODEL_UNDEFINED;
     }
 
     /**
@@ -657,20 +666,6 @@
     }
 
     /**
-     * Returns the name of the specified power model.  Intended for logging and debugging.
-     */
-    public static String powerModelToString(@BatteryConsumer.PowerModel int powerModel) {
-        switch (powerModel) {
-            case BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION:
-                return "energy consumption";
-            case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
-                return "power profile";
-            default:
-                return "";
-        }
-    }
-
-    /**
      * Returns the equivalent PowerModel enum for the specified power model.
      * {@see BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsage.PowerModel}
      */
@@ -857,10 +852,8 @@
 
     static class BatteryConsumerDataLayout {
         private static final Key[] KEY_ARRAY = new Key[0];
-        public static final int POWER_MODEL_NOT_INCLUDED = -1;
         public final String[] customPowerComponentNames;
         public final int customPowerComponentCount;
-        public final boolean powerModelsIncluded;
         public final boolean processStateDataIncluded;
         public final boolean screenStateDataIncluded;
         public final boolean powerStateDataIncluded;
@@ -872,11 +865,10 @@
         private SparseArray<Key[]> mPerComponentKeys;
 
         private BatteryConsumerDataLayout(int firstColumn, String[] customPowerComponentNames,
-                boolean powerModelsIncluded, boolean includeProcessStateData,
-                boolean includeScreenState, boolean includePowerState) {
+                boolean includeProcessStateData, boolean includeScreenState,
+                boolean includePowerState) {
             this.customPowerComponentNames = customPowerComponentNames;
             this.customPowerComponentCount = customPowerComponentNames.length;
-            this.powerModelsIncluded = powerModelsIncluded;
             this.processStateDataIncluded = includeProcessStateData;
             this.screenStateDataIncluded = includeScreenState;
             this.powerStateDataIncluded = includePowerState;
@@ -904,7 +896,7 @@
                         continue;
                     }
                     for (int i = 0; i < powerComponentIds.length; i++) {
-                        columnIndex = addKeys(keyList, powerModelsIncluded, includeProcessStateData,
+                        columnIndex = addKeys(keyList, includeProcessStateData,
                                 powerComponentIds[i], screenState, powerState, columnIndex);
                     }
                 }
@@ -934,13 +926,10 @@
             }
         }
 
-        private int addKeys(List<Key> keys, boolean powerModelsIncluded,
-                boolean includeProcessStateData, @PowerComponentId int componentId,
-                int screenState, int powerState, int columnIndex) {
+        private int addKeys(List<Key> keys, boolean includeProcessStateData,
+                @PowerComponentId int componentId, int screenState, int powerState,
+                int columnIndex) {
             keys.add(new Key(componentId, PROCESS_STATE_UNSPECIFIED, screenState, powerState,
-                    powerModelsIncluded
-                            ? columnIndex++
-                            : POWER_MODEL_NOT_INCLUDED,  // power model
                     columnIndex++,      // power
                     columnIndex++       // usage duration
             ));
@@ -956,9 +945,6 @@
                             continue;
                         }
                         keys.add(new Key(componentId, processState, screenState, powerState,
-                                powerModelsIncluded
-                                        ? columnIndex++
-                                        : POWER_MODEL_NOT_INCLUDED, // power model
                                 columnIndex++,      // power
                                 columnIndex++       // usage duration
                         ));
@@ -1016,7 +1002,7 @@
     }
 
     static BatteryConsumerDataLayout createBatteryConsumerDataLayout(
-            String[] customPowerComponentNames, boolean includePowerModels,
+            String[] customPowerComponentNames,
             boolean includeProcessStateData, boolean includeScreenStateData,
             boolean includePowerStateData) {
         int columnCount = BatteryConsumer.COLUMN_COUNT;
@@ -1025,8 +1011,7 @@
         columnCount = Math.max(columnCount, UserBatteryConsumer.COLUMN_COUNT);
 
         return new BatteryConsumerDataLayout(columnCount, customPowerComponentNames,
-                includePowerModels, includeProcessStateData, includeScreenStateData,
-                includePowerStateData);
+                includeProcessStateData, includeScreenStateData, includePowerStateData);
     }
 
     protected abstract static class BaseBuilder<T extends BaseBuilder<?>> {
@@ -1086,7 +1071,7 @@
         public T setConsumedPower(@PowerComponentId int componentId, double componentPower,
                 @PowerModel int powerModel) {
             mPowerComponentsBuilder.setConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED),
-                    componentPower, powerModel);
+                    componentPower);
             return (T) this;
         }
 
@@ -1095,14 +1080,14 @@
         public T addConsumedPower(@PowerComponentId int componentId, double componentPower,
                 @PowerModel int powerModel) {
             mPowerComponentsBuilder.addConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED),
-                    componentPower, powerModel);
+                    componentPower);
             return (T) this;
         }
 
         @SuppressWarnings("unchecked")
         @NonNull
         public T setConsumedPower(Key key, double componentPower, @PowerModel int powerModel) {
-            mPowerComponentsBuilder.setConsumedPower(key, componentPower, powerModel);
+            mPowerComponentsBuilder.setConsumedPower(key, componentPower);
             return (T) this;
         }
 
@@ -1110,21 +1095,14 @@
         @NonNull
         public T addConsumedPower(@PowerComponentId int componentId, double componentPower) {
             mPowerComponentsBuilder.addConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED),
-                    componentPower, POWER_MODEL_UNDEFINED);
+                    componentPower);
             return (T) this;
         }
 
         @SuppressWarnings("unchecked")
         @NonNull
         public T addConsumedPower(Key key, double componentPower) {
-            mPowerComponentsBuilder.addConsumedPower(key, componentPower, POWER_MODEL_UNDEFINED);
-            return (T) this;
-        }
-
-        @SuppressWarnings("unchecked")
-        @NonNull
-        public T addConsumedPower(Key key, double componentPower, @PowerModel int powerModel) {
-            mPowerComponentsBuilder.addConsumedPower(key, componentPower, powerModel);
+            mPowerComponentsBuilder.addConsumedPower(key, componentPower);
             return (T) this;
         }
 
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 8b267bf..b63ad5f 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -167,76 +167,90 @@
     public static final String EXTRA_CHARGING_STATUS = "android.os.extra.CHARGING_STATUS";
 
     /**
-     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
-     * Int value representing the battery's capacity level. These constants are key indicators of
-     * battery status and system capabilities, guiding power management decisions for both the
-     * system and apps:
-     * {@link #BATTERY_CAPACITY_LEVEL_UNSUPPORTED}: Feature not supported on this device.
-     * {@link #BATTERY_CAPACITY_LEVEL_UNKNOWN}: Battery status is unavailable or uninitialized.
-     * {@link #BATTERY_CAPACITY_LEVEL_CRITICAL}: Battery is critically low and the Android
-     * framework has been notified to schedule a shutdown by this value
-     * {@link #BATTERY_CAPACITY_LEVEL_LOW}: Android framework must limit background jobs to
-     * avoid impacting charging speed
-     * {@link #BATTERY_CAPACITY_LEVEL_NORMAL}: Battery level and charging rates are normal,
-     * battery temperature is within normal range and adapter power is enough to charge the
-     * battery at an acceptable rate. Android framework can run light background tasks without
-     * affecting charging performance severely.
-     * {@link #BATTERY_CAPACITY_LEVEL_HIGH}: Battery level is high, battery temperature is
-     * within normal range and adapter power is enough to charge the battery at an acceptable
-     * rate while running background loads. Android framework can run background tasks without
-     * affecting charging or battery performance.
-     * {@link #BATTERY_CAPACITY_LEVEL_FULL}: The battery is full, battery temperature is
-     * within normal range and adapter power is enough to sustain running background loads.
-     * Android framework can run background tasks without affecting the battery level or
-     * battery performance.
-     */
-
-    @FlaggedApi(FLAG_BATTERY_PART_STATUS_API)
-    public static final String EXTRA_CAPACITY_LEVEL = "android.os.extra.CAPACITY_LEVEL";
-
-    /**
-     * Battery capacity level is unsupported. @see EXTRA_CAPACITY_LEVEL
+     * Battery capacity level is unsupported.
+     *
+     * @see #EXTRA_CAPACITY_LEVEL
      */
     @FlaggedApi(FLAG_BATTERY_PART_STATUS_API)
     public static final int BATTERY_CAPACITY_LEVEL_UNSUPPORTED = -1;
 
     /**
-     * Battery capacity level is unknown. @see EXTRA_CAPACITY_LEVEL
+     * Battery capacity level is unknown.
+     *
+     * @see #EXTRA_CAPACITY_LEVEL
      */
     @FlaggedApi(FLAG_BATTERY_PART_STATUS_API)
     public static final int BATTERY_CAPACITY_LEVEL_UNKNOWN = 0;
 
     /**
-     * Battery capacity level is critical. @see EXTRA_CAPACITY_LEVEL
+     * Battery capacity level is critical. The Android framework has been notified to schedule
+     * a shutdown by this value.
+     *
+     * @see #EXTRA_CAPACITY_LEVEL
      */
     @FlaggedApi(FLAG_BATTERY_PART_STATUS_API)
     public static final int BATTERY_CAPACITY_LEVEL_CRITICAL = 1;
 
     /**
-     * Battery capacity level is low. @see EXTRA_CAPACITY_LEVEL
+     * Battery capacity level is low. The Android framework must limit background jobs to avoid
+     * impacting charging speed.
+     *
+     * @see #EXTRA_CAPACITY_LEVEL
      */
     @FlaggedApi(FLAG_BATTERY_PART_STATUS_API)
     public static final int BATTERY_CAPACITY_LEVEL_LOW = 2;
 
     /**
-     * Battery capacity level is normal. @see EXTRA_CAPACITY_LEVEL
+     * Battery capacity level is normal. Battery level and charging rates are normal, battery
+     * temperature is within the normal range, and adapter power is enough to charge the battery
+     * at an acceptable rate. The Android framework can run light background tasks without
+     * affecting charging performance severely.
+     *
+     * @see #EXTRA_CAPACITY_LEVEL
      */
     @FlaggedApi(FLAG_BATTERY_PART_STATUS_API)
     public static final int BATTERY_CAPACITY_LEVEL_NORMAL = 3;
 
     /**
-     * Battery capacity level is high. @see EXTRA_CAPACITY_LEVEL
+     * Battery capacity level is high. Battery level is high, battery temperature is within the
+     * normal range, and adapter power is enough to charge the battery at an acceptable rate
+     * while running background loads. The Android framework can run background tasks without
+     * affecting charging or battery performance.
+     *
+     * @see #EXTRA_CAPACITY_LEVEL
      */
     @FlaggedApi(FLAG_BATTERY_PART_STATUS_API)
     public static final int BATTERY_CAPACITY_LEVEL_HIGH = 4;
 
     /**
-     * Battery capacity level is full. @see EXTRA_CAPACITY_LEVEL
+     * Battery capacity level is full. The battery is full, the battery temperature is within the
+     * normal range, and adapter power is enough to sustain running background loads. The Android
+     * framework can run background tasks without affecting the battery level or battery
+     * performance.
+     *
+     * @see #EXTRA_CAPACITY_LEVEL
      */
     @FlaggedApi(FLAG_BATTERY_PART_STATUS_API)
     public static final int BATTERY_CAPACITY_LEVEL_FULL = 5;
 
     /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * Int value representing the battery's capacity level. These constants are key indicators of
+     * battery status and system capabilities, guiding power management decisions for both the
+     * system and apps.
+     *
+     * @see #BATTERY_CAPACITY_LEVEL_UNSUPPORTED
+     * @see #BATTERY_CAPACITY_LEVEL_UNKNOWN
+     * @see #BATTERY_CAPACITY_LEVEL_CRITICAL
+     * @see #BATTERY_CAPACITY_LEVEL_LOW
+     * @see #BATTERY_CAPACITY_LEVEL_NORMAL
+     * @see #BATTERY_CAPACITY_LEVEL_HIGH
+     * @see #BATTERY_CAPACITY_LEVEL_FULL
+     */
+    @FlaggedApi(FLAG_BATTERY_PART_STATUS_API)
+    public static final String EXTRA_CAPACITY_LEVEL = "android.os.extra.CAPACITY_LEVEL";
+
+    /**
      * Extra for {@link android.content.Intent#ACTION_BATTERY_LEVEL_CHANGED}:
      * Contains list of Bundles representing battery events
      * @hide
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index 72e4cef..f913fcf 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -114,7 +114,6 @@
     static final String XML_ATTR_POWER_STATE = "power_state";
     static final String XML_ATTR_POWER = "power";
     static final String XML_ATTR_DURATION = "duration";
-    static final String XML_ATTR_MODEL = "model";
     static final String XML_ATTR_BATTERY_CAPACITY = "battery_capacity";
     static final String XML_ATTR_DISCHARGE_PERCENT = "discharge_pct";
     static final String XML_ATTR_DISCHARGE_LOWER = "discharge_lower";
@@ -155,7 +154,6 @@
     private final long mBatteryTimeRemainingMs;
     private final long mChargeTimeRemainingMs;
     private final String[] mCustomPowerComponentNames;
-    private final boolean mIncludesPowerModels;
     private final boolean mIncludesProcessStateData;
     private final boolean mIncludesScreenStateData;
     private final boolean mIncludesPowerStateData;
@@ -179,7 +177,6 @@
         mBatteryTimeRemainingMs = builder.mBatteryTimeRemainingMs;
         mChargeTimeRemainingMs = builder.mChargeTimeRemainingMs;
         mCustomPowerComponentNames = builder.mCustomPowerComponentNames;
-        mIncludesPowerModels = builder.mIncludePowerModels;
         mIncludesProcessStateData = builder.mIncludesProcessStateData;
         mIncludesScreenStateData = builder.mIncludesScreenStateData;
         mIncludesPowerStateData = builder.mIncludesPowerStateData;
@@ -364,14 +361,13 @@
         mBatteryTimeRemainingMs = source.readLong();
         mChargeTimeRemainingMs = source.readLong();
         mCustomPowerComponentNames = source.readStringArray();
-        mIncludesPowerModels = source.readBoolean();
         mIncludesProcessStateData = source.readBoolean();
         mIncludesScreenStateData = source.readBoolean();
         mIncludesPowerStateData = source.readBoolean();
 
         mBatteryConsumersCursorWindow = CursorWindow.newFromParcel(source);
         mBatteryConsumerDataLayout = BatteryConsumer.createBatteryConsumerDataLayout(
-                mCustomPowerComponentNames, mIncludesPowerModels, mIncludesProcessStateData,
+                mCustomPowerComponentNames, mIncludesProcessStateData,
                 mIncludesScreenStateData, mIncludesPowerStateData);
 
         final int numRows = mBatteryConsumersCursorWindow.getNumRows();
@@ -424,7 +420,6 @@
         dest.writeLong(mBatteryTimeRemainingMs);
         dest.writeLong(mChargeTimeRemainingMs);
         dest.writeStringArray(mCustomPowerComponentNames);
-        dest.writeBoolean(mIncludesPowerModels);
         dest.writeBoolean(mIncludesProcessStateData);
         dest.writeBoolean(mIncludesScreenStateData);
         dest.writeBoolean(mIncludesPowerStateData);
@@ -506,9 +501,6 @@
                 getDischargeDurationMs());
         deviceBatteryConsumer.writeStatsProto(proto,
                 BatteryUsageStatsAtomsProto.DEVICE_BATTERY_CONSUMER);
-        if (mIncludesPowerModels) {
-            deviceBatteryConsumer.writePowerComponentModelProto(proto);
-        }
         writeUidBatteryConsumersProto(proto, maxRawSize);
     }
 
@@ -629,7 +621,7 @@
 
             printPowerComponent(pw, prefix,
                     mBatteryConsumerDataLayout.getPowerComponentName(powerComponent),
-                    devicePowerMah, appsPowerMah, BatteryConsumer.POWER_MODEL_UNDEFINED,
+                    devicePowerMah, appsPowerMah,
                     deviceConsumer.getUsageDurationMillis(powerComponent));
         }
 
@@ -716,23 +708,15 @@
             printPowerComponent(pw, prefix,
                     mBatteryConsumerDataLayout.getPowerComponentName(powerComponent),
                     devicePowerMah, appsPowerMah,
-                    mIncludesPowerModels ? deviceConsumer.getPowerModel(powerComponent)
-                            : BatteryConsumer.POWER_MODEL_UNDEFINED,
                     deviceConsumer.getUsageDurationMillis(dimensions));
         }
     }
 
     private void printPowerComponent(PrintWriter pw, String prefix, String label,
-            double devicePowerMah, double appsPowerMah, int powerModel, long durationMs) {
+            double devicePowerMah, double appsPowerMah, long durationMs) {
         StringBuilder sb = new StringBuilder();
         sb.append(prefix).append("    ").append(label).append(": ")
                 .append(BatteryStats.formatCharge(devicePowerMah));
-        if (powerModel != BatteryConsumer.POWER_MODEL_UNDEFINED
-                && powerModel != BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
-            sb.append(" [");
-            sb.append(BatteryConsumer.powerModelToString(powerModel));
-            sb.append("]");
-        }
         sb.append(" apps: ").append(BatteryStats.formatCharge(appsPowerMah));
         if (durationMs != 0) {
             sb.append(" duration: ");
@@ -828,7 +812,7 @@
                 final boolean includesPowerStateData = parser.getAttributeBoolean(null,
                         XML_ATTR_PREFIX_INCLUDES_POWER_STATE_DATA, false);
 
-                builder = new Builder(customComponentNames.toArray(new String[0]), true,
+                builder = new Builder(customComponentNames.toArray(new String[0]),
                         includesProcStateData, includesScreenStateData, includesPowerStateData, 0);
 
                 builder.setStatsStartTimestamp(
@@ -913,7 +897,6 @@
         private final CursorWindow mBatteryConsumersCursorWindow;
         @NonNull
         private final String[] mCustomPowerComponentNames;
-        private final boolean mIncludePowerModels;
         private final boolean mIncludesProcessStateData;
         private final boolean mIncludesScreenStateData;
         private final boolean mIncludesPowerStateData;
@@ -938,22 +921,21 @@
         private BatteryStatsHistory mBatteryStatsHistory;
 
         public Builder(@NonNull String[] customPowerComponentNames) {
-            this(customPowerComponentNames, false, false, false, false, 0);
+            this(customPowerComponentNames, false, false, false, 0);
         }
 
-        public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels,
+        public Builder(@NonNull String[] customPowerComponentNames,
                 boolean includeProcessStateData, boolean includeScreenStateData,
                 boolean includesPowerStateData, double minConsumedPowerThreshold) {
             mBatteryConsumersCursorWindow =
                     new CursorWindow(null, BATTERY_CONSUMER_CURSOR_WINDOW_SIZE);
             onCursorWindowAllocated(mBatteryConsumersCursorWindow);
             mBatteryConsumerDataLayout = BatteryConsumer.createBatteryConsumerDataLayout(
-                    customPowerComponentNames, includePowerModels, includeProcessStateData,
+                    customPowerComponentNames, includeProcessStateData,
                     includeScreenStateData, includesPowerStateData);
             mBatteryConsumersCursorWindow.setNumColumns(mBatteryConsumerDataLayout.columnCount);
 
             mCustomPowerComponentNames = customPowerComponentNames;
-            mIncludePowerModels = includePowerModels;
             mIncludesProcessStateData = includeProcessStateData;
             mIncludesScreenStateData = includeScreenStateData;
             mIncludesPowerStateData = includesPowerStateData;
diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java
index 6325b00..6e67578 100644
--- a/core/java/android/os/BatteryUsageStatsQuery.java
+++ b/core/java/android/os/BatteryUsageStatsQuery.java
@@ -24,6 +24,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
 
 /**
  * Query parameters for the {@link BatteryStatsManager#getBatteryUsageStats()} call.
@@ -65,12 +66,6 @@
      */
     public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY = 0x0002;
 
-    /**
-     * Indicates that identifiers of power models used for computations of power
-     * consumption should be included in the BatteryUsageStats.
-     */
-    public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS = 0x0004;
-
     public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA = 0x0008;
 
     public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS = 0x0010;
@@ -202,7 +197,24 @@
         return mAggregatedToTimestamp;
     }
 
+    @Override
+    public String toString() {
+        return "BatteryUsageStatsQuery{"
+                + "mFlags=" + Integer.toHexString(mFlags)
+                + ", mUserIds=" + Arrays.toString(mUserIds)
+                + ", mMaxStatsAgeMs=" + mMaxStatsAgeMs
+                + ", mAggregatedFromTimestamp=" + mAggregatedFromTimestamp
+                + ", mAggregatedToTimestamp=" + mAggregatedToTimestamp
+                + ", mMonotonicStartTime=" + mMonotonicStartTime
+                + ", mMonotonicEndTime=" + mMonotonicEndTime
+                + ", mMinConsumedPowerThreshold=" + mMinConsumedPowerThreshold
+                + ", mPowerComponents=" + Arrays.toString(mPowerComponents)
+                + '}';
+    }
+
     private BatteryUsageStatsQuery(Parcel in) {
+        mMonotonicStartTime = in.readLong();
+        mMonotonicEndTime = in.readLong();
         mFlags = in.readInt();
         mUserIds = new int[in.readInt()];
         in.readIntArray(mUserIds);
@@ -215,6 +227,8 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
+        dest.writeLong(mMonotonicStartTime);
+        dest.writeLong(mMonotonicEndTime);
         dest.writeInt(mFlags);
         dest.writeInt(mUserIds.length);
         dest.writeIntArray(mUserIds);
@@ -311,7 +325,10 @@
          * power monitoring data is available.
          *
          * Should only be used for testing and debugging.
+         *
+         * @deprecated PowerModel is no longer supported
          */
+        @Deprecated
         public Builder powerProfileModeledOnly() {
             mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL;
             return this;
@@ -322,9 +339,10 @@
          * of power consumption.
          *
          * Should only be used for testing and debugging.
+         * @deprecated PowerModel is no longer supported
          */
+        @Deprecated
         public Builder includePowerModels() {
-            mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS;
             return this;
         }
 
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 4c9f08d..4769681 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -19,8 +19,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.TestApi;
-import android.app.ActivityThread;
-import android.app.Instrumentation;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Process;
 import android.os.UserHandle;
@@ -88,14 +86,20 @@
     // queue for async messages when inserting a message at the tail.
     private int mAsyncMessageCount;
 
-    /*
+    /**
      * Select between two implementations of message queue. The legacy implementation is used
      * by default as it provides maximum compatibility with applications and tests that
      * reach into MessageQueue via the mMessages field. The concurrent implemmentation is used for
      * system processes and provides a higher level of concurrency and higher enqueue throughput
      * than the legacy implementation.
      */
-    private boolean mUseConcurrent;
+    private final boolean mUseConcurrent;
+
+    /**
+     * Caches process-level checks that determine `mUseConcurrent`.
+     * This is to avoid redoing checks that shouldn't change during the process's lifetime.
+     */
+    private static Boolean sIsProcessAllowedToUseConcurrent = null;
 
     @RavenwoodRedirect
     private native static long nativeInit();
@@ -112,34 +116,41 @@
     private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
 
     MessageQueue(boolean quitAllowed) {
-        // Concurrent mode modifies behavior that is observable via reflection and is commonly used
-        // by tests.
-        // For now, we limit it to system processes to avoid breaking apps and their tests.
-        mUseConcurrent = UserHandle.isCore(Process.myUid());
-        // Even then, we don't use it if instrumentation is loaded as it breaks some
-        // platform tests.
-        final Instrumentation instrumentation = getInstrumentation();
-        mUseConcurrent &= instrumentation == null || !instrumentation.isInstrumenting();
-        // We can lift this restriction in the future after we've made it possible for test authors
-        // to test Looper and MessageQueue without resorting to reflection.
+        if (sIsProcessAllowedToUseConcurrent == null) {
+            // Concurrent mode modifies behavior that is observable via reflection and is commonly
+            // used by tests.
+            // For now, we limit it to system processes to avoid breaking apps and their tests.
+            boolean useConcurrent = UserHandle.isCore(Process.myUid());
+
+            // Some platform tests run in system UIDs.
+            // Use this awful heuristic to detect them.
+            if (useConcurrent) {
+                final String processName = Process.myProcessName();
+                if (processName == null
+                        || processName.contains("test")
+                        || processName.contains("Test")) {
+                    useConcurrent = false;
+                }
+            }
+
+            // We can lift this restriction in the future after we've made it possible for test
+            // authors to test Looper and MessageQueue without resorting to reflection.
+
+            // Holdback study.
+            if (useConcurrent && Flags.messageQueueForceLegacy()) {
+                useConcurrent = false;
+            }
+
+            sIsProcessAllowedToUseConcurrent = useConcurrent;
+            mUseConcurrent = useConcurrent;
+        } else {
+            mUseConcurrent = sIsProcessAllowedToUseConcurrent;
+        }
 
         mQuitAllowed = quitAllowed;
         mPtr = nativeInit();
     }
 
-    @android.ravenwood.annotation.RavenwoodReplace(blockedBy = ActivityThread.class)
-    private static Instrumentation getInstrumentation() {
-        final ActivityThread activityThread = ActivityThread.currentActivityThread();
-        if (activityThread != null) {
-            return activityThread.getInstrumentation();
-        }
-        return null;
-    }
-
-    private static Instrumentation getInstrumentation$ravenwood() {
-        return null; // Instrumentation not supported on Ravenwood yet.
-    }
-
     @Override
     protected void finalize() throws Throwable {
         try {
diff --git a/core/java/android/os/CpuHeadroomParams.java b/core/java/android/os/CpuHeadroomParams.java
index f0d4f7d..8e78b7e 100644
--- a/core/java/android/os/CpuHeadroomParams.java
+++ b/core/java/android/os/CpuHeadroomParams.java
@@ -18,10 +18,13 @@
 
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
 import android.os.health.SystemHealthManager;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
 
 /**
  * Headroom request params used by {@link SystemHealthManager#getCpuHeadroom(CpuHeadroomParams)}.
@@ -54,6 +57,16 @@
     public static final int CPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1;
 
     /**
+     * Minimum CPU headroom calculation window size.
+     */
+    public static final int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50;
+
+    /**
+     * Maximum CPU headroom calculation window size.
+     */
+    public static final int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000;
+
+    /**
      * Sets the headroom calculation type.
      * <p>
      *
@@ -83,6 +96,63 @@
     }
 
     /**
+     * Sets the headroom calculation window size in milliseconds.
+     * <p>
+     *
+     * @param windowMillis the window size in milliseconds, ranged from
+     *                     [{@link #CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN},
+     *                     {@link #CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX}]. The smaller
+     *                     the value, the larger fluctuation in value should be expected. The
+     *                     default value can be retrieved from the
+     *                     {@link #getCalculationWindowMillis}. The device will try to use the
+     *                     closest feasible window size to this param.
+     * @throws IllegalArgumentException if the window size is not in allowed range.
+     */
+    public void setCalculationWindowMillis(
+            @IntRange(from = CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to =
+                    CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int windowMillis) {
+        if (windowMillis < CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN
+                || windowMillis > CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) {
+            throw new IllegalArgumentException("Invalid calculation window: " + windowMillis);
+        }
+        mInternal.calculationWindowMillis = windowMillis;
+    }
+
+    /**
+     * Gets the headroom calculation window size in milliseconds.
+     * <p>
+     * This will return the default value chosen by the device if not set.
+     */
+    public @IntRange(from = CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to =
+            CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) long getCalculationWindowMillis() {
+        return mInternal.calculationWindowMillis;
+    }
+
+    /**
+     * Sets the thread TIDs to track.
+     * <p>
+     * The TIDs should belong to the same of the process that will the headroom call. And they
+     * should not have different core affinity.
+     * <p>
+     * If not set, the headroom will be based on the PID of the process making the call.
+     *
+     * @param tids non-empty list of TIDs, maximum 5.
+     * @throws IllegalArgumentException if the list size is not in allowed range or TID is not
+     *                                  positive.
+     */
+    public void setTids(@NonNull int... tids) {
+        if (tids.length == 0 || tids.length > 5) {
+            throw new IllegalArgumentException("Invalid number of TIDs: " + tids.length);
+        }
+        for (int tid : tids) {
+            if (tid <= 0) {
+                throw new IllegalArgumentException("Invalid TID: " + tid);
+            }
+        }
+        mInternal.tids = Arrays.copyOf(tids, tids.length);
+    }
+
+    /**
      * @hide
      */
     public CpuHeadroomParamsInternal getInternal() {
diff --git a/core/java/android/os/CpuHeadroomParamsInternal.aidl b/core/java/android/os/CpuHeadroomParamsInternal.aidl
index 6cc4699..d572f965 100644
--- a/core/java/android/os/CpuHeadroomParamsInternal.aidl
+++ b/core/java/android/os/CpuHeadroomParamsInternal.aidl
@@ -25,6 +25,8 @@
 @JavaDerive(equals = true, toString = true)
 parcelable CpuHeadroomParamsInternal {
     boolean usesDeviceHeadroom = false;
+    int[] tids;
+    int calculationWindowMillis = 1000;
     CpuHeadroomParams.CalculationType calculationType = CpuHeadroomParams.CalculationType.MIN;
     CpuHeadroomParams.SelectionType selectionType = CpuHeadroomParams.SelectionType.ALL;
 }
diff --git a/core/java/android/os/GpuHeadroomParams.java b/core/java/android/os/GpuHeadroomParams.java
index efb2a28..4dc9826 100644
--- a/core/java/android/os/GpuHeadroomParams.java
+++ b/core/java/android/os/GpuHeadroomParams.java
@@ -18,6 +18,7 @@
 
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.os.health.SystemHealthManager;
 
 import java.lang.annotation.Retention;
@@ -54,6 +55,16 @@
     public static final int GPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1;
 
     /**
+     * Minimum GPU headroom calculation window size.
+     */
+    public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50;
+
+    /**
+     * Maximum GPU headroom calculation window size.
+     */
+    public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000;
+
+    /**
      * Sets the headroom calculation type.
      * <p>
      *
@@ -83,6 +94,39 @@
     }
 
     /**
+     * Sets the headroom calculation window size in milliseconds.
+     * <p>
+     *
+     * @param windowMillis the window size in milliseconds, ranged from
+     *                     [{@link #GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN},
+     *                     {@link #GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX}]. The smaller
+     *                     the value, the larger fluctuation in value should be expected. The
+     *                     default value can be retrieved from the
+     *                     {@link #getCalculationWindowMillis}. If the device will try to use the
+     *                     closest feasible window size to this param.
+     * @throws IllegalArgumentException if the window is invalid.
+     */
+    public void setCalculationWindowMillis(
+            @IntRange(from = GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to =
+                    GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int windowMillis) {
+        if (windowMillis < GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN
+                || windowMillis > GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) {
+            throw new IllegalArgumentException("Invalid calculation window: " + windowMillis);
+        }
+        mInternal.calculationWindowMillis = windowMillis;
+    }
+
+    /**
+     * Gets the headroom calculation window size in milliseconds.
+     * <p>
+     * This will return the default value chosen by the device if not set.
+     */
+    public @IntRange(from = GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN, to =
+            GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX) int getCalculationWindowMillis() {
+        return mInternal.calculationWindowMillis;
+    }
+
+    /**
      * @hide
      */
     public GpuHeadroomParamsInternal getInternal() {
diff --git a/core/java/android/os/GpuHeadroomParamsInternal.aidl b/core/java/android/os/GpuHeadroomParamsInternal.aidl
index 20309e7..40d5d8e 100644
--- a/core/java/android/os/GpuHeadroomParamsInternal.aidl
+++ b/core/java/android/os/GpuHeadroomParamsInternal.aidl
@@ -24,5 +24,6 @@
  */
 @JavaDerive(equals = true, toString = true)
 parcelable GpuHeadroomParamsInternal {
+    int calculationWindowMillis = 1000;
     GpuHeadroomParams.CalculationType calculationType = GpuHeadroomParams.CalculationType.MIN;
 }
diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl
index 3312055..f1936b5 100644
--- a/core/java/android/os/IHintManager.aidl
+++ b/core/java/android/os/IHintManager.aidl
@@ -20,7 +20,10 @@
 import android.os.CpuHeadroomParamsInternal;
 import android.os.GpuHeadroomParamsInternal;
 import android.os.IHintSession;
+import android.os.SessionCreationConfig;
+import android.hardware.power.CpuHeadroomResult;
 import android.hardware.power.ChannelConfig;
+import android.hardware.power.GpuHeadroomResult;
 import android.hardware.power.SessionConfig;
 import android.hardware.power.SessionTag;
 
@@ -34,8 +37,8 @@
      * Throws UnsupportedOperationException if ADPF is not supported, and IllegalStateException
      * if creation is supported but fails.
      */
-    IHintSession createHintSessionWithConfig(in IBinder token, in int[] threadIds,
-            in long durationNanos, in SessionTag tag, out SessionConfig config);
+    IHintSession createHintSessionWithConfig(in IBinder token, in SessionTag tag,
+            in SessionCreationConfig creationConfig, out SessionConfig config);
 
     /**
      * Get preferred rate limit in nanoseconds.
@@ -52,8 +55,13 @@
      */
     @nullable ChannelConfig getSessionChannel(in IBinder token);
     oneway void closeSessionChannel();
-    float[] getCpuHeadroom(in CpuHeadroomParamsInternal params);
+    @nullable CpuHeadroomResult getCpuHeadroom(in CpuHeadroomParamsInternal params);
     long getCpuHeadroomMinIntervalMillis();
-    float getGpuHeadroom(in GpuHeadroomParamsInternal params);
+    @nullable GpuHeadroomResult getGpuHeadroom(in GpuHeadroomParamsInternal params);
     long getGpuHeadroomMinIntervalMillis();
+
+    /**
+     * Get Maximum number of graphics pipeline threads allowed per-app.
+     */
+    int getMaxGraphicsPipelineThreadsCount();
 }
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index e63b664..f9789c1 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -89,6 +89,10 @@
 per-file DdmSyncStageUpdater.java = sanglardf@google.com, rpaquay@google.com
 
 # PerformanceHintManager
+per-file CpuHeadroom*.aidl = file:/ADPF_OWNERS
+per-file GpuHeadroom*.aidl = file:/ADPF_OWNERS
+per-file CpuHeadroom*.java = file:/ADPF_OWNERS
+per-file GpuHeadroom*.java = file:/ADPF_OWNERS
 per-file PerformanceHintManager.java = file:/ADPF_OWNERS
 per-file WorkDuration.java = file:/ADPF_OWNERS
 per-file IHintManager.aidl = file:/ADPF_OWNERS
diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java
index d116e07..4db1f1b 100644
--- a/core/java/android/os/PowerComponents.java
+++ b/core/java/android/os/PowerComponents.java
@@ -15,7 +15,6 @@
  */
 package android.os;
 
-import static android.os.BatteryConsumer.BatteryConsumerDataLayout.POWER_MODEL_NOT_INCLUDED;
 import static android.os.BatteryConsumer.POWER_COMPONENT_ANY;
 import static android.os.BatteryConsumer.POWER_COMPONENT_BASE;
 import static android.os.BatteryConsumer.POWER_STATE_ANY;
@@ -156,15 +155,6 @@
         return mData.layout.getPowerComponentName(componentId);
     }
 
-    @BatteryConsumer.PowerModel
-    int getPowerModel(BatteryConsumer.Key key) {
-        if (key.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) {
-            throw new IllegalStateException(
-                    "Power model IDs were not requested in the BatteryUsageStatsQuery");
-        }
-        return mData.getInt(key.mPowerModelColumnIndex);
-    }
-
     /**
      * Returns the amount of time used by the specified component, e.g. CPU, WiFi etc.
      *
@@ -378,10 +368,6 @@
             if (durationMs != 0) {
                 serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_DURATION, durationMs);
             }
-            if (mData.layout.powerModelsIncluded) {
-                serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_MODEL,
-                        getPowerModel(key));
-            }
             serializer.endTag(null, BatteryUsageStats.XML_TAG_COMPONENT);
         }
         serializer.endTag(null, BatteryUsageStats.XML_TAG_POWER_COMPONENTS);
@@ -411,7 +397,6 @@
                         int powerState = POWER_STATE_UNSPECIFIED;
                         double powerMah = 0;
                         long durationMs = 0;
-                        int model = BatteryConsumer.POWER_MODEL_UNDEFINED;
                         for (int i = 0; i < parser.getAttributeCount(); i++) {
                             switch (parser.getAttributeName(i)) {
                                 case BatteryUsageStats.XML_ATTR_ID:
@@ -432,14 +417,11 @@
                                 case BatteryUsageStats.XML_ATTR_DURATION:
                                     durationMs = parser.getAttributeLong(i);
                                     break;
-                                case BatteryUsageStats.XML_ATTR_MODEL:
-                                    model = parser.getAttributeInt(i);
-                                    break;
                             }
                         }
                         final BatteryConsumer.Key key = builder.mData.layout.getKey(componentId,
                                 processState, screenState, powerState);
-                        builder.addConsumedPower(key, powerMah, model);
+                        builder.addConsumedPower(key, powerMah);
                         builder.addUsageDurationMillis(key, durationMs);
                         break;
                     }
@@ -453,43 +435,28 @@
      * Builder for PowerComponents.
      */
     static final class Builder {
-        private static final byte POWER_MODEL_UNINITIALIZED = -1;
-
         private final BatteryConsumer.BatteryConsumerData mData;
         private final double mMinConsumedPowerThreshold;
 
         Builder(BatteryConsumer.BatteryConsumerData data, double minConsumedPowerThreshold) {
             mData = data;
             mMinConsumedPowerThreshold = minConsumedPowerThreshold;
-            for (BatteryConsumer.Key key : mData.layout.keys) {
-                if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
-                    mData.putInt(key.mPowerModelColumnIndex, POWER_MODEL_UNINITIALIZED);
-                }
-            }
         }
 
         /**
-         * @deprecated use {@link #addConsumedPower(BatteryConsumer.Key, double, int)}
+         * @deprecated use {@link #addConsumedPower(BatteryConsumer.Key, double)}
          */
         @Deprecated
         @NonNull
-        public Builder setConsumedPower(BatteryConsumer.Key key, double componentPower,
-                int powerModel) {
+        public Builder setConsumedPower(BatteryConsumer.Key key, double componentPower) {
             mData.putDouble(key.mPowerColumnIndex, componentPower);
-            if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
-                mData.putInt(key.mPowerModelColumnIndex, powerModel);
-            }
             return this;
         }
 
         @NonNull
-        public Builder addConsumedPower(BatteryConsumer.Key key, double componentPower,
-                int powerModel) {
+        public Builder addConsumedPower(BatteryConsumer.Key key, double componentPower) {
             mData.putDouble(key.mPowerColumnIndex,
                     mData.getDouble(key.mPowerColumnIndex) + componentPower);
-            if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
-                mData.putInt(key.mPowerModelColumnIndex, powerModel);
-            }
             return this;
         }
 
@@ -547,28 +514,6 @@
                             mData.getLong(key.mDurationColumnIndex)
                                     + otherData.getLong(otherKey.mDurationColumnIndex));
                 }
-                if (key.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) {
-                    continue;
-                }
-
-                boolean undefined = false;
-                if (otherKey.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) {
-                    undefined = true;
-                } else {
-                    final int powerModel = mData.getInt(key.mPowerModelColumnIndex);
-                    int otherPowerModel = otherData.getInt(otherKey.mPowerModelColumnIndex);
-                    if (powerModel == POWER_MODEL_UNINITIALIZED) {
-                        mData.putInt(key.mPowerModelColumnIndex, otherPowerModel);
-                    } else if (powerModel != otherPowerModel
-                            && otherPowerModel != POWER_MODEL_UNINITIALIZED) {
-                        undefined = true;
-                    }
-                }
-
-                if (undefined) {
-                    mData.putInt(key.mPowerModelColumnIndex,
-                            BatteryConsumer.POWER_MODEL_UNDEFINED);
-                }
             }
         }
 
@@ -594,13 +539,6 @@
         @NonNull
         public PowerComponents build() {
             for (BatteryConsumer.Key key : mData.layout.keys) {
-                if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
-                    if (mData.getInt(key.mPowerModelColumnIndex) == POWER_MODEL_UNINITIALIZED) {
-                        mData.putInt(key.mPowerModelColumnIndex,
-                                BatteryConsumer.POWER_MODEL_UNDEFINED);
-                    }
-                }
-
                 if (mMinConsumedPowerThreshold != 0) {
                     if (mData.getDouble(key.mPowerColumnIndex) < mMinConsumedPowerThreshold) {
                         mData.putDouble(key.mPowerColumnIndex, 0);
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index d5630fd..4123209 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -214,7 +214,7 @@
             if (mFrozenCalleePolicy != FROZEN_CALLEE_POLICY_UNSET) {
                 try {
                     mBinder.removeFrozenStateChangeCallback(this);
-                } catch (UnsupportedOperationException e) {
+                } catch (UnsupportedOperationException | IllegalArgumentException e) {
                     // The kernel does not support frozen notifications. Ignore the error and move
                     // on.
                 }
diff --git a/core/java/android/os/SessionCreationConfig.aidl b/core/java/android/os/SessionCreationConfig.aidl
new file mode 100644
index 0000000..cdc0ef4
--- /dev/null
+++ b/core/java/android/os/SessionCreationConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright 2024, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.hardware.power.SessionTag;
+import android.hardware.power.SessionMode;
+
+/** {@hide} */
+parcelable SessionCreationConfig {
+    /**
+     * List of tids to be included in the hint session.
+     */
+    int[] tids;
+
+    /**
+     * The initial target work duration of this hint session in nanoseconds.
+     */
+    long targetWorkDurationNanos;
+
+    /**
+     * List of the modes to be enabled upon session creation.
+     */
+    SessionMode[] modesToEnable;
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 5a53bc15..a1ede5f 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -3878,7 +3878,11 @@
             Manifest.permission.MANAGE_USERS,
             Manifest.permission.CREATE_USERS,
             Manifest.permission.QUERY_USERS})
+    @CachedProperty(api = "user_manager_user_data")
     public UserInfo getUserInfo(@UserIdInt int userId) {
+        if (android.multiuser.Flags.cacheUserInfoReadOnly()) {
+            return UserManagerCache.getUserInfo(mService::getUserInfo, userId);
+        }
         try {
             return mService.getUserInfo(userId);
         } catch (RemoteException re) {
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index f6bc389..0a0e806 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -18,6 +18,7 @@
 
 import static android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS;
 
+import android.annotation.DurationMillisLong;
 import android.annotation.FlaggedApi;
 import android.annotation.FloatRange;
 import android.annotation.IntDef;
@@ -34,6 +35,7 @@
 import android.hardware.vibrator.V1_0.EffectStrength;
 import android.hardware.vibrator.V1_3.Effect;
 import android.net.Uri;
+import android.os.vibrator.BasicPwleSegment;
 import android.os.vibrator.Flags;
 import android.os.vibrator.PrebakedSegment;
 import android.os.vibrator.PrimitiveSegment;
@@ -1713,10 +1715,13 @@
         /**
          * Add a haptic primitive to the end of the current composition.
          *
+         * <p>Similar to {@link #addPrimitive(int, float, int, int)}, but default
+         * delay type applied is {@link #DELAY_TYPE_PAUSE}.
+         *
          * @param primitiveId The primitive to add
          * @param scale The scale to apply to the intensity of the primitive.
-         * @param delay The amount of time in milliseconds to wait before playing this primitive,
-         *              starting at the time the previous element in this composition is finished.
+         * @param delay The amount of time in milliseconds to wait between the end of the last
+         *              primitive and the beginning of this one (i.e. a pause in the composition).
          * @return This {@link Composition} object to enable adding multiple elements in one chain.
          */
         @NonNull
@@ -1843,6 +1848,8 @@
      *     .build();
      * }</pre>
      *
+     * <p>The builder automatically starts all effects at 0 amplitude.
+     *
      * <p>It is crucial to ensure that the frequency range used in your effect is compatible with
      * the device's capabilities. The framework will not play any frequencies that fall partially
      * or completely outside the device's supported range. It will also not attempt to correct or
@@ -1908,7 +1915,7 @@
                         firstSegment.getEndAmplitude(),
                         initialFrequencyHz, // Update start frequency
                         firstSegment.getEndFrequencyHz(),
-                        (int) firstSegment.getDuration()));
+                        firstSegment.getDuration()));
             }
 
             return this;
@@ -1930,25 +1937,26 @@
          * transition as quickly as possible, use
          * {@link VibratorEnvelopeEffectInfo#getMinControlPointDurationMillis()}.
          *
-         * @param amplitude   The amplitude value between 0 and 1, inclusive. 0 represents the
-         *                    vibrator being off, and 1 represents the maximum achievable amplitude
-         *                    at this frequency.
-         * @param frequencyHz The frequency in Hz, must be greater than zero.
-         * @param timeMillis  The transition time in milliseconds.
+         * @param amplitude      The amplitude value between 0 and 1, inclusive. 0 represents the
+         *                       vibrator being off, and 1 represents the maximum achievable
+         *                       amplitude
+         *                       at this frequency.
+         * @param frequencyHz    The frequency in Hz, must be greater than zero.
+         * @param durationMillis The transition time in milliseconds.
          */
         @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
         @SuppressWarnings("MissingGetterMatchingBuilder") // No getters to segments once created.
         @NonNull
         public WaveformEnvelopeBuilder addControlPoint(
                 @FloatRange(from = 0, to = 1) float amplitude,
-                @FloatRange(from = 0) float frequencyHz, int timeMillis) {
+                @FloatRange(from = 0) float frequencyHz, @DurationMillisLong long durationMillis) {
 
             if (Float.isNaN(mLastFrequencyHz)) {
                 mLastFrequencyHz = frequencyHz;
             }
 
             mSegments.add(new PwleSegment(mLastAmplitude, amplitude, mLastFrequencyHz, frequencyHz,
-                    timeMillis));
+                    durationMillis));
 
             mLastAmplitude = amplitude;
             mLastFrequencyHz = frequencyHz;
@@ -1980,6 +1988,168 @@
     }
 
     /**
+     * A builder for waveform effects defined by their envelope, designed to provide a consistent
+     * haptic perception across devices with varying capabilities.
+     *
+     * <p>This builder simplifies the creation of waveform effects by automatically adapting them
+     * to different devices based on their capabilities. Effects are defined by control points
+     * specifying target vibration intensity and sharpness, along with durations to reach those
+     * targets. The vibrator will smoothly transition between these control points.
+     *
+     * <p><b>Intensity:</b> Defines the overall strength of the vibration, ranging from
+     * 0 (off) to 1 (maximum achievable strength). Higher values result in stronger
+     * vibrations. Supported intensity values guarantee sensitivity levels (SL) above
+     * 10 dB SL to ensure human perception.
+     *
+     * <p><b>Sharpness:</b> Defines the crispness of the vibration, ranging from 0 to 1.
+     * Lower values produce smoother vibrations, while higher values create a sharper,
+     * more snappy sensation. Sharpness is mapped to its equivalent frequency within
+     * the device's supported frequency range.
+     *
+     * <p>While this builder handles most of the adaptation logic, it does come with some
+     * limitations:
+     * <ul>
+     *     <li>It may not use the full range of frequencies</li>
+     *     <li>It's restricted to a frequency range that can generate output of at least 10 db
+     *     SL</li>
+     *     <li>Effects must end with a zero intensity control point. Failure to end at a zero
+     *     intensity control point will result in an {@link IllegalStateException}.</li>
+     * </ul>
+     *
+     * <p>The builder automatically starts all effects at 0 intensity.
+     *
+     * <p>To avoid these limitations and to have more control over the effects output, use
+     * {@link WaveformEnvelopeBuilder}, where direct amplitude and frequency values can be used.
+     *
+     * <p>For optimal cross-device consistency, it's recommended to limit the number of control
+     * points to a maximum of 16. However this is not mandatory, and if a pattern exceeds the
+     * maximum number of allowed control points, the framework will automatically break down the
+     * effect to ensure it plays correctly.
+     *
+     * <p>For example, the following code creates a vibration effect that ramps up the intensity
+     * from a low-pitched to a high-pitched strong vibration over 500ms and then ramps it down to
+     * 0 (off) over 100ms:
+     *
+     * <pre>{@code
+     * VibrationEffect effect = new VibrationEffect.BasicEnvelopeBuilder()
+     *     .setInitialSharpness(0.0f)
+     *     .addControlPoint(1.0f, 1.0f, 500)
+     *     .addControlPoint(0.0f, 1.0f, 100)
+     *     .build();
+     * }</pre>
+     */
+    @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+    public static final class BasicEnvelopeBuilder {
+
+        private ArrayList<BasicPwleSegment> mSegments = new ArrayList<>();
+        private float mLastIntensity = 0f;
+        private float mLastSharpness = Float.NaN;
+
+        public BasicEnvelopeBuilder() {}
+
+        /**
+         * Sets the initial sharpness for the basic envelope effect.
+         *
+         * <p>The effect will start vibrating at this sharpness when it transitions to the
+         * intensity and sharpness defined by the first control point.
+         *
+         * <p> The sharpness defines the crispness of the vibration, ranging from 0 to 1. Lower
+         * values translate to smoother vibrations, while higher values create a sharper more snappy
+         * sensation. This value is mapped to the supported frequency range of the device.
+         *
+         * @param initialSharpness The starting sharpness of the vibration in the range of [0, 1].
+         */
+        @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+        @SuppressWarnings("MissingGetterMatchingBuilder")// No getter to initial sharpness once set.
+        @NonNull
+        public BasicEnvelopeBuilder setInitialSharpness(
+                @FloatRange(from = 0, to = 1) float initialSharpness) {
+
+            if (mSegments.isEmpty()) {
+                mLastSharpness = initialSharpness;
+            } else {
+                BasicPwleSegment firstSegment = mSegments.getFirst();
+                mSegments.set(0, new BasicPwleSegment(
+                        firstSegment.getStartIntensity(),
+                        firstSegment.getEndIntensity(),
+                        initialSharpness, // Update start sharpness
+                        firstSegment.getEndSharpness(),
+                        firstSegment.getDuration()));
+            }
+
+            return this;
+        }
+
+        /**
+         * Adds a new control point to the end of this waveform envelope.
+         *
+         * <p>Intensity defines the overall strength of the vibration, ranging from 0 (off) to 1
+         * (maximum achievable strength). Higher values translate to stronger vibrations.
+         *
+         * <p>Sharpness defines the crispness of the vibration, ranging from 0 to 1. Lower
+         * values translate to smoother vibrations, while higher values create a sharper more snappy
+         * sensation. This value is mapped to the supported frequency range of the device.
+         *
+         * <p>Time specifies the duration (in milliseconds) for the vibrator to smoothly transition
+         * from the previous control point to this new one. It must be greater than zero. To
+         * transition as quickly as possible, use
+         * {@link VibratorEnvelopeEffectInfo#getMinControlPointDurationMillis()}.
+         *
+         * @param intensity      The target vibration intensity, ranging from 0 (off) to 1 (maximum
+         *                       strength).
+         * @param sharpness      The target sharpness, ranging from 0 (smoothest) to 1 (sharpest).
+         * @param durationMillis The transition time in milliseconds.
+         */
+        @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+        @SuppressWarnings("MissingGetterMatchingBuilder") // No getters to segments once created.
+        @NonNull
+        public BasicEnvelopeBuilder addControlPoint(
+                @FloatRange(from = 0, to = 1) float intensity,
+                @FloatRange(from = 0, to = 1) float sharpness,
+                @DurationMillisLong long durationMillis) {
+
+            if (Float.isNaN(mLastSharpness)) {
+                mLastSharpness = sharpness;
+            }
+
+            mSegments.add(new BasicPwleSegment(mLastIntensity, intensity, mLastSharpness, sharpness,
+                    durationMillis));
+
+            mLastIntensity = intensity;
+            mLastSharpness = sharpness;
+
+            return this;
+        }
+
+        /**
+         * Build the waveform as a single {@link VibrationEffect}.
+         *
+         * <p>The {@link BasicEnvelopeBuilder} object is still valid after this call, so you can
+         * continue adding more primitives to it and generating more {@link VibrationEffect}s by
+         * calling this method again.
+         *
+         * @return The {@link VibrationEffect} resulting from the list of control points.
+         * @throws IllegalStateException if the last control point does not end at zero intensity.
+         */
+        @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+        @NonNull
+        public VibrationEffect build() {
+            if (mSegments.isEmpty()) {
+                throw new IllegalStateException(
+                        "BasicEnvelopeBuilder must have at least one control point to build.");
+            }
+            if (mSegments.getLast().getEndIntensity() != 0) {
+                throw new IllegalStateException(
+                        "Basic envelope effects must end at a zero intensity control point.");
+            }
+            VibrationEffect effect = new Composed(mSegments, /* repeatIndex= */ -1);
+            effect.validate();
+            return effect;
+        }
+
+    }
+
+    /**
      * A builder for waveform haptic effects.
      *
      * <p>Waveform vibrations constitute of one or more timed transitions to new sets of vibration
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 2ef8764..3001fbd 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -4,6 +4,15 @@
 
 # keep-sorted start block=yes newline_separated=yes
 flag {
+     # Holdback study for concurrent MessageQueue.
+     # Do not promote beyond trunkfood.
+     namespace: "system_performance"
+     name: "message_queue_force_legacy"
+     description: "Whether to holdback concurrent MessageQueue (force legacy)."
+     bug: "336880969"
+}
+
+flag {
     name: "adpf_gpu_report_actual_work_duration"
     is_exported: true
     namespace: "game"
@@ -12,6 +21,15 @@
 }
 
 flag {
+    name: "adpf_graphics_pipeline"
+    is_exported: true
+    namespace: "game"
+    description: "Guards use of SessionCreationConfig and Graphics Pipeline mode"
+    is_fixed_read_only: true
+    bug: "367803904"
+}
+
+flag {
     name: "adpf_hwui_gpu"
     namespace: "game"
     description: "Guards use of the FMQ channel for ADPF"
@@ -213,6 +231,15 @@
 }
 
 flag {
+     name: "message_queue_testability"
+     namespace: "system_performance"
+     is_exported: true
+     description: "Whether MessageQueue implements test APIs."
+     bug: "379472827"
+     is_fixed_read_only: true
+}
+
+flag {
     name: "network_time_uses_shared_memory"
     namespace: "system_performance"
     description: "SystemClock.currentNetworkTimeMillis() reads network time offset from shared memory"
diff --git a/core/java/android/os/health/SystemHealthManager.java b/core/java/android/os/health/SystemHealthManager.java
index 4db9bc3..cd79e41 100644
--- a/core/java/android/os/health/SystemHealthManager.java
+++ b/core/java/android/os/health/SystemHealthManager.java
@@ -23,6 +23,8 @@
 import android.annotation.SystemService;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.hardware.power.CpuHeadroomResult;
+import android.hardware.power.GpuHeadroomResult;
 import android.os.BatteryStats;
 import android.os.Build;
 import android.os.Bundle;
@@ -110,15 +112,16 @@
     }
 
     /**
-     * Provides an estimate of global available CPU headroom of the calling thread.
+     * Provides an estimate of global available CPU headroom.
      * <p>
      *
      * @param  params params to customize the CPU headroom calculation, null to use default params.
-     * @return a single value a {@code Float.NaN} if it's temporarily unavailable.
+     * @return a single value headroom or a {@code Float.NaN} if it's temporarily unavailable.
      *         A valid value is ranged from [0, 100], where 0 indicates no more CPU resources can be
      *         granted.
-     * @throws UnsupportedOperationException if the API is unsupported or the request params can't
-     *         be served.
+     * @throws UnsupportedOperationException if the API is unsupported.
+     * @throws SecurityException if the TIDs of the params don't belong to the same process.
+     * @throws IllegalStateException if the TIDs of the params don't have the same affinity setting.
      */
     @FlaggedApi(android.os.Flags.FLAG_CPU_GPU_HEADROOMS)
     public @FloatRange(from = 0f, to = 100f) float getCpuHeadroom(
@@ -127,8 +130,12 @@
             throw new UnsupportedOperationException();
         }
         try {
-            return mHintManager.getCpuHeadroom(
-                    params != null ? params.getInternal() : new CpuHeadroomParamsInternal())[0];
+            final CpuHeadroomResult ret = mHintManager.getCpuHeadroom(
+                    params != null ? params.getInternal() : new CpuHeadroomParamsInternal());
+            if (ret == null || ret.getTag() != CpuHeadroomResult.globalHeadroom) {
+                return Float.NaN;
+            }
+            return ret.getGlobalHeadroom();
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -144,8 +151,7 @@
      * @return a single value headroom or a {@code Float.NaN} if it's temporarily unavailable.
      *         A valid value is ranged from [0, 100], where 0 indicates no more GPU resources can be
      *         granted.
-     * @throws UnsupportedOperationException if the API is unsupported or the request params can't
-     *         be served.
+     * @throws UnsupportedOperationException if the API is unsupported.
      */
     @FlaggedApi(android.os.Flags.FLAG_CPU_GPU_HEADROOMS)
     public @FloatRange(from = 0f, to = 100f) float getGpuHeadroom(
@@ -154,8 +160,12 @@
             throw new UnsupportedOperationException();
         }
         try {
-            return mHintManager.getGpuHeadroom(
+            final GpuHeadroomResult ret = mHintManager.getGpuHeadroom(
                     params != null ? params.getInternal() : new GpuHeadroomParamsInternal());
+            if (ret == null || ret.getTag() != GpuHeadroomResult.globalHeadroom) {
+                return Float.NaN;
+            }
+            return ret.getGlobalHeadroom();
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
diff --git a/core/java/android/os/vibrator/BasicPwleSegment.java b/core/java/android/os/vibrator/BasicPwleSegment.java
new file mode 100644
index 0000000..ed68173
--- /dev/null
+++ b/core/java/android/os/vibrator/BasicPwleSegment.java
@@ -0,0 +1,222 @@
+/*
+ * 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.vibrator;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * A {@link VibrationEffectSegment} that represents a smooth transition from the starting
+ * intensity and sharpness to new values over a specified duration.
+ *
+ * <p>The intensity and sharpness are expressed by float values in the range [0, 1], where
+ * intensity represents the user-perceived strength of the vibration, while sharpness represents
+ * the crispness of the vibration.
+ *
+ * @hide
+ */
+@TestApi
+@FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+public final class BasicPwleSegment extends VibrationEffectSegment {
+    private final float mStartIntensity;
+    private final float mEndIntensity;
+    private final float mStartSharpness;
+    private final float mEndSharpness;
+    private final long mDuration;
+
+    BasicPwleSegment(@NonNull Parcel in) {
+        this(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat(), in.readLong());
+    }
+
+    /** @hide */
+    @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+    public BasicPwleSegment(float startIntensity, float endIntensity, float startSharpness,
+            float endSharpness, long duration) {
+        mStartIntensity = startIntensity;
+        mEndIntensity = endIntensity;
+        mStartSharpness = startSharpness;
+        mEndSharpness = endSharpness;
+        mDuration = duration;
+    }
+
+    public float getStartIntensity() {
+        return mStartIntensity;
+    }
+
+    public float getEndIntensity() {
+        return mEndIntensity;
+    }
+
+    public float getStartSharpness() {
+        return mStartSharpness;
+    }
+
+    public float getEndSharpness() {
+        return mEndSharpness;
+    }
+
+    @Override
+    public long getDuration() {
+        return mDuration;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof BasicPwleSegment)) {
+            return false;
+        }
+        BasicPwleSegment other = (BasicPwleSegment) o;
+        return Float.compare(mStartIntensity, other.mStartIntensity) == 0
+                && Float.compare(mEndIntensity, other.mEndIntensity) == 0
+                && Float.compare(mStartSharpness, other.mStartSharpness) == 0
+                && Float.compare(mEndSharpness, other.mEndSharpness) == 0
+                && mDuration == other.mDuration;
+    }
+
+    /** @hide */
+    @Override
+    public boolean areVibrationFeaturesSupported(@NonNull VibratorInfo vibratorInfo) {
+        return vibratorInfo.areEnvelopeEffectsSupported();
+    }
+
+    /** @hide */
+    @Override
+    public boolean isHapticFeedbackCandidate() {
+        return true;
+    }
+
+    /** @hide */
+    @Override
+    public void validate() {
+        Preconditions.checkArgumentInRange(mStartSharpness, 0f, 1f, "startSharpness");
+        Preconditions.checkArgumentInRange(mEndSharpness, 0f, 1f, "endSharpness");
+        Preconditions.checkArgumentInRange(mStartIntensity, 0f, 1f, "startIntensity");
+        Preconditions.checkArgumentInRange(mEndIntensity, 0f, 1f, "endIntensity");
+        Preconditions.checkArgumentPositive(mDuration, "Time must be greater than zero.");
+    }
+
+    /** @hide */
+    @NonNull
+    @Override
+    public BasicPwleSegment resolve(int defaultAmplitude) {
+        return this;
+    }
+
+    /** @hide */
+    @NonNull
+    @Override
+    public BasicPwleSegment scale(float scaleFactor) {
+        float newStartIntensity = VibrationEffect.scale(mStartIntensity, scaleFactor);
+        float newEndIntensity = VibrationEffect.scale(mEndIntensity, scaleFactor);
+        if (Float.compare(mStartIntensity, newStartIntensity) == 0
+                && Float.compare(mEndIntensity, newEndIntensity) == 0) {
+            return this;
+        }
+        return new BasicPwleSegment(newStartIntensity, newEndIntensity, mStartSharpness,
+                mEndSharpness,
+                mDuration);
+    }
+
+    /** @hide */
+    @NonNull
+    @Override
+    public BasicPwleSegment scaleLinearly(float scaleFactor) {
+        float newStartIntensity = VibrationEffect.scaleLinearly(mStartIntensity, scaleFactor);
+        float newEndIntensity = VibrationEffect.scaleLinearly(mEndIntensity, scaleFactor);
+        if (Float.compare(mStartIntensity, newStartIntensity) == 0
+                && Float.compare(mEndIntensity, newEndIntensity) == 0) {
+            return this;
+        }
+        return new BasicPwleSegment(newStartIntensity, newEndIntensity, mStartSharpness,
+                mEndSharpness,
+                mDuration);
+    }
+
+    /** @hide */
+    @NonNull
+    @Override
+    public BasicPwleSegment applyEffectStrength(int effectStrength) {
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mStartIntensity, mEndIntensity, mStartSharpness, mEndSharpness,
+                mDuration);
+    }
+
+    @Override
+    public String toString() {
+        return "BasicPwle{startIntensity=" + mStartIntensity
+                + ", endIntensity=" + mEndIntensity
+                + ", startSharpness=" + mStartSharpness
+                + ", endSharpness=" + mEndSharpness
+                + ", duration=" + mDuration
+                + "}";
+    }
+
+    /** @hide */
+    @Override
+    public String toDebugString() {
+        return String.format(Locale.US, "Pwle=%dms(intensity=%.2f @ %.2f to %.2f @ %.2f)",
+                mDuration,
+                mStartIntensity,
+                mStartSharpness,
+                mEndIntensity,
+                mEndSharpness);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(PARCEL_TOKEN_PWLE);
+        dest.writeFloat(mStartIntensity);
+        dest.writeFloat(mEndIntensity);
+        dest.writeFloat(mStartSharpness);
+        dest.writeFloat(mEndSharpness);
+        dest.writeLong(mDuration);
+    }
+
+    @NonNull
+    public static final Creator<BasicPwleSegment> CREATOR =
+            new Creator<BasicPwleSegment>() {
+                @Override
+                public BasicPwleSegment createFromParcel(Parcel in) {
+                    // Skip the type token
+                    in.readInt();
+                    return new BasicPwleSegment(in);
+                }
+
+                @Override
+                public BasicPwleSegment[] newArray(int size) {
+                    return new BasicPwleSegment[size];
+                }
+            };
+}
diff --git a/core/java/android/os/vibrator/PwlePoint.java b/core/java/android/os/vibrator/PwlePoint.java
index ea3ae6c..4be5c68 100644
--- a/core/java/android/os/vibrator/PwlePoint.java
+++ b/core/java/android/os/vibrator/PwlePoint.java
@@ -63,4 +63,12 @@
     public int hashCode() {
         return Objects.hash(mAmplitude, mFrequencyHz, mTimeMillis);
     }
+
+    @Override
+    public String toString() {
+        return "PwlePoint{amplitude=" + mAmplitude
+                + ", frequency=" + mFrequencyHz
+                + ", time=" + mTimeMillis
+                + "}";
+    }
 }
diff --git a/core/java/android/os/vibrator/PwleSegment.java b/core/java/android/os/vibrator/PwleSegment.java
index 9074bde..942b7b3 100644
--- a/core/java/android/os/vibrator/PwleSegment.java
+++ b/core/java/android/os/vibrator/PwleSegment.java
@@ -44,16 +44,16 @@
     private final float mStartFrequencyHz;
     private final float mEndAmplitude;
     private final float mEndFrequencyHz;
-    private final int mDuration;
+    private final long mDuration;
 
     PwleSegment(@android.annotation.NonNull Parcel in) {
-        this(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat(), in.readInt());
+        this(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat(), in.readLong());
     }
 
     /** @hide */
     @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
     public PwleSegment(float startAmplitude, float endAmplitude, float startFrequencyHz,
-            float endFrequencyHz, int duration) {
+            float endFrequencyHz, long duration) {
         mStartAmplitude = startAmplitude;
         mEndAmplitude = endAmplitude;
         mStartFrequencyHz = startFrequencyHz;
@@ -213,7 +213,7 @@
         dest.writeFloat(mEndAmplitude);
         dest.writeFloat(mStartFrequencyHz);
         dest.writeFloat(mEndFrequencyHz);
-        dest.writeInt(mDuration);
+        dest.writeLong(mDuration);
     }
 
     @android.annotation.NonNull
diff --git a/core/java/android/os/vibrator/VibrationEffectSegment.java b/core/java/android/os/vibrator/VibrationEffectSegment.java
index b934e11..325a058 100644
--- a/core/java/android/os/vibrator/VibrationEffectSegment.java
+++ b/core/java/android/os/vibrator/VibrationEffectSegment.java
@@ -47,6 +47,7 @@
     static final int PARCEL_TOKEN_STEP = 3;
     static final int PARCEL_TOKEN_RAMP = 4;
     static final int PARCEL_TOKEN_PWLE = 5;
+    static final int PARCEL_TOKEN_BASIC_PWLE = 6;
 
     /** Prevent subclassing from outside of this package */
     VibrationEffectSegment() {
@@ -228,7 +229,12 @@
                             if (Flags.normalizedPwleEffects()) {
                                 return new PwleSegment(in);
                             }
-                            // Fall through if the flag is not enabled.
+                            // Fall through to default if the flag is not enabled.
+                        case PARCEL_TOKEN_BASIC_PWLE:
+                            if (Flags.normalizedPwleEffects()) {
+                                return new BasicPwleSegment(in);
+                            }
+                            // Fall through to default if the flag is not enabled.
                         default:
                             throw new IllegalStateException(
                                     "Unexpected vibration event type token in parcel.");
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 1093503..a719583 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -58,7 +58,7 @@
     is_fixed_read_only: true
     namespace: "permissions"
     description: "enable enhanced confirmation incall apis"
-    bug: "310220212"
+    bug: "364535720"
 }
 
 flag {
@@ -67,7 +67,7 @@
     is_fixed_read_only: true
     namespace: "permissions"
     description: "enable the blocking of certain app installs during an unknown call"
-    bug: "310220212"
+    bug: "364535720"
 }
 
 flag {
@@ -427,3 +427,21 @@
     description: "Gives the device policy management role the ability to create a managed profile using new APIs"
     bug: "375382324"
 }
+
+flag {
+    name: "use_profile_labels_for_default_app_section_titles"
+    is_exported: true
+    is_fixed_read_only: true
+    namespace: "profile_experiences"
+    description: "Use profile labels from UserManager for default app section titles to allow partner customization"
+    bug: "358369931"
+}
+
+flag {
+    name: "wallet_role_cross_user_enabled"
+    is_exported: true
+    is_fixed_read_only: true
+    namespace: "wallet_integration"
+    description: "Enable the Wallet role within profiles"
+    bug: "356107987"
+}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 1b289fd..99ff38b 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -3151,7 +3151,7 @@
                  *                {@link #DEFAULT_ACCOUNT_STATE_CLOUD} or
                  *                {@link #DEFAULT_ACCOUNT_STATE_SIM}, or null otherwise.
                  */
-                public DefaultAccountAndState(@DefaultAccountState int state,
+                private DefaultAccountAndState(@DefaultAccountState int state,
                         @Nullable Account account) {
                     if (!isValidDefaultAccountState(state)) {
                         throw new IllegalArgumentException("Invalid default account state.");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 19b0c6f..d5b5258 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6271,6 +6271,14 @@
         public static final String TOUCHPAD_TAP_DRAGGING = "touchpad_tap_dragging";
 
         /**
+         * Whether to enable three finger tap customization on touchpads.
+         *
+         * @hide
+         */
+        public static final String TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION =
+                "touchpad_three_finger_tap_customization";
+
+        /**
          * Whether to enable a right-click zone on touchpads.
          *
          * When set to 1, pressing to click in a section on the right-hand side of the touchpad will
@@ -10991,6 +10999,25 @@
                 "emergency_gesture_ui_last_started_millis";
 
         /**
+         * Whether double tap the power button gesture is enabled.
+         *
+         * @hide
+         */
+        @Readable
+        public static final String DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED =
+                "double_tap_power_button_gesture_enabled";
+
+        /**
+         * Double tap power button gesture behavior.
+         * 0 = Camera launch
+         * 1 = Wallet launch
+         * @hide
+         */
+        @Readable
+        public static final String DOUBLE_TAP_POWER_BUTTON_GESTURE =
+                "double_tap_power_button_gesture";
+
+        /**
          * Whether the camera launch gesture to double tap the power button when the screen is off
          * should be disabled.
          *
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
index 9fe0dda..0302faf 100644
--- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
@@ -281,7 +281,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+    @RequiresPermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
     public void setAdvancedProtectionEnabled(boolean enabled) {
         try {
             mService.setAdvancedProtectionEnabled(enabled);
@@ -297,7 +297,7 @@
      */
     @SystemApi
     @NonNull
-    @RequiresPermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+    @RequiresPermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
     public List<AdvancedProtectionFeature> getAdvancedProtectionFeatures() {
         try {
             return mService.getAdvancedProtectionFeatures();
diff --git a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
index 6830763..1939f82 100644
--- a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
+++ b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
@@ -31,8 +31,8 @@
     void registerAdvancedProtectionCallback(IAdvancedProtectionCallback callback);
     @EnforcePermission("QUERY_ADVANCED_PROTECTION_MODE")
     void unregisterAdvancedProtectionCallback(IAdvancedProtectionCallback callback);
-    @EnforcePermission("SET_ADVANCED_PROTECTION_MODE")
+    @EnforcePermission("MANAGE_ADVANCED_PROTECTION_MODE")
     void setAdvancedProtectionEnabled(boolean enabled);
-    @EnforcePermission("SET_ADVANCED_PROTECTION_MODE")
+    @EnforcePermission("MANAGE_ADVANCED_PROTECTION_MODE")
     List<AdvancedProtectionFeature> getAdvancedProtectionFeatures();
 }
\ No newline at end of file
diff --git a/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
index 8759f72..eab1c15 100644
--- a/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
@@ -15,6 +15,7 @@
  */
 
 package android.security.intrusiondetection;
+
 import android.security.intrusiondetection.IntrusionDetectionEvent;
 
 import com.android.internal.infra.AndroidFuture;
@@ -24,18 +25,20 @@
     /**
      * Initialize the server side.
      */
-    void initialize(in AndroidFuture<int> resultFuture);
+    void initialize(in AndroidFuture<boolean> resultFuture);
 
     /**
-     * Send intrusiondetection logging data to the backup destination.
+     * Send intrusiondetection logging data to the transport destination.
      * The data is a list of IntrusionDetectionEvent.
      * The IntrusionDetectionEvent is an abstract class that represents
-     * different type of events.
+     * different types of events.
      */
-    void addData(in List<IntrusionDetectionEvent> events, in AndroidFuture<int> resultFuture);
+    void addData(
+        in List<IntrusionDetectionEvent> events,
+        in AndroidFuture<boolean> resultFuture);
 
     /**
      * Release the binder to the server.
      */
-    void release(in AndroidFuture<int> resultFuture);
+    void release(in AndroidFuture<boolean> resultFuture);
 }
diff --git a/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
index 538acf9..b479ca7 100644
--- a/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
@@ -22,6 +22,7 @@
 import android.app.admin.ConnectEvent;
 import android.app.admin.DnsEvent;
 import android.app.admin.SecurityLog.SecurityEvent;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.security.Flags;
@@ -31,14 +32,36 @@
 
 /**
  * A class that represents a intrusiondetection event.
+ *
  * @hide
  */
+@SystemApi
 @FlaggedApi(Flags.FLAG_AFL_API)
 public final class IntrusionDetectionEvent implements Parcelable {
     private static final String TAG = "IntrusionDetectionEvent";
 
+    /**
+     * Event type representing a security-related event.
+     * This type is associated with a {@link SecurityEvent} object.
+     *
+     * @see SecurityEvent
+     */
     public static final int SECURITY_EVENT = 0;
+
+    /**
+     * Event type representing a network DNS event.
+     * This type is associated with a {@link DnsEvent} object.
+     *
+     * @see DnsEvent
+     */
     public static final int NETWORK_EVENT_DNS = 1;
+
+    /**
+     * Event type representing a network connection event.
+     * This type is associated with a {@link ConnectEvent} object.
+     *
+     * @see ConnectEvent
+     */
     public static final int NETWORK_EVENT_CONNECT = 2;
 
     /** @hide */
@@ -67,6 +90,12 @@
                 }
             };
 
+    /**
+     * Creates an IntrusionDetectionEvent object with a
+     * {@link SecurityEvent} object as the event source.
+     *
+     * @param securityEvent The SecurityEvent object.
+     */
     public IntrusionDetectionEvent(@NonNull SecurityEvent securityEvent) {
         mType = SECURITY_EVENT;
         mSecurityEvent = securityEvent;
@@ -74,6 +103,12 @@
         mNetworkEventConnect = null;
     }
 
+    /**
+     * Creates an IntrusionDetectionEvent object with a
+     * {@link DnsEvent} object as the event source.
+     *
+     * @param dnsEvent The DnsEvent object.
+     */
     public IntrusionDetectionEvent(@NonNull DnsEvent dnsEvent) {
         mType = NETWORK_EVENT_DNS;
         mNetworkEventDns = dnsEvent;
@@ -81,6 +116,12 @@
         mNetworkEventConnect = null;
     }
 
+    /**
+     * Creates an IntrusionDetectionEvent object with a
+     * {@link ConnectEvent} object as the event source.
+     *
+     * @param connectEvent The ConnectEvent object.
+     */
     public IntrusionDetectionEvent(@NonNull ConnectEvent connectEvent) {
         mType = NETWORK_EVENT_CONNECT;
         mNetworkEventConnect = connectEvent;
diff --git a/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java b/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java
new file mode 100644
index 0000000..2e2d0f7
--- /dev/null
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.intrusiondetection;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.annotation.SuppressLint;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.util.CloseGuard;
+
+import android.security.Flags;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
+import android.security.intrusiondetection.IIntrusionDetectionEventTransport;
+
+import com.android.internal.infra.AndroidFuture;
+
+import java.lang.AutoCloseable;
+import java.util.List;
+
+/**
+ * A class that provides a stable API for transporting intrusion detection events
+ * to a transport location, such as a file or a network endpoint.
+ *
+ * This class acts as a bridge between the {@link IIntrusionDetectionEventTransport}
+ * interface and its implementations. It allows system components to add intrusion
+ * detection events ({@link IntrusionDetectionEvent}) to a transport queue,
+ * which will then be delivered to the specified location.
+ *
+ * Usage:
+ * 1. Obtain an instance of {@link IntrusionDetectionEventTransport} using the constructor.
+ * 2. Initialize the transport by calling {@link #initialize()}.
+ * 3. Add events to the transport queue using {@link #addData(List)}.
+ * 4. Release the transport when finished by calling {@link #release()}.
+ *
+ * Key Components:
+ * - {@link IIntrusionDetectionEventTransport}: The underlying AIDL interface
+ *     for interacting with transport implementations.
+ * - {@link IntrusionDetectionEvent}: Represents a single event.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_AFL_API)
+@SuppressLint("NotCloseable")
+public class IntrusionDetectionEventTransport {
+    IIntrusionDetectionEventTransport mBinderImpl = new TransportImpl();
+
+    /**
+     * Returns the binder interface for this transport.
+     */
+    @NonNull
+    public IBinder getBinder() {
+        return mBinderImpl.asBinder();
+    }
+
+    /**
+     * Initializes the transport.
+     *
+     * @return whether the initialization was successful.
+     */
+    public boolean initialize() {
+        return false;
+    }
+
+    /**
+     * Adds data to the transport.
+     *
+     * @param events the events to add.
+     * @return whether the addition was successful.
+     */
+    public boolean addData(@NonNull List<IntrusionDetectionEvent> events) {
+        return false;
+    }
+
+    /**
+     * Releases the transport.
+     *
+     * The release() method is a callback implemented by the concrete transport
+     * endpoint.
+     * The "SuppressLint" annotation is used to allow the release() method to be
+     * included in the API without requiring the class to implement AutoCloseable.
+     *
+     * @return whether the release was successful.
+     */
+    public boolean release() {
+        return false;
+    }
+
+    /**
+     * Bridge between the actual IIntrusionDetectionEventTransport implementation
+     * and the stable API.  If the binder interface needs to change, we use this
+     * layer to translate so that we can decouple those framework-side changes
+     * from the IntrusionDetectionEventTransport implementations.
+     */
+    class TransportImpl extends IIntrusionDetectionEventTransport.Stub {
+        @Override
+        public void initialize(AndroidFuture<Boolean> resultFuture) {
+            try {
+                boolean result = IntrusionDetectionEventTransport.this.initialize();
+                resultFuture.complete(result);
+            } catch (RuntimeException e) {
+                resultFuture.cancel(/* mayInterruptIfRunning */ true);
+            }
+        }
+
+        @Override
+        public void addData(
+            List<IntrusionDetectionEvent> events,
+            AndroidFuture<Boolean> resultFuture) {
+            try {
+                boolean result = IntrusionDetectionEventTransport.this.addData(events);
+                resultFuture.complete(result);
+            } catch (RuntimeException e) {
+                resultFuture.cancel(/* mayInterruptIfRunning */ true);
+            }
+        }
+
+        @Override
+        public void release(AndroidFuture<Boolean> resultFuture) {
+            try {
+                boolean result = IntrusionDetectionEventTransport.this.release();
+                resultFuture.complete(result);
+            } catch (RuntimeException e) {
+                resultFuture.cancel(/* mayInterruptIfRunning */ true);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig
index 6c92991..a5c837b 100644
--- a/core/java/android/security/responsible_apis_flags.aconfig
+++ b/core/java/android/security/responsible_apis_flags.aconfig
@@ -96,6 +96,21 @@
 }
 
 flag {
+    name: "prevent_intent_redirect_throw_exception_if_nested_keys_not_collected"
+    namespace: "responsible_apis"
+    description: "Prevent intent redirect attacks by throwing exception if the intent does not collect nested keys"
+    bug: "361143368"
+}
+
+flag {
+    name: "prevent_intent_redirect_collect_nested_keys_on_server_if_not_collected"
+    namespace: "responsible_apis"
+    description: "Prevent intent redirect attacks by collecting nested keys on server if not yet collected"
+    bug: "361143368"
+    is_fixed_read_only: true
+}
+
+flag {
     name: "enable_intent_matching_flags"
     is_exported: true
     namespace: "permissions"
@@ -110,3 +125,16 @@
     description: "Android Advanced Protection Mode Feature: Disable Install Unknown Sources"
     bug: "369361373"
 }
+
+flag {
+    name: "aapm_feature_memory_tagging_extension"
+    namespace: "responsible_apis"
+    description: "Android Advanced Protection Mode Feature: Memory Tagging Extension"
+    bug: "378931989"
+}
+flag {
+    name: "aapm_feature_disable_cellular_2g"
+    namespace: "responsible_apis"
+    description: "Android Advanced Protection Mode Feature: Disable Cellular 2G"
+    bug: "377748286"
+}
diff --git a/core/java/android/service/notification/SystemZenRules.java b/core/java/android/service/notification/SystemZenRules.java
index ebb8569..f11ce16 100644
--- a/core/java/android/service/notification/SystemZenRules.java
+++ b/core/java/android/service/notification/SystemZenRules.java
@@ -122,17 +122,16 @@
     @Nullable
     public static String getTriggerDescriptionForScheduleTime(Context context,
             @NonNull ScheduleInfo schedule) {
-        final StringBuilder sb = new StringBuilder();
         String daysSummary = getDaysOfWeekShort(context, schedule);
         if (daysSummary == null) {
             // no use outputting times without dates
             return null;
         }
-        sb.append(daysSummary);
-        sb.append(context.getString(R.string.zen_mode_trigger_summary_divider_text));
-        sb.append(getTimeSummary(context, schedule));
-
-        return sb.toString();
+        return context.getString(
+                R.string.zen_mode_trigger_summary_combined,
+                daysSummary,
+                getTimeSummary(context, schedule)
+        );
     }
 
     /**
diff --git a/core/java/android/service/quickaccesswallet/flags.aconfig b/core/java/android/service/quickaccesswallet/flags.aconfig
index 75a9309..7225f27 100644
--- a/core/java/android/service/quickaccesswallet/flags.aconfig
+++ b/core/java/android/service/quickaccesswallet/flags.aconfig
@@ -6,4 +6,11 @@
     namespace: "wallet_integration"
     description: "Option to launch the Wallet app on double-tap of the power button"
     bug: "378469025"
+}
+
+flag {
+    name: "launch_selected_card_from_qs_tile"
+    namespace: "wallet_integration"
+    description: "When the wallet QS tile is tapped, launch the selected card pending intent instead of the home screen pending intent."
+    bug: "378469025"
 }
\ No newline at end of file
diff --git a/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java b/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java
index 1d08c52..1acb7b8 100644
--- a/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java
+++ b/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java
@@ -19,7 +19,7 @@
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.SuppressLint;
-import android.app.PendingIntent;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -63,7 +63,7 @@
     private final boolean mRestricted;
     private final int mSensitivity;
     @Nullable
-    private final PendingIntent mLaunchIntent;
+    private final Intent mLaunchIntent;
     @NonNull
     private final Bundle mExtras;
 
@@ -149,6 +149,8 @@
 
     /**
      * Returns whether Preference is restricted.
+     * <p>If true, this means the Preference is treated as a Restricted Preference which indicates
+     * that it could be conditionally disabled/unavailable due to admin settings.
      */
     public boolean isRestricted() {
         return mRestricted;
@@ -165,14 +167,18 @@
     /**
      * Returns the intent to launch the host app page for this Preference.
      */
+    @SuppressLint("IntentBuilderName")
     @Nullable
-    public PendingIntent getLaunchIntent() {
+    public Intent getLaunchIntent() {
         return mLaunchIntent;
     }
 
     /**
      * Returns any additional fields specific to this preference.
-     * <p>Treat all data as optional.
+     * <p>Treat all data as optional. This may contain unstructured data for a given preference,
+     * where the type and format of this data may only known by inspecting the source code of that
+     * preference. As such, any access of this data must handle failures gracefully to account for
+     * changing or missing data.
      */
     @NonNull
     public Bundle getExtras() {
@@ -236,8 +242,8 @@
         mWritable = in.readBoolean();
         mRestricted = in.readBoolean();
         mSensitivity = in.readInt();
-        mLaunchIntent = in.readParcelable(PendingIntent.class.getClassLoader(),
-                PendingIntent.class);
+        mLaunchIntent = in.readParcelable(Intent.class.getClassLoader(),
+                Intent.class);
         mExtras = Objects.requireNonNullElseGet(in.readBundle(), Bundle::new);
     }
 
@@ -298,7 +304,7 @@
         private boolean mWritable = false;
         private boolean mRestricted = false;
         @WriteSensitivity private int mSensitivity = INTENT_ONLY;
-        private PendingIntent mLaunchIntent;
+        private Intent mLaunchIntent;
         private Bundle mExtras;
 
         /**
@@ -411,7 +417,7 @@
          * Sets the intent to launch the host app page for this preference.
          */
         @NonNull
-        public Builder setLaunchIntent(@Nullable PendingIntent launchIntent) {
+        public Builder setLaunchIntent(@Nullable Intent launchIntent) {
             mLaunchIntent = launchIntent;
             return this;
         }
diff --git a/core/java/android/service/settings/preferences/SettingsPreferenceServiceClient.java b/core/java/android/service/settings/preferences/SettingsPreferenceServiceClient.java
index 39995a4..f6d85d5 100644
--- a/core/java/android/service/settings/preferences/SettingsPreferenceServiceClient.java
+++ b/core/java/android/service/settings/preferences/SettingsPreferenceServiceClient.java
@@ -49,67 +49,55 @@
  * available services, a caller may query {@link android.content.pm.PackageManager} for applications
  * that provide the intent action {@link SettingsPreferenceService#ACTION_PREFERENCE_SERVICE} that
  * are also system applications ({@link android.content.pm.ApplicationInfo#FLAG_SYSTEM}).
+ * <p>
+ * Note: Each instance of this client will open a binding to an application. This can be resource
+ * intensive and affect the health of the system. It is essential that each client instance is
+ * only used when needed and the number of calls made are minimal.
  */
 @FlaggedApi(Flags.FLAG_SETTINGS_CATALYST)
 public class SettingsPreferenceServiceClient implements AutoCloseable {
 
+    @NonNull
     private final Context mContext;
+    @NonNull
     private final Intent mServiceIntent;
+    @NonNull
     private final ServiceConnection mServiceConnection;
-    private final boolean mSystemOnly;
+    @Nullable
     private ISettingsPreferenceService mRemoteService;
 
     /**
      * Construct a client for binding to a {@link SettingsPreferenceService} provided by the
      * application corresponding to the provided package name.
-     * @param packageName - package name for which this client will initiate a service binding
+     * @param context Application context
+     * @param packageName package name for which this client will initiate a service binding
+     * @param callbackExecutor executor on which to invoke clientReadyCallback
+     * @param clientReadyCallback callback invoked once the client is ready, error otherwise
      */
-    public SettingsPreferenceServiceClient(@NonNull Context context,
-                                           @NonNull String packageName) {
-        this(context, packageName, true, null);
+    public SettingsPreferenceServiceClient(
+            @NonNull Context context,
+            @NonNull String packageName,
+            @CallbackExecutor @NonNull Executor callbackExecutor,
+            @NonNull
+            OutcomeReceiver<SettingsPreferenceServiceClient, Exception> clientReadyCallback) {
+        this(context, packageName, true, callbackExecutor, clientReadyCallback);
     }
 
     /**
      * @hide Only to be called directly by test
      */
     @TestApi
-    public SettingsPreferenceServiceClient(@NonNull Context context,
-                                           @NonNull String packageName,
-                                           boolean systemOnly,
-                                           @Nullable ServiceConnection connectionListener) {
+    public SettingsPreferenceServiceClient(
+            @NonNull Context context,
+            @NonNull String packageName,
+            boolean systemOnly,
+            @CallbackExecutor @NonNull Executor callbackExecutor,
+            @NonNull
+            OutcomeReceiver<SettingsPreferenceServiceClient, Exception> clientReadyCallback) {
         mContext = context.getApplicationContext();
         mServiceIntent = new Intent(ACTION_PREFERENCE_SERVICE).setPackage(packageName);
-        mSystemOnly = systemOnly;
-        mServiceConnection = createServiceConnection(connectionListener);
-    }
-
-    /**
-     * Initiate binding to service.
-     * <p>If no service exists for the package provided or the package is not for a system
-     * application, no binding will occur.
-     */
-    public void start() {
-        PackageManager pm = mContext.getPackageManager();
-        PackageManager.ResolveInfoFlags flags;
-        if (mSystemOnly) {
-            flags = PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY);
-        } else {
-            flags = PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL);
-        }
-        List<ResolveInfo> infos = pm.queryIntentServices(mServiceIntent, flags);
-        if (infos.size() == 1) {
-            mContext.bindService(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
-        }
-    }
-
-    /**
-     * If there is an active service binding, unbind from that service.
-     */
-    public void stop() {
-        if (mRemoteService != null) {
-            mRemoteService = null;
-            mContext.unbindService(mServiceConnection);
-        }
+        mServiceConnection = createServiceConnection(callbackExecutor, clientReadyCallback);
+        connect(systemOnly, callbackExecutor, clientReadyCallback);
     }
 
     /**
@@ -209,32 +197,6 @@
         }
     }
 
-    @NonNull
-    private ServiceConnection createServiceConnection(@Nullable ServiceConnection listener) {
-        return new ServiceConnection() {
-            @Override
-            public void onServiceConnected(ComponentName name, IBinder service) {
-                mRemoteService = getPreferenceServiceInterface(service);
-                if (listener != null) {
-                    listener.onServiceConnected(name, service);
-                }
-            }
-
-            @Override
-            public void onServiceDisconnected(ComponentName name) {
-                mRemoteService = null;
-                if (listener != null) {
-                    listener.onServiceDisconnected(name);
-                }
-            }
-        };
-    }
-
-    @NonNull
-    private ISettingsPreferenceService getPreferenceServiceInterface(@NonNull IBinder service) {
-        return ISettingsPreferenceService.Stub.asInterface(service);
-    }
-
     /**
      * This client handles a resource, thus is it important to appropriately close that resource
      * when it is no longer needed.
@@ -243,6 +205,65 @@
      */
     @Override
     public void close() {
-        stop();
+        if (mRemoteService != null) {
+            mRemoteService = null;
+            mContext.unbindService(mServiceConnection);
+        }
+    }
+
+    /*
+     * Initiate binding to service.
+     * <p>If no service exists for the package provided or the package is not for a system
+     * application, no binding will occur.
+     */
+    private void connect(
+            boolean matchSystemOnly,
+            @NonNull Executor callbackExecutor,
+            @NonNull OutcomeReceiver<SettingsPreferenceServiceClient, Exception> clientCallback) {
+        PackageManager pm = mContext.getPackageManager();
+        PackageManager.ResolveInfoFlags flags;
+        if (matchSystemOnly) {
+            flags = PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY);
+        } else {
+            flags = PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL);
+        }
+        List<ResolveInfo> infos = pm.queryIntentServices(mServiceIntent, flags);
+        if (infos.size() != 1
+                || !mContext.bindService(mServiceIntent, mServiceConnection,
+                Context.BIND_AUTO_CREATE)) {
+            callbackExecutor.execute(() ->
+                    clientCallback.onError(new IllegalStateException("Unable to bind service")));
+        }
+    }
+
+    @NonNull
+    private ServiceConnection createServiceConnection(
+            @NonNull Executor callbackExecutor,
+            @NonNull OutcomeReceiver<SettingsPreferenceServiceClient, Exception> clientCallback) {
+        return new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                mRemoteService = ISettingsPreferenceService.Stub.asInterface(service);
+                callbackExecutor.execute(() ->
+                        clientCallback.onResult(SettingsPreferenceServiceClient.this));
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+                mRemoteService = null;
+            }
+
+            @Override
+            public void onBindingDied(ComponentName name) {
+                close();
+            }
+
+            @Override
+            public void onNullBinding(ComponentName name) {
+                callbackExecutor.execute(() -> clientCallback.onError(
+                        new IllegalStateException("Unable to connect client")));
+                close();
+            }
+        };
     }
 }
diff --git a/core/java/android/service/settings/preferences/SettingsPreferenceValue.java b/core/java/android/service/settings/preferences/SettingsPreferenceValue.java
index f056e34..08826ca 100644
--- a/core/java/android/service/settings/preferences/SettingsPreferenceValue.java
+++ b/core/java/android/service/settings/preferences/SettingsPreferenceValue.java
@@ -44,6 +44,7 @@
     @Type
     private final int mType;
     private final boolean mBooleanValue;
+    private final int mIntValue;
     private final long mLongValue;
     private final double mDoubleValue;
     @Nullable
@@ -65,6 +66,13 @@
     }
 
     /**
+     * Returns the int value for Preference if type is {@link #TYPE_INT}.
+     */
+    public int getIntValue() {
+        return mIntValue;
+    }
+
+    /**
      * Returns the long value for Preference if type is {@link #TYPE_LONG}.
      */
     public long getLongValue() {
@@ -92,6 +100,7 @@
             TYPE_LONG,
             TYPE_DOUBLE,
             TYPE_STRING,
+            TYPE_INT,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Type {}
@@ -104,6 +113,8 @@
     public static final int TYPE_DOUBLE = 2;
     /** Value is of type string. Access via {@link #getStringValue}. */
     public static final int TYPE_STRING = 3;
+    /** Value is of type int. Access via {@link #getIntValue}. */
+    public static final int TYPE_INT = 4;
 
     private SettingsPreferenceValue(@NonNull Builder builder) {
         mType = builder.mType;
@@ -111,6 +122,7 @@
         mLongValue = builder.mLongValue;
         mDoubleValue = builder.mDoubleValue;
         mStringValue = builder.mStringValue;
+        mIntValue = builder.mIntValue;
     }
 
     private SettingsPreferenceValue(@NonNull Parcel in) {
@@ -119,6 +131,7 @@
         mLongValue = in.readLong();
         mDoubleValue = in.readDouble();
         mStringValue = in.readString8();
+        mIntValue = in.readInt();
     }
 
     /** @hide */
@@ -129,6 +142,7 @@
         dest.writeLong(mLongValue);
         dest.writeDouble(mDoubleValue);
         dest.writeString8(mStringValue);
+        dest.writeInt(mIntValue);
     }
 
     /** @hide */
@@ -163,6 +177,7 @@
         private long mLongValue;
         private double mDoubleValue;
         private String mStringValue;
+        private int mIntValue;
 
         /**
          * Create Builder instance.
@@ -183,6 +198,15 @@
         }
 
         /**
+         * Sets the int value for Preference.
+         */
+        @NonNull
+        public Builder setIntValue(int intValue) {
+            mIntValue = intValue;
+            return this;
+        }
+
+        /**
          * Sets long value for Preference.
          */
         @NonNull
diff --git a/core/java/android/service/wearable/WearableSensingService.java b/core/java/android/service/wearable/WearableSensingService.java
index 47ec080..e20d5e9 100644
--- a/core/java/android/service/wearable/WearableSensingService.java
+++ b/core/java/android/service/wearable/WearableSensingService.java
@@ -27,6 +27,7 @@
 import android.app.ambientcontext.AmbientContextEventRequest;
 import android.app.wearable.Flags;
 import android.app.wearable.IWearableSensingCallback;
+import android.app.wearable.WearableConnection;
 import android.app.wearable.WearableSensingDataRequest;
 import android.app.wearable.WearableSensingManager;
 import android.content.Context;
@@ -380,7 +381,11 @@
      *
      * @param secureWearableConnection The secure connection to the wearable.
      * @param statusConsumer The consumer for the service status.
+     * @deprecated Use {@link #onSecureConnectionProvided(ParcelFileDescriptor, PersistableBundle,
+     *     Consumer)} instead to receive a remote wearable device connection.
      */
+    @FlaggedApi(Flags.FLAG_ENABLE_CONCURRENT_WEARABLE_CONNECTIONS)
+    @Deprecated
     @BinderThread
     public void onSecureConnectionProvided(
             @NonNull ParcelFileDescriptor secureWearableConnection,
@@ -389,12 +394,20 @@
     }
 
     /**
-     * Called when a secure connection to the wearable is available.
+     * Called when a secure connection to the wearable is available. See {@link
+     * WearableSensingManager#provideConnection(WearableConnection, Executor)} for details about the
+     * secure connection.
+     *
+     * <p>When the {@code secureWearableConnection} is closed, the system will send a {@link
+     * WearableSensingManager#STATUS_CHANNEL_ERROR} status code to the error callback provided by
+     * the caller of {@link WearableSensingManager#provideConnection(WearableConnection, Executor)}.
+     *
+     * <p>The implementing class should override this method. It should return an appropriate status
+     * code via {@code statusConsumer} after receiving the {@code secureWearableConnection}.
      *
      * @param secureWearableConnection The secure connection to the wearable.
      * @param metadata Metadata related to the provided connection.
      * @param statusConsumer The consumer for the service status.
-     * @see #onSecureConnectionProvided(ParcelFileDescriptor, Consumer)
      */
     @FlaggedApi(Flags.FLAG_ENABLE_CONCURRENT_WEARABLE_CONNECTIONS)
     @BinderThread
diff --git a/core/java/android/text/style/TtsSpan.java b/core/java/android/text/style/TtsSpan.java
index b7b8f0b1..a337ba2 100644
--- a/core/java/android/text/style/TtsSpan.java
+++ b/core/java/android/text/style/TtsSpan.java
@@ -19,6 +19,7 @@
 import static com.android.text.flags.Flags.FLAG_TTS_SPAN_DURATION;
 
 import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.PersistableBundle;
@@ -324,7 +325,8 @@
 
     /**
      * Argument used to specify the seconds of a time or duration. The seconds should be
-     * provided as an integer in the range from 0 up to and including 59.
+     * provided as an integer in the range from 0 up to and including 59 for
+     * {@link #TYPE_TIME}.
      * Can be used with {@link #TYPE_TIME} or {@link #TYPE_DURATION}.
      */
     @FlaggedApi(FLAG_TTS_SPAN_DURATION)
@@ -1140,7 +1142,7 @@
          * @return This instance.
          * @see #ARG_HOURS
          */
-        public TimeBuilder setHours(int hours) {
+        public TimeBuilder setHours(@IntRange(from = 0, to = 24) int hours) {
             return setIntArgument(TtsSpan.ARG_HOURS, hours);
         }
 
@@ -1151,7 +1153,7 @@
          * @return This instance.
          * @see #ARG_MINUTES
          */
-        public TimeBuilder setMinutes(int minutes) {
+        public TimeBuilder setMinutes(@IntRange(from = 0, to = 59) int minutes) {
             return setIntArgument(TtsSpan.ARG_MINUTES, minutes);
         }
 
@@ -1162,7 +1164,7 @@
          */
         @FlaggedApi(FLAG_TTS_SPAN_DURATION)
         @NonNull
-        public TimeBuilder setSeconds(int seconds) {
+        public TimeBuilder setSeconds(@IntRange(from = 0, to = 59) int seconds) {
             return setIntArgument(TtsSpan.ARG_SECONDS, seconds);
         }
     }
diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java
index 264db4a..239da87 100644
--- a/core/java/android/view/AttachedSurfaceControl.java
+++ b/core/java/android/view/AttachedSurfaceControl.java
@@ -210,6 +210,9 @@
     /**
      * Registers a {@link OnJankDataListener} to receive jank classification data about rendered
      * frames.
+     * <p>
+     * Use {@link SurfaceControl.OnJankDataListenerRegistration#removeAfter} to unregister the
+     * listener.
      *
      * @param executor The executor on which the listener will be invoked.
      * @param listener The listener to add.
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index a1a9fc6..c9d560c 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -20,6 +20,7 @@
 import static android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS;
 import static android.hardware.flags.Flags.FLAG_OVERLAYPROPERTIES_CLASS_API;
 
+import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_GET_SUPPORTED_REFRESH_RATES;
 import static com.android.server.display.feature.flags.Flags.FLAG_HIGHEST_HDR_SDR_RATIO_API;
 import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_HAS_ARR_SUPPORT;
 import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE;
@@ -63,6 +64,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
@@ -1207,17 +1209,36 @@
 
     /**
      * Get the supported refresh rates of this display in frames per second.
-     * <p>
-     * This method only returns refresh rates for the display's default modes. For more options, use
-     * {@link #getSupportedModes()}.
      *
-     * @deprecated use {@link #getSupportedModes()} instead
+     * <ul>
+     * <li> Android version {@link Build.VERSION_CODES#BAKLAVA} and above:
+     * returns display supported render rates.
+     * <li> Android version {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} and below:
+     * This method only returns refresh rates for the display's default modes. For more options,
+     * use {@link #getSupportedModes()}.
+     * </ul>
      */
-    @Deprecated
-    public float[] getSupportedRefreshRates() {
+    @FlaggedApi(FLAG_ENABLE_GET_SUPPORTED_REFRESH_RATES)
+    public @NonNull float[] getSupportedRefreshRates() {
         synchronized (mLock) {
             updateDisplayInfoLocked();
-            return mDisplayInfo.getDefaultRefreshRates();
+            final float[] refreshRates = mDisplayInfo.getDefaultRefreshRates();
+            Objects.requireNonNull(refreshRates);
+            return refreshRates;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    @SuppressLint({"UnflaggedApi"}) // Usage in the CTS to test backward compatibility.
+    public @NonNull float[] getSupportedRefreshRatesLegacy() {
+        synchronized (mLock) {
+            updateDisplayInfoLocked();
+            final float[] refreshRates = mDisplayInfo.getDefaultRefreshRatesLegacy();
+            Objects.requireNonNull(refreshRates);
+            return refreshRates;
         }
     }
 
@@ -1279,8 +1300,19 @@
         }
     }
 
+    /**
+     * Represents the {@link FrameRateCategory} for the Normal frame rate
+     *
+     * @see FrameRateCategory
+     */
     @FlaggedApi(FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE)
     public static final int FRAME_RATE_CATEGORY_NORMAL = 0;
+
+    /**
+     * Represents the {@link FrameRateCategory} for the High frame rate
+     *
+     * @see FrameRateCategory
+     */
     @FlaggedApi(FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE)
     public static final int FRAME_RATE_CATEGORY_HIGH = 1;
 
@@ -2438,6 +2470,8 @@
          * constrained by the system.
          * @hide
          */
+        @SuppressWarnings("UnflaggedApi") // For testing only
+        @TestApi
         public float getVsyncRate() {
             return mVsyncRate;
         }
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 4ff04d5..8b6458a 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -210,6 +210,11 @@
     public FrameRateCategoryRate frameRateCategoryRate;
 
     /**
+     * All the refresh rates supported in the active mode.
+     */
+    public float[] supportedRefreshRates = new float[0];
+
+    /**
      * The default display mode.
      */
     public int defaultModeId;
@@ -449,6 +454,7 @@
                 && modeId == other.modeId
                 && hasArrSupport == other.hasArrSupport
                 && Objects.equals(frameRateCategoryRate, other.frameRateCategoryRate)
+                && Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
                 && defaultModeId == other.defaultModeId
                 && userPreferredModeId == other.userPreferredModeId
                 && Arrays.equals(supportedModes, other.supportedModes)
@@ -512,6 +518,8 @@
         renderFrameRate = other.renderFrameRate;
         hasArrSupport = other.hasArrSupport;
         frameRateCategoryRate = other.frameRateCategoryRate;
+        supportedRefreshRates = Arrays.copyOf(
+                other.supportedRefreshRates, other.supportedRefreshRates.length);
         defaultModeId = other.defaultModeId;
         userPreferredModeId = other.userPreferredModeId;
         supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
@@ -571,6 +579,11 @@
         hasArrSupport = source.readBoolean();
         frameRateCategoryRate = source.readParcelable(null,
                 android.view.FrameRateCategoryRate.class);
+        int numOfSupportedRefreshRates = source.readInt();
+        supportedRefreshRates = new float[numOfSupportedRefreshRates];
+        for (int i = 0; i < numOfSupportedRefreshRates; i++) {
+            supportedRefreshRates[i] = source.readFloat();
+        }
         defaultModeId = source.readInt();
         userPreferredModeId = source.readInt();
         int nModes = source.readInt();
@@ -646,6 +659,10 @@
         dest.writeFloat(renderFrameRate);
         dest.writeBoolean(hasArrSupport);
         dest.writeParcelable(frameRateCategoryRate, flags);
+        dest.writeInt(supportedRefreshRates.length);
+        for (float supportedRefreshRate : supportedRefreshRates) {
+            dest.writeFloat(supportedRefreshRate);
+        }
         dest.writeInt(defaultModeId);
         dest.writeInt(userPreferredModeId);
         dest.writeInt(supportedModes.length);
@@ -750,9 +767,19 @@
     }
 
     /**
-     * Returns the list of supported refresh rates in the default mode.
+     * Returns the list of supported refresh rates in the active mode.
      */
     public float[] getDefaultRefreshRates() {
+        if (supportedRefreshRates.length == 0) {
+            return getDefaultRefreshRatesLegacy();
+        }
+        return Arrays.copyOf(supportedRefreshRates, supportedRefreshRates.length);
+    }
+
+    /**
+     * Returns the list of supported refresh rates in the default mode.
+     */
+    public float[] getDefaultRefreshRatesLegacy() {
         Display.Mode[] modes = appsSupportedModes;
         ArraySet<Float> rates = new ArraySet<>();
         Display.Mode defaultMode = getDefaultMode();
@@ -898,6 +925,8 @@
         sb.append(hasArrSupport);
         sb.append(", frameRateCategoryRate ");
         sb.append(frameRateCategoryRate);
+        sb.append(", supportedRefreshRates ");
+        sb.append(Arrays.toString(supportedRefreshRates));
         sb.append(", defaultMode ");
         sb.append(defaultModeId);
         sb.append(", userPreferredModeId ");
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 11a3168..1f8f0820 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -372,4 +372,14 @@
      */
     oneway void notifyImeWindowVisibilityChangedFromClient(IWindow window, boolean visible,
             in ImeTracker.Token statsToken);
+
+    /**
+     * Notifies WindowState whether inset animations are currently running within the Window.
+     * This value is used by the server to vote for refresh rate.
+     * see {@link com.android.server.wm.WindowState#mInsetsAnimationRunning).
+     *
+     * @param window The window that is insets animaiton is running.
+     * @param running Indicates the insets animation state.
+     */
+    oneway void notifyInsetsAnimationRunningStateChanged(IWindow window, boolean running);
 }
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 58ef5ef..6cd4a40 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -260,6 +260,15 @@
         touchableRegionSurfaceControl = new WeakReference<>(bounds);
     }
 
+    /**
+     * Resize the window touchable region.
+     * @param rect new touchable region rectangle.
+     */
+    public void setTouchableRegion(Rect rect) {
+        touchableRegion.set(rect);
+    }
+
+
     public void setWindowToken(IBinder iwindow) {
         windowToken = iwindow;
     }
diff --git a/core/java/android/view/ScrollCaptureSearchResults.java b/core/java/android/view/ScrollCaptureSearchResults.java
index 3469b9d..b1ce949 100644
--- a/core/java/android/view/ScrollCaptureSearchResults.java
+++ b/core/java/android/view/ScrollCaptureSearchResults.java
@@ -16,10 +16,16 @@
 
 package android.view;
 
+import static android.view.flags.Flags.scrollCaptureTargetZOrderFix;
+
+import static java.util.Comparator.comparing;
 import static java.util.Objects.requireNonNull;
+import static java.util.Objects.requireNonNullElse;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UiThread;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.CancellationSignal;
 import android.util.IndentingPrintWriter;
@@ -113,7 +119,9 @@
 
     private void signalComplete() {
         mComplete = true;
-        mTargets.sort(PRIORITY_ORDER);
+        if (!scrollCaptureTargetZOrderFix()) {
+            mTargets.sort(PRIORITY_ORDER);
+        }
         if (mOnCompleteListener != null) {
             mOnCompleteListener.run();
             mOnCompleteListener = null;
@@ -125,14 +133,73 @@
         return new ArrayList<>(mTargets);
     }
 
+    private Rect getScrollBoundsInWindow(@Nullable ScrollCaptureTarget target) {
+        if (target == null || target.getScrollBounds() == null) {
+            return new Rect();
+        }
+        Rect windowRect = new Rect(target.getScrollBounds());
+        Point windowPosition = target.getPositionInWindow();
+        windowRect.offset(windowPosition.x, windowPosition.y);
+        return windowRect;
+    }
+
     /**
      * Get the top ranked result out of all completed requests.
      *
      * @return the top ranked result
      */
+    @Nullable
     public ScrollCaptureTarget getTopResult() {
-        ScrollCaptureTarget target = mTargets.isEmpty() ? null : mTargets.get(0);
-        return target != null && target.getScrollBounds() != null ? target : null;
+        if (!scrollCaptureTargetZOrderFix()) {
+            ScrollCaptureTarget target = mTargets.isEmpty() ? null : mTargets.get(0);
+            return target != null && target.getScrollBounds() != null ? target : null;
+        }
+        List<ScrollCaptureTarget> filtered = new ArrayList<>();
+
+        mTargets.removeIf(a -> nullOrEmpty(a.getScrollBounds()));
+
+        // Remove scroll targets obscured or covered by other scrolling views.
+        nextTarget:
+        for (int i = 0; i <  mTargets.size(); i++) {
+            ScrollCaptureTarget current = mTargets.get(i);
+
+            View currentView = current.getContainingView();
+
+            // Nested scroll containers:
+            // Check if the next view is a child of the current. If so, skip the current.
+            if (i + 1 < mTargets.size()) {
+                ScrollCaptureTarget next = mTargets.get(i + 1);
+                View nextView = next.getContainingView();
+                // Honor explicit include hint on parent as escape hatch (unless both have it)
+                if (isDescendant(currentView, nextView)
+                        && (!hasIncludeHint(currentView) || hasIncludeHint(nextView))) {
+                    continue;
+                }
+            }
+
+            // Check if any views will be drawn partially or fully over this one.
+            for (int j = i + 1; j < mTargets.size(); j++) {
+                ScrollCaptureTarget above = mTargets.get(j);
+                if (Rect.intersects(getScrollBoundsInWindow(current),
+                        getScrollBoundsInWindow(above))) {
+                    continue nextTarget;
+                }
+            }
+
+            filtered.add(current);
+        }
+
+        // natural order, false->true
+        Comparator<ScrollCaptureTarget> byIncludeHintPresence = comparing(
+                ScrollCaptureSearchResults::hasIncludeHint);
+
+        // natural order, smallest->largest area
+        Comparator<ScrollCaptureTarget> byArea = comparing(
+                target -> area(requireNonNullElse(target.getScrollBounds(), new Rect())));
+
+        // The top result is the last one (with include hint if present, then by largest area)
+        filtered.sort(byIncludeHintPresence.thenComparing(byArea));
+        return filtered.isEmpty() ? null : filtered.getLast();
     }
 
     private class SearchRequest implements Consumer<Rect> {
@@ -226,6 +293,10 @@
         return r == null || r.isEmpty();
     }
 
+    private static boolean hasIncludeHint(ScrollCaptureTarget target) {
+        return hasIncludeHint(target.getContainingView());
+    }
+
     private static boolean hasIncludeHint(View view) {
         return (view.getScrollCaptureHint() & View.SCROLL_CAPTURE_HINT_INCLUDE) != 0;
     }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index d56768d..dd9a95e 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -37,6 +37,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.Size;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.ColorSpace;
@@ -58,6 +59,7 @@
 import android.hardware.display.DisplayedContentSample;
 import android.hardware.display.DisplayedContentSamplingAttributes;
 import android.hardware.graphics.common.DisplayDecorationSupport;
+import android.media.quality.PictureProfileHandle;
 import android.opengl.EGLDisplay;
 import android.opengl.EGLSync;
 import android.os.Build;
@@ -234,7 +236,6 @@
             long nativeObject, float currentBufferRatio, float desiredRatio);
     private static native void nativeSetDesiredHdrHeadroom(long transactionObj,
             long nativeObject, float desiredRatio);
-
     private static native void nativeSetCachingHint(long transactionObj,
             long nativeObject, int cachingHint);
     private static native void nativeSetDamageRegion(long transactionObj, long nativeObject,
@@ -314,6 +315,11 @@
     private static native void nativeSetLuts(long transactionObj, long nativeObject,
             float[] buffers, int[] slots, int[] dimensions, int[] sizes, int[] samplingKeys);
     private static native void nativeEnableDebugLogCallPoints(long transactionObj);
+    private static native int nativeGetMaxPictureProfiles();
+    private static native void nativeSetPictureProfileId(long transactionObj,
+            long nativeObject, long pictureProfileId);
+    private static native void nativeSetContentPriority(long transactionObj, long nativeObject,
+            int priority);
 
     /**
      * Transforms that can be applied to buffers as they are displayed to a window.
@@ -598,8 +604,11 @@
         }
 
         /**
-         * Request a flush of any pending jank classification data. May cause the registered
-         * listener to be invoked inband.
+         * Request a flush of any pending jank classification data.
+         * <p>
+         * May cause the registered listener to be invoked inband. Since jank is tracked by the
+         * system compositor by surface, flushing the data on one listener, will also cause other
+         * listeners on the same surface to receive jank classification data.
          */
         public void flush() {
             nativeFlushJankData(mNativeObject);
@@ -1923,6 +1932,7 @@
         public float renderFrameRate;
         public boolean hasArrSupport;
         public FrameRateCategoryRate frameRateCategoryRate;
+        public float[] supportedRefreshRates;
 
         public int[] supportedColorModes;
         public int activeColorMode;
@@ -1942,6 +1952,7 @@
                     + ", renderFrameRate=" + renderFrameRate
                     + ", hasArrSupport=" + hasArrSupport
                     + ", frameRateCategoryRate=" + frameRateCategoryRate
+                    + ", supportedRefreshRates=" + Arrays.toString(supportedRefreshRates)
                     + ", supportedColorModes=" + Arrays.toString(supportedColorModes)
                     + ", activeColorMode=" + activeColorMode
                     + ", hdrCapabilities=" + hdrCapabilities
@@ -1963,14 +1974,15 @@
                 && Objects.equals(hdrCapabilities, that.hdrCapabilities)
                 && preferredBootDisplayMode == that.preferredBootDisplayMode
                 && hasArrSupport == that.hasArrSupport
-                && Objects.equals(frameRateCategoryRate, that.frameRateCategoryRate);
+                && Objects.equals(frameRateCategoryRate, that.frameRateCategoryRate)
+                && Arrays.equals(supportedRefreshRates, that.supportedRefreshRates);
         }
 
         @Override
         public int hashCode() {
             return Objects.hash(Arrays.hashCode(supportedDisplayModes), activeDisplayModeId,
                     renderFrameRate, activeColorMode, hdrCapabilities, hasArrSupport,
-                    frameRateCategoryRate);
+                    frameRateCategoryRate, Arrays.hashCode(supportedRefreshRates));
         }
     }
 
@@ -2833,6 +2845,33 @@
     }
 
     /**
+     * Retrieve the maximum number of concurrent picture profiles allowed across all displays.
+     *
+     * A picture profile is assigned to a layer via:
+     * <ul>
+     *     <li>Picture processing via {@link MediaCodec.KEY_PICTURE_PROFILE}</li>
+     *     <li>Picture processing via {@link SurfaceControl.Transaction#setPictureProfileHandle}
+     *     </li>
+     * </ul>
+     *
+     * If the maximum number is exceeded, some layers will not receive profiles based on:
+     * <ul>
+     *     <li>The content priority assigned by the app</li>
+     *     <li>The system-determined priority of the app owning the layer</li>
+     * </ul>
+     *
+     * @see MediaCodec.KEY_PICTURE_PROFILE
+     * @see SurfaceControl.Transaction#setPictureProfileHandle
+     * @see SurfaceControl.Transaction#setContentPriority
+     *
+     * @hide
+     */
+    @IntRange(from = 0)
+    public static int getMaxPictureProfiles() {
+        return nativeGetMaxPictureProfiles();
+    }
+
+    /**
      * Interface to handle request to
      * {@link SurfaceControl.Transaction#addTransactionCommittedListener(Executor, TransactionCommittedListener)}
      */
@@ -4595,6 +4634,71 @@
         }
 
         /**
+         * Sets the desired picture profile handle for a layer.
+         * <p>
+         * A handle, retrieved from {@link MediaQualityManager#getProfileHandles}, which
+         * refers a set of parameters that are used to configure picture processing that is applied
+         * to all subsequent buffers to enhance the quality of their contents (e.g. gamma, color
+         * temperature, hue, saturation, etc.).
+         * <p>
+         * Setting a handle does not guarantee access to limited picture processing. The content
+         * priority for the  as well as the prominance of app to the current user experience plays a
+         * role in which layer(s) get access to the limited picture processing resources. A maximum
+         * number of {@link MediaQualityManager.getMaxPictureProfiles} can be applied at any given
+         * point in time.
+         *
+         * @param sc The SurfaceControl of the layer that should be updated
+         * @param handle The picture profile handle which refers to the set of desired parameters
+         *
+         * @see MediaQualityManager#getMaxPictureProfiles
+         * @see MediaQualityManager#getProfileHandles
+         * @see MediaCodec.KEY_PICTURE_PROFILE
+         * @see SurfaceControl.Transaction#setContentPriority
+         *
+         * @hide
+         */
+        @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
+        @SystemApi
+        public @NonNull Transaction setPictureProfileHandle(@NonNull SurfaceControl sc,
+                                                            @NonNull PictureProfileHandle handle) {
+            checkPreconditions(sc);
+
+            nativeSetPictureProfileId(mNativeObject, sc.mNativeObject, handle.getId());
+            return this;
+        }
+
+        /**
+         * Sets the importance the layer's contents has to the app's user experience.
+         * <p>
+         * When a two layers within the same app are competing for a limited rendering resource,
+         * the priority will determine which layer gets access to the resource. The lower the
+         * priority, the more likely the layer will get access to the resource.
+         * <p>
+         * Resources managed by this priority:
+         * <ul>
+         *     <li>Picture processing via {@link MediaCodec.KEY_PICTURE_PROFILE}</li>
+         *     <li>Picture processing via {@link SurfaceControl.Transaction#setPictureProfileHandle}
+         *     </li>
+         * </ul>
+         *
+         * @param sc The SurfaceControl of the layer that should be updated
+         * @param priority The priority this layer should have with respect to other layers in the
+         *                 app. The default priority is zero.
+         *
+         * @see MediaQualityManager#getMaxPictureProfiles
+         * @see MediaCodec.KEY_PICTURE_PROFILE
+         * @see SurfaceControl.Transaction#setPictureProfileHandle
+         */
+        @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
+        public @NonNull Transaction setContentPriority(@NonNull SurfaceControl sc,
+                                                       int priority) {
+            checkPreconditions(sc);
+
+            nativeSetContentPriority(mNativeObject, sc.mNativeObject, priority);
+            return this;
+        }
+
+        /**
          * Sets the caching hint for the layer. By default, the caching hint is
          * {@link CACHING_ENABLED}.
          *
diff --git a/core/java/android/view/SurfaceControlActivePicture.java b/core/java/android/view/SurfaceControlActivePicture.java
new file mode 100644
index 0000000..569159d
--- /dev/null
+++ b/core/java/android/view/SurfaceControlActivePicture.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.NonNull;
+import android.media.quality.PictureProfileHandle;
+
+/**
+ * A record of a visible layer that is using picture processing.
+ * @hide
+ */
+public class SurfaceControlActivePicture {
+    private final int mLayerId;
+    private final int mOwnerUid;
+    private final @NonNull PictureProfileHandle mPictureProfileHandle;
+
+    /**
+     * Create a record of a visible layer that is using picture processing.
+     *
+     * @param layerId the layer that is using picture processing
+     * @param ownerUid the UID of the package that owns the layer
+     * @param handle the handle for the picture profile that configured the processing
+     */
+    private SurfaceControlActivePicture(int layerId, int ownerUid, PictureProfileHandle handle) {
+        mLayerId = layerId;
+        mOwnerUid = ownerUid;
+        mPictureProfileHandle = handle;
+    }
+
+    /** The layer that is using picture processing.  */
+    public int getLayerId() {
+        return mLayerId;
+    }
+
+    /** The UID of the package that owns the layer using picture processing. */
+    public int getOwnerUid() {
+        return mOwnerUid;
+    }
+
+    /** A handle that indicates which picture profile has configured the picture processing. */
+    public @NonNull PictureProfileHandle getPictureProfileHandle() {
+        return mPictureProfileHandle;
+    }
+}
diff --git a/core/java/android/view/SurfaceControlActivePictureListener.java b/core/java/android/view/SurfaceControlActivePictureListener.java
new file mode 100644
index 0000000..d7c5374
--- /dev/null
+++ b/core/java/android/view/SurfaceControlActivePictureListener.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.RequiresPermission;
+
+import libcore.util.NativeAllocationRegistry;
+
+/**
+ * Allows for the monitoring of visible layers that are using picture processing.
+ * @hide
+ */
+public abstract class SurfaceControlActivePictureListener {
+    private static final NativeAllocationRegistry sRegistry =
+            NativeAllocationRegistry.createMalloced(
+                    SurfaceControlActivePictureListener.class.getClassLoader(),
+                    nativeGetDestructor());
+
+    /**
+      * Callback when there are changes in the visible layers that are using picture processing.
+      *
+      * @param activePictures The visible layers that are using picture processing.
+      */
+    public abstract void onActivePicturesChanged(SurfaceControlActivePicture[] activePictures);
+
+    /**
+     * Start listening to changes in active pictures.
+     */
+    @RequiresPermission(android.Manifest.permission.OBSERVE_PICTURE_PROFILES)
+    public void startListening() {
+        synchronized (this) {
+            long nativePtr = nativeMakeAndStartListening();
+            mDestructor = sRegistry.registerNativeAllocation(this, nativePtr);
+        }
+    }
+
+    /**
+     * Stop listening to changes in active pictures.
+     */
+    @RequiresPermission(android.Manifest.permission.OBSERVE_PICTURE_PROFILES)
+    public void stopListening() {
+        final Runnable destructor;
+        synchronized (this) {
+            destructor = mDestructor;
+        }
+        if (destructor != null) {
+            destructor.run();
+        }
+    }
+
+    private native long nativeMakeAndStartListening();
+    private static native long nativeGetDestructor();
+
+    private Runnable mDestructor;
+}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 4df7649..b0051ce 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -932,7 +932,8 @@
 
     /**
      * Sets the desired amount of HDR headroom to be used when HDR content is presented on this
-     * SurfaceView.
+     * SurfaceView. This is expressed as the ratio of maximum HDR white point over the SDR
+     * white point, not as absolute nits.
      *
      * <p>By default the system will choose an amount of HDR headroom that is appropriate
      * for the underlying device capabilities & bit-depth of the panel. However, for some types
@@ -946,6 +947,10 @@
      * See {@link Display#getHdrSdrRatio()} for more information as well as how to query the
      * current value.</p>
      *
+     * <p>Note: This API operates independently of both the
+     * {@link Window#setColorMode Widow color mode} and the
+     * {@link Window#setDesiredHdrHeadroom Window desiredHdrHeadroom}</p>
+     *
      * @param desiredHeadroom The amount of HDR headroom that is desired. Must be >= 1.0 (no HDR)
      *                        and <= 10,000.0. Passing 0.0 will reset to the default, automatically
      *                        chosen value.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 4a9916c..949b667 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -20,6 +20,7 @@
 import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
 import static android.view.flags.Flags.FLAG_TOOLKIT_VIEWGROUP_SET_REQUESTED_FRAME_RATE_API;
 import static android.view.flags.Flags.toolkitViewgroupSetRequestedFrameRateApi;
+import static android.view.flags.Flags.scrollCaptureTargetZOrderFix;
 
 import android.animation.LayoutTransition;
 import android.annotation.CallSuper;
@@ -7657,6 +7658,11 @@
             @NonNull Rect localVisibleRect, @NonNull Point windowOffset,
             @NonNull Consumer<ScrollCaptureTarget> targets) {
 
+        // Only visible views can be captured.
+        if (getVisibility() != View.VISIBLE) {
+            return;
+        }
+
         if (getClipToPadding() && !localVisibleRect.intersect(mPaddingLeft, mPaddingTop,
                     (mRight - mLeft)  - mPaddingRight, (mBottom - mTop) - mPaddingBottom)) {
             return;
@@ -7665,19 +7671,39 @@
         // Dispatch to self first.
         super.dispatchScrollCaptureSearch(localVisibleRect, windowOffset, targets);
 
+        final int childrenCount = mChildrenCount;
+        if (childrenCount == 0) {
+            return;
+        }
+
         // Skip children if descendants excluded.
         if ((getScrollCaptureHint() & SCROLL_CAPTURE_HINT_EXCLUDE_DESCENDANTS) != 0) {
             return;
         }
-
         final Rect tmpRect = getTempRect();
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = getChildAt(i);
+
+        ArrayList<View> preorderedList = null;
+        boolean customOrder = false;
+        if (scrollCaptureTargetZOrderFix()) {
+            preorderedList = buildOrderedChildList();
+            customOrder = preorderedList == null && isChildrenDrawingOrderEnabled();
+        }
+        final View[] children = mChildren;
+        for (int i = 0; i < childrenCount; i++) {
+            View child;
+            if (scrollCaptureTargetZOrderFix()) {
+                // Traverse children in the same order they will be drawn (honors Z if set)
+                final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+                child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
+            } else {
+                child = children[i];
+            }
+
             // Only visible views can be captured.
             if (child.getVisibility() != View.VISIBLE) {
                 continue;
             }
+
             // Offset the given rectangle (in parent's local coordinates) into child's coordinate
             // space and clip the result to the child View's bounds, padding and clipRect as needed.
             // If the resulting rectangle is not empty, the request is forwarded to the child.
@@ -7706,6 +7732,9 @@
                 child.dispatchScrollCaptureSearch(tmpRect, childWindowOffset, targets);
             }
         }
+        if (preorderedList != null) {
+            preorderedList.clear();
+        }
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 19d3dc4..a0feccd 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -110,7 +110,6 @@
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
-import static android.view.accessibility.Flags.fixMergedContentChangeEventV2;
 import static android.view.accessibility.Flags.forceInvertColor;
 import static android.view.accessibility.Flags.reduceWindowContentChangedEventThrottle;
 import static android.view.flags.Flags.addSchandleToVriSurface;
@@ -1237,6 +1236,8 @@
     private @ActivityInfo.ColorMode int mCurrentColorMode = ActivityInfo.COLOR_MODE_DEFAULT;
     private long mColorModeLastSetMillis = -1;
 
+    private final boolean mIsSubscribeGranularDisplayEventsEnabled;
+
     public ViewRootImpl(Context context, Display display) {
         this(context, display, WindowManagerGlobal.getWindowSession(), new WindowLayout());
     }
@@ -1334,6 +1335,8 @@
         // Disable DRAW_WAKE_LOCK starting U.
         mDisableDrawWakeLock =
                 CompatChanges.isChangeEnabled(DISABLE_DRAW_WAKE_LOCK) && disableDrawWakeLock();
+        mIsSubscribeGranularDisplayEventsEnabled =
+                com.android.server.display.feature.flags.Flags.subscribeGranularDisplayEvents();
     }
 
     public static void addFirstDrawHandler(Runnable callback) {
@@ -1811,14 +1814,22 @@
                 mAccessibilityInteractionConnectionManager, mHandler);
         mAccessibilityManager.addHighContrastTextStateChangeListener(
                 mExecutor, mHighContrastTextManager);
+
+
+        long eventsToBeRegistered =
+                (mIsSubscribeGranularDisplayEventsEnabled)
+                ? DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
+                        | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_STATE
+                        | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED
+                : DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
+                        | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
+                        | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED;
         DisplayManagerGlobal
                 .getInstance()
                 .registerDisplayListener(
                         mDisplayListener,
                         mHandler,
-                        DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
-                        | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
-                        | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED,
+                        eventsToBeRegistered,
                         mBasePackageName);
 
         if (forceInvertColor()) {
@@ -2515,12 +2526,16 @@
     @VisibleForTesting
     public void notifyInsetsAnimationRunningStateChanged(boolean running) {
         if (sToolkitSetFrameRateReadOnlyFlagValue) {
-            mInsetsAnimationRunning = running;
             if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                 Trace.instant(Trace.TRACE_TAG_VIEW,
                         TextUtils.formatSimple("notifyInsetsAnimationRunningStateChanged(%s)",
                         Boolean.toString(running)));
             }
+            mInsetsAnimationRunning = running;
+            try {
+                mWindowSession.notifyInsetsAnimationRunningStateChanged(mWindow, running);
+            } catch (RemoteException e) {
+            }
         }
     }
 
@@ -8873,11 +8888,6 @@
 
         SyntheticTouchNavigationHandler() {
             super(true);
-            int gestureDetectorVelocityStrategy =
-                    android.companion.virtual.flags.Flags
-                            .impulseVelocityStrategyForTouchNavigation()
-                    ? VelocityTracker.VELOCITY_TRACKER_STRATEGY_IMPULSE
-                    : VelocityTracker.VELOCITY_TRACKER_STRATEGY_DEFAULT;
             mGestureDetector = new GestureDetector(mContext,
                     new GestureDetector.OnGestureListener() {
                         @Override
@@ -8917,7 +8927,7 @@
                         }
                     },
                     /* handler= */ null,
-                    gestureDetectorVelocityStrategy);
+                    VelocityTracker.VELOCITY_TRACKER_STRATEGY_IMPULSE);
         }
 
         public void process(MotionEvent event) {
@@ -12290,31 +12300,20 @@
             }
 
             if (mSource != null) {
-                if (fixMergedContentChangeEventV2()) {
-                    View newSource = getCommonPredecessor(mSource, source);
-                    if (newSource != null) {
-                        newSource = newSource.getSelfOrParentImportantForA11y();
-                    }
-                    if (newSource == null) {
-                        // If there is no common predecessor, then mSource points to
-                        // a removed view, hence in this case always prefer the source.
-                        newSource = source;
-                    }
-
-                    mChangeTypes |= changeType;
-                    if (mSource != newSource) {
-                        mChangeTypes |= AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
-                        mSource = newSource;
-                    }
-                } else {
+                View newSource = getCommonPredecessor(mSource, source);
+                if (newSource != null) {
+                    newSource = newSource.getSelfOrParentImportantForA11y();
+                }
+                if (newSource == null) {
                     // If there is no common predecessor, then mSource points to
                     // a removed view, hence in this case always prefer the source.
-                    View predecessor = getCommonPredecessor(mSource, source);
-                    if (predecessor != null) {
-                        predecessor = predecessor.getSelfOrParentImportantForA11y();
-                    }
-                    mSource = (predecessor != null) ? predecessor : source;
-                    mChangeTypes |= changeType;
+                    newSource = source;
+                }
+
+                mChangeTypes |= changeType;
+                if (mSource != newSource) {
+                    mChangeTypes |= AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
+                    mSource = newSource;
                 }
 
                 final int performingAction = mAccessibilityManager.getPerformingAction();
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 381006c..3953334 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1334,6 +1334,9 @@
      * <p>The requested color mode is not guaranteed to be honored. Please refer to
      * {@link #getColorMode()} for more information.</p>
      *
+     * <p>Note: This does not impact SurfaceViews or SurfaceControls, as those have their own
+     * independent color mode and HDR parameters.</p>
+     *
      * @see #getColorMode()
      * @see Display#isWideColorGamut()
      * @see Configuration#isScreenWideColorGamut()
@@ -1361,6 +1364,9 @@
      * See {@link Display#getHdrSdrRatio()} for more information as well as how to query the
      * current value.</p>
      *
+     * <p>Note: This does not impact SurfaceViews or SurfaceControls, as those have their own
+     * independent desired HDR headroom and HDR capabilities.</p>
+     *
      * @param desiredHeadroom The amount of HDR headroom that is desired. Must be >= 1.0 (no HDR)
      *                        and <= 10,000.0. Passing 0.0 will reset to the default, automatically
      *                        chosen value.
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index b4b0687..1e8cad6 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1426,8 +1426,9 @@
             "android.window.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE";
 
     /**
-     * Activity-level {@link android.content.pm.PackageManager.Property PackageManager.Property}
-     * that specifies whether this activity can declare or request
+     * Application or Activity level
+     * {@link android.content.pm.PackageManager.Property PackageManager.Property}
+     * that specifies whether this package or activity can declare or request
      * {@link android.R.attr#screenOrientation fixed orientation},
      * {@link android.R.attr#minAspectRatio max aspect ratio},
      * {@link android.R.attr#maxAspectRatio min aspect ratio}
@@ -1438,6 +1439,13 @@
      *
      * <p><b>Syntax:</b>
      * <pre>
+     * &lt;application&gt;
+     *   &lt;property
+     *     android:name="android.window.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE"
+     *     android:value="false"/&gt;
+     * &lt;/application&gt;
+     * </pre>or
+     * <pre>
      * &lt;activity&gt;
      *   &lt;property
      *     android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY"
@@ -1446,7 +1454,7 @@
      * </pre>
      * @hide
      */
-    // TODO(b/357141415): Make this public API.
+    // TODO(b/357141415): Remove this from sdk 37
     String PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY =
             "android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY";
 
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 65e9930..72a595d 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -679,6 +679,11 @@
             @NonNull ImeTracker.Token statsToken) {
     }
 
+    @Override
+    public void notifyInsetsAnimationRunningStateChanged(IWindow window, boolean running) {
+        // NO-OP
+    }
+
     void setParentInterface(@Nullable ISurfaceControlViewHostParent parentInterface) {
         IBinder oldInterface = mParentInterface == null ? null : mParentInterface.asBinder();
         IBinder newInterface = parentInterface == null ? null : parentInterface.asBinder();
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 0dfaf41..88ccf88 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -959,6 +959,8 @@
                 CONTENT_CHANGE_TYPE_CONTENT_INVALID,
                 CONTENT_CHANGE_TYPE_ERROR,
                 CONTENT_CHANGE_TYPE_ENABLED,
+                CONTENT_CHANGE_TYPE_CHECKED,
+                CONTENT_CHANGE_TYPE_EXPANDED,
                 CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION,
             })
     public @interface ContentChangeTypes {}
@@ -1241,6 +1243,16 @@
             case CONTENT_CHANGE_TYPE_ERROR: return "CONTENT_CHANGE_TYPE_ERROR";
             case CONTENT_CHANGE_TYPE_ENABLED: return "CONTENT_CHANGE_TYPE_ENABLED";
             default: {
+                if (Flags.triStateChecked()) {
+                    if (type == CONTENT_CHANGE_TYPE_CHECKED) {
+                        return "CONTENT_CHANGE_TYPE_CHECKED";
+                    }
+                }
+                if (Flags.a11yExpansionStateApi()) {
+                    if (type == CONTENT_CHANGE_TYPE_EXPANDED) {
+                        return "CONTENT_CHANGE_TYPE_EXPANDED";
+                    }
+                }
                 if (Flags.supplementalDescription()) {
                     if (type == CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION) {
                         return "CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION";
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 0204517..df0c5a3 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -6551,16 +6551,24 @@
         /**
          * Range type: indeterminate.
          *
-         * A {@link RangeInfo} type used to represent a node which may typically expose range
-         * information but is presently in an indeterminate state, such as a {@link
-         * android.widget.ProgressBar} representing a loading operation of unknown duration.
          * When using this type, the {@code min}, {@code max}, and {@code current} values used to
-         * construct an instance may be ignored. It is recommended to use {@code Float.NaN} for
-         * these values.
+         * construct an instance may be ignored.
+         *
+         *  @see #INDETERMINATE
          */
         @FlaggedApi(Flags.FLAG_INDETERMINATE_RANGE_INFO)
         public static final int RANGE_TYPE_INDETERMINATE = 3;
 
+        /**
+         * A {@link RangeInfo} type used to represent a node which may typically expose range
+         * information but is presently in an indeterminate state, such as a {@link
+         * android.widget.ProgressBar} representing a loading operation of unknown duration.
+         */
+        @NonNull
+        @FlaggedApi(Flags.FLAG_INDETERMINATE_RANGE_INFO)
+        public static final RangeInfo INDETERMINATE = new RangeInfo(RANGE_TYPE_INDETERMINATE, 0.0f,
+                0.0f, 0.0f);
+
         private int mType;
         private float mMin;
         private float mMax;
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index 8a006fa..e60fc3a 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -99,16 +99,6 @@
 
 flag {
     namespace: "accessibility"
-    name: "fix_merged_content_change_event_v2"
-    description: "Fixes event type and source of content change event merged in ViewRootImpl"
-    bug: "277305460"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
-    namespace: "accessibility"
     name: "flash_notification_system_api"
     is_exported: true
     description: "Makes flash notification APIs as system APIs for calling from mainline module"
diff --git a/core/java/android/view/flags/scroll_capture.aconfig b/core/java/android/view/flags/scroll_capture.aconfig
new file mode 100644
index 0000000..fdf9c1e
--- /dev/null
+++ b/core/java/android/view/flags/scroll_capture.aconfig
@@ -0,0 +1,13 @@
+package: "android.view.flags"
+container: "system"
+
+flag {
+    name: "scroll_capture_target_z_order_fix"
+    namespace: "system_ui"
+    description: "Always prefer targets with higher z-order"
+    bug: "365969802"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
diff --git a/core/java/android/view/inputmethod/InputMethodSession.java b/core/java/android/view/inputmethod/InputMethodSession.java
index 4f48cb6..1806a83 100644
--- a/core/java/android/view/inputmethod/InputMethodSession.java
+++ b/core/java/android/view/inputmethod/InputMethodSession.java
@@ -16,6 +16,7 @@
 
 package android.view.inputmethod;
 
+import android.annotation.NonNull;
 import android.graphics.Rect;
 import android.inputmethodservice.InputMethodService;
 import android.os.Bundle;
@@ -125,6 +126,23 @@
     public void dispatchKeyEvent(int seq, KeyEvent event, EventCallback callback);
 
     /**
+     * Received by the IME before dispatch to {@link InputMethodService#onKeyDown(int, KeyEvent)}
+     * to let the system know if the {@link KeyEvent} needs to be verified that it originated from
+     * the system. {@link KeyEvent}s may originate from outside of the system and any sensitive keys
+     * should be marked for verification. One example of this could be using key shortcuts for
+     * switching to another IME.
+     *
+     * @param event the event that may need verification.
+     * @return {@code true} if {@link KeyEvent} should have its HMAC verified before dispatch,
+     * {@code false} otherwise.
+     *
+     * @hide
+     */
+    default boolean onShouldVerifyKeyEvent(@NonNull KeyEvent event) {
+        return false;
+    }
+
+    /**
      * This method is called when there is a track ball event.
      *
      * <p>
diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig
index deaf957..73abc47 100644
--- a/core/java/android/view/inputmethod/flags.aconfig
+++ b/core/java/android/view/inputmethod/flags.aconfig
@@ -184,3 +184,11 @@
   bug: "350047836"
   is_fixed_read_only: true
 }
+
+flag {
+  name: "verify_key_event"
+  namespace: "input_method"
+  description: "Verify KeyEvents in IME"
+  bug: "331730488"
+  is_fixed_read_only: true
+}
diff --git a/core/java/android/widget/Button.java b/core/java/android/widget/Button.java
index 98c00ac..0bf6380 100644
--- a/core/java/android/widget/Button.java
+++ b/core/java/android/widget/Button.java
@@ -16,17 +16,22 @@
 
 package android.widget;
 
-import static android.view.flags.Flags.enableArrowIconOnHoverWhenClickable;
 import static android.view.flags.Flags.FLAG_ENABLE_ARROW_ICON_ON_HOVER_WHEN_CLICKABLE;
+import static android.view.flags.Flags.enableArrowIconOnHoverWhenClickable;
 
 import android.annotation.FlaggedApi;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.util.AttributeSet;
 import android.view.InputDevice;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.PointerIcon;
 import android.widget.RemoteViews.RemoteView;
+import android.widget.flags.Flags;
 
 /**
  * A user interface element the user can tap or click to perform an action.
@@ -88,6 +93,12 @@
 @RemoteView
 public class Button extends TextView {
 
+    @ChangeId
+    @EnabledSince(targetSdkVersion = 36)
+    private static final long WEAR_MATERIAL3_BUTTON = 376561342L;
+
+    private static Boolean sUseWearMaterial3Style;
+
     /**
      * Simple constructor to use when creating a button from code.
      *
@@ -118,7 +129,18 @@
      * @see android.view.View#View(Context, AttributeSet)
      */
     public Button(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.buttonStyle);
+        // Starting sdk 36+, wear devices will use a specific material3
+        // design. The new design will be applied when all of following conditions are met:
+        // 1. app target sdk is 36 or above.
+        // 2. feature flag rolled-out.
+        // 3. device is a watch.
+        // getButtonDefaultStyleAttr and getButtonDefaultStyleRes works together to alter the UI
+        // while considering the conditions above.
+        // Their results are mutual exclusive. i.e. when conditions above are all true,
+        // getButtonDefaultStyleRes returns non-zero value(new wear material3), abd
+        // getButtonDefaultStyleAttr returns 0. Otherwise, getButtonDefaultStyleAttr returns system
+        // attr com.android.internal.R.attr.buttonStyle and getButtonDefaultStyleRes returns 0.
+        this(context, attrs, getButtonDefaultStyleAttr(context), getButtonDefaultStyleRes());
     }
 
     /**
@@ -189,4 +211,24 @@
         }
         return super.onResolvePointerIcon(event, pointerIndex);
     }
+
+    private static int getButtonDefaultStyleAttr(Context context) {
+        sUseWearMaterial3Style = useWearMaterial3Style(context);
+        if (sUseWearMaterial3Style) {
+            return 0;
+        }
+        return com.android.internal.R.attr.buttonStyle;
+    }
+
+    private static int getButtonDefaultStyleRes() {
+        if (sUseWearMaterial3Style != null && sUseWearMaterial3Style) {
+            return com.android.internal.R.style.Widget_DeviceDefault_Button_WearMaterial3;
+        }
+        return 0;
+    }
+
+    private static boolean useWearMaterial3Style(Context context) {
+        return Flags.useWearMaterial3Ui() && CompatChanges.isChangeEnabled(WEAR_MATERIAL3_BUTTON)
+                && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+    }
 }
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 6e43d0f..2a8a928 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import static android.view.accessibility.Flags.indeterminateRangeInfo;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -2364,15 +2366,22 @@
     public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfoInternal(info);
 
-        if (!isIndeterminate()) {
-            AccessibilityNodeInfo.RangeInfo rangeInfo = AccessibilityNodeInfo.RangeInfo.obtain(
+        AccessibilityNodeInfo.RangeInfo rangeInfo = null;
+        if (isIndeterminate()) {
+            if (indeterminateRangeInfo()) {
+                rangeInfo = AccessibilityNodeInfo.RangeInfo.INDETERMINATE;
+            }
+        }  else {
+            rangeInfo = new AccessibilityNodeInfo.RangeInfo(
                     AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_INT, getMin(), getMax(),
                     getProgress());
-            info.setRangeInfo(rangeInfo);
         }
 
-        // Only set the default state description when custom state descripton is null.
+        info.setRangeInfo(rangeInfo);
+
+        // Only set the default state description when custom state description is null.
         if (getStateDescription() == null) {
+            // TODO(b/380340432): Remove after accessibility services stop relying on this.
             if (isIndeterminate()) {
                 info.setStateDescription(getResources().getString(R.string.in_progress));
             } else {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 9b6311f..7e3b904 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -20,6 +20,7 @@
 import static android.appwidget.flags.Flags.FLAG_REMOTE_VIEWS_PROTO;
 import static android.appwidget.flags.Flags.drawDataParcel;
 import static android.appwidget.flags.Flags.remoteAdapterConversion;
+import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
 import static android.util.proto.ProtoInputStream.NO_MORE_FIELDS;
 import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
 
@@ -54,6 +55,10 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.ServiceConnection;
+import android.content.om.FabricatedOverlay;
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.content.om.OverlayManagerTransaction;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.ColorStateList;
@@ -1293,7 +1298,13 @@
 
         @Override
         public void visitUris(@NonNull Consumer<Uri> visitor) {
-            if (mIntentId != -1 || mItems == null) {
+            if (mItems == null) {
+                // Null item indicates adapter conversion took place, so the URIs in cached items
+                // need to be validated.
+                RemoteCollectionItems cachedItems = mCollectionCache.getItemsForId(mIntentId);
+                if (cachedItems != null) {
+                    cachedItems.visitUris(visitor);
+                }
                 return;
             }
 
@@ -1559,6 +1570,16 @@
             final Context context = ActivityThread.currentApplication();
 
             final CompletableFuture<RemoteCollectionItems> result = new CompletableFuture<>();
+            String contextPackageName = context.getPackageName();
+            ComponentName intentComponent = intent.getComponent();
+            if (contextPackageName != null
+                    && intentComponent != null
+                    && (!contextPackageName.equals(intentComponent.getPackageName()))) {
+                // We shouldn't allow for connections to other packages
+                result.complete(new RemoteCollectionItems.Builder().build());
+                return result;
+            }
+
             context.bindService(intent, Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
                     result.defaultExecutor(), new ServiceConnection() {
                         @Override
@@ -8468,8 +8489,11 @@
             }
             try {
                 LoadedApk.checkAndUpdateApkPaths(mApplication);
-                return context.createApplicationContext(mApplication,
+                Context applicationContext = context.createApplicationContext(mApplication,
                         Context.CONTEXT_RESTRICTED);
+                // Get the correct apk paths while maintaining the current context's configuration.
+                return applicationContext.createConfigurationContext(
+                        context.getResources().getConfiguration());
             } catch (NameNotFoundException e) {
                 Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found");
             }
@@ -8547,8 +8571,6 @@
     /**
      * Object allowing the modification of a context to overload the system's dynamic colors.
      *
-     * Only colors from {@link android.R.color#system_accent1_0} to
-     * {@link android.R.color#system_neutral2_1000} can be overloaded.
      * @hide
      */
     public static final class ColorResources {
@@ -8559,6 +8581,9 @@
         // Size, in bytes, of an entry in the array of colors in an ARSC file.
         private static final int ARSC_ENTRY_SIZE = 16;
 
+        private static final String OVERLAY_NAME = "remote_views_color_resources";
+        private static final String OVERLAY_TARGET_PACKAGE_NAME = "android";
+
         private final ResourcesLoader mLoader;
         private final SparseIntArray mColorMapping;
 
@@ -8629,7 +8654,11 @@
         }
 
         /**
-         *  Adds a resource loader for theme colors to the given context.
+         *  Adds a resource loader for theme colors to the given context. The loader is created
+         *  based on resource files created at build time.
+         *
+         * <p>Only colors from {@link android.R.color#system_accent1_0} to
+         * {@link android.R.color#system_error_1000} can be overloaded.</p>
          *
          * @param context Context of the view hosting the widget.
          * @param colorMapping Mapping of resources to color values.
@@ -8667,6 +8696,57 @@
             }
             return null;
         }
+
+        /**
+         *  Adds a resource loader for theme colors to the given context. The loader is created
+         *  using fabricated runtime resource overlay (FRRO).
+         *
+         *  <p>The created class can overlay any color resources, private or public, at runtime.</p>
+         *
+         * @param context Context of the view hosting the widget.
+         * @param colorMapping Mapping of resources to color values.
+         *
+         * @hide
+         */
+        @Nullable
+        public static ColorResources createWithOverlay(Context context,
+                SparseIntArray colorMapping) {
+            try {
+                String owningPackage = context.getPackageName();
+                FabricatedOverlay overlay = new FabricatedOverlay.Builder(owningPackage,
+                        OVERLAY_NAME, OVERLAY_TARGET_PACKAGE_NAME).build();
+
+                for (int i = 0; i < colorMapping.size(); i++) {
+                    overlay.setResourceValue(
+                            context.getResources().getResourceName(colorMapping.keyAt(i)),
+                            TYPE_INT_COLOR_ARGB8, colorMapping.valueAt(i), null);
+                }
+                OverlayManager overlayManager = context.getSystemService(OverlayManager.class);
+                OverlayManagerTransaction.Builder transaction =
+                        new OverlayManagerTransaction.Builder()
+                                .registerFabricatedOverlay(overlay)
+                                .setSelfTargeting(true);
+                overlayManager.commit(transaction.build());
+
+                OverlayInfo overlayInfo =
+                        overlayManager.getOverlayInfosForTarget(OVERLAY_TARGET_PACKAGE_NAME)
+                                .stream()
+                                .filter(info -> TextUtils.equals(info.overlayName, OVERLAY_NAME)
+                                        && TextUtils.equals(info.packageName, owningPackage))
+                                .findFirst()
+                                .orElse(null);
+                if (overlayInfo == null) {
+                    Log.e(LOG_TAG, "Failed to get overlay info ", new Throwable());
+                    return null;
+                }
+                ResourcesLoader colorsLoader = new ResourcesLoader();
+                colorsLoader.addProvider(ResourcesProvider.loadOverlay(overlayInfo));
+                return new ColorResources(colorsLoader, colorMapping.clone());
+            } catch (Exception e) {
+                Log.e(LOG_TAG, "Failed to add theme color overlay into loader", e);
+            }
+            return null;
+        }
     }
 
     /**
@@ -9259,7 +9339,11 @@
         Set<Integer> bitmapIdSet = getBitmapIdsUsedByActions(new HashSet<>());
         int result = 0;
         for (int bitmapId: bitmapIdSet) {
-            result += mBitmapCache.getBitmapForId(bitmapId).getAllocationByteCount();
+            Bitmap currentBitmap = mBitmapCache.getBitmapForId(bitmapId);
+            if (currentBitmap == null) {
+                continue;
+            }
+            result += currentBitmap.getAllocationByteCount();
         }
 
         return result;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index cb70466..d7750bd 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -106,7 +106,6 @@
 import android.os.ParcelableParcel;
 import android.os.Process;
 import android.os.SystemClock;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.BoringLayout;
@@ -9230,179 +9229,174 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "TextView.onDraw");
-        try {
-            restartMarqueeIfNeeded();
+        restartMarqueeIfNeeded();
 
-            // Draw the background for this view
-            super.onDraw(canvas);
+        // Draw the background for this view
+        super.onDraw(canvas);
 
-            final int compoundPaddingLeft = getCompoundPaddingLeft();
-            final int compoundPaddingTop = getCompoundPaddingTop();
-            final int compoundPaddingRight = getCompoundPaddingRight();
-            final int compoundPaddingBottom = getCompoundPaddingBottom();
-            final int scrollX = mScrollX;
-            final int scrollY = mScrollY;
-            final int right = mRight;
-            final int left = mLeft;
-            final int bottom = mBottom;
-            final int top = mTop;
-            final boolean isLayoutRtl = isLayoutRtl();
-            final int offset = getHorizontalOffsetForDrawables();
-            final int leftOffset = isLayoutRtl ? 0 : offset;
-            final int rightOffset = isLayoutRtl ? offset : 0;
+        final int compoundPaddingLeft = getCompoundPaddingLeft();
+        final int compoundPaddingTop = getCompoundPaddingTop();
+        final int compoundPaddingRight = getCompoundPaddingRight();
+        final int compoundPaddingBottom = getCompoundPaddingBottom();
+        final int scrollX = mScrollX;
+        final int scrollY = mScrollY;
+        final int right = mRight;
+        final int left = mLeft;
+        final int bottom = mBottom;
+        final int top = mTop;
+        final boolean isLayoutRtl = isLayoutRtl();
+        final int offset = getHorizontalOffsetForDrawables();
+        final int leftOffset = isLayoutRtl ? 0 : offset;
+        final int rightOffset = isLayoutRtl ? offset : 0;
 
-            final Drawables dr = mDrawables;
-            if (dr != null) {
-                /*
-                 * Compound, not extended, because the icon is not clipped
-                 * if the text height is smaller.
-                 */
+        final Drawables dr = mDrawables;
+        if (dr != null) {
+            /*
+             * Compound, not extended, because the icon is not clipped
+             * if the text height is smaller.
+             */
 
-                int vspace = bottom - top - compoundPaddingBottom - compoundPaddingTop;
-                int hspace = right - left - compoundPaddingRight - compoundPaddingLeft;
+            int vspace = bottom - top - compoundPaddingBottom - compoundPaddingTop;
+            int hspace = right - left - compoundPaddingRight - compoundPaddingLeft;
 
-                // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
-                // Make sure to update invalidateDrawable() when changing this code.
-                if (dr.mShowing[Drawables.LEFT] != null) {
-                    canvas.save();
-                    canvas.translate(scrollX + mPaddingLeft + leftOffset,
-                            scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightLeft) / 2);
-                    dr.mShowing[Drawables.LEFT].draw(canvas);
-                    canvas.restore();
-                }
-
-                // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
-                // Make sure to update invalidateDrawable() when changing this code.
-                if (dr.mShowing[Drawables.RIGHT] != null) {
-                    canvas.save();
-                    canvas.translate(scrollX + right - left - mPaddingRight
-                                    - dr.mDrawableSizeRight - rightOffset,
-                            scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightRight) / 2);
-                    dr.mShowing[Drawables.RIGHT].draw(canvas);
-                    canvas.restore();
-                }
-
-                // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
-                // Make sure to update invalidateDrawable() when changing this code.
-                if (dr.mShowing[Drawables.TOP] != null) {
-                    canvas.save();
-                    canvas.translate(scrollX + compoundPaddingLeft
-                            + (hspace - dr.mDrawableWidthTop) / 2, scrollY + mPaddingTop);
-                    dr.mShowing[Drawables.TOP].draw(canvas);
-                    canvas.restore();
-                }
-
-                // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
-                // Make sure to update invalidateDrawable() when changing this code.
-                if (dr.mShowing[Drawables.BOTTOM] != null) {
-                    canvas.save();
-                    canvas.translate(scrollX + compoundPaddingLeft
-                                    + (hspace - dr.mDrawableWidthBottom) / 2,
-                            scrollY + bottom - top - mPaddingBottom - dr.mDrawableSizeBottom);
-                    dr.mShowing[Drawables.BOTTOM].draw(canvas);
-                    canvas.restore();
-                }
+            // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
+            // Make sure to update invalidateDrawable() when changing this code.
+            if (dr.mShowing[Drawables.LEFT] != null) {
+                canvas.save();
+                canvas.translate(scrollX + mPaddingLeft + leftOffset,
+                        scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightLeft) / 2);
+                dr.mShowing[Drawables.LEFT].draw(canvas);
+                canvas.restore();
             }
 
-            int color = mCurTextColor;
-
-            if (mLayout == null) {
-                assumeLayout();
+            // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
+            // Make sure to update invalidateDrawable() when changing this code.
+            if (dr.mShowing[Drawables.RIGHT] != null) {
+                canvas.save();
+                canvas.translate(scrollX + right - left - mPaddingRight
+                        - dr.mDrawableSizeRight - rightOffset,
+                         scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightRight) / 2);
+                dr.mShowing[Drawables.RIGHT].draw(canvas);
+                canvas.restore();
             }
 
-            Layout layout = mLayout;
-
-            if (mHint != null && !mHideHint && mText.length() == 0) {
-                if (mHintTextColor != null) {
-                    color = mCurHintTextColor;
-                }
-
-                layout = mHintLayout;
+            // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
+            // Make sure to update invalidateDrawable() when changing this code.
+            if (dr.mShowing[Drawables.TOP] != null) {
+                canvas.save();
+                canvas.translate(scrollX + compoundPaddingLeft
+                        + (hspace - dr.mDrawableWidthTop) / 2, scrollY + mPaddingTop);
+                dr.mShowing[Drawables.TOP].draw(canvas);
+                canvas.restore();
             }
 
-            mTextPaint.setColor(color);
-            mTextPaint.drawableState = getDrawableState();
-
-            canvas.save();
-            /*  Would be faster if we didn't have to do this. Can we chop the
-                (displayable) text so that we don't need to do this ever?
-            */
-
-            int extendedPaddingTop = getExtendedPaddingTop();
-            int extendedPaddingBottom = getExtendedPaddingBottom();
-
-            final int vspace = mBottom - mTop - compoundPaddingBottom - compoundPaddingTop;
-            final int maxScrollY = mLayout.getHeight() - vspace;
-
-            float clipLeft = compoundPaddingLeft + scrollX;
-            float clipTop = (scrollY == 0) ? 0 : extendedPaddingTop + scrollY;
-            float clipRight = right - left - getCompoundPaddingRight() + scrollX;
-            float clipBottom = bottom - top + scrollY
-                    - ((scrollY == maxScrollY) ? 0 : extendedPaddingBottom);
-
-            if (mShadowRadius != 0) {
-                clipLeft += Math.min(0, mShadowDx - mShadowRadius);
-                clipRight += Math.max(0, mShadowDx + mShadowRadius);
-
-                clipTop += Math.min(0, mShadowDy - mShadowRadius);
-                clipBottom += Math.max(0, mShadowDy + mShadowRadius);
+            // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
+            // Make sure to update invalidateDrawable() when changing this code.
+            if (dr.mShowing[Drawables.BOTTOM] != null) {
+                canvas.save();
+                canvas.translate(scrollX + compoundPaddingLeft
+                        + (hspace - dr.mDrawableWidthBottom) / 2,
+                         scrollY + bottom - top - mPaddingBottom - dr.mDrawableSizeBottom);
+                dr.mShowing[Drawables.BOTTOM].draw(canvas);
+                canvas.restore();
             }
-
-            canvas.clipRect(clipLeft, clipTop, clipRight, clipBottom);
-
-            int voffsetText = 0;
-            int voffsetCursor = 0;
-
-            // translate in by our padding
-            /* shortcircuit calling getVerticaOffset() */
-            if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) {
-                voffsetText = getVerticalOffset(false);
-                voffsetCursor = getVerticalOffset(true);
-            }
-            canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText);
-
-            final int layoutDirection = getLayoutDirection();
-            final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
-            if (isMarqueeFadeEnabled()) {
-                if (!mSingleLine && getLineCount() == 1 && canMarquee()
-                        && (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) {
-                    final int width = mRight - mLeft;
-                    final int padding = getCompoundPaddingLeft() + getCompoundPaddingRight();
-                    final float dx = mLayout.getLineRight(0) - (width - padding);
-                    canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
-                }
-
-                if (mMarquee != null && mMarquee.isRunning()) {
-                    final float dx = -mMarquee.getScroll();
-                    canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
-                }
-            }
-
-            final int cursorOffsetVertical = voffsetCursor - voffsetText;
-
-            maybeUpdateHighlightPaths();
-            // If there is a gesture preview highlight, then the selection or cursor is not drawn.
-            Path highlight = hasGesturePreviewHighlight() ? null : getUpdatedHighlightPath();
-            if (mEditor != null) {
-                mEditor.onDraw(canvas, layout, mHighlightPaths, mHighlightPaints, highlight,
-                        mHighlightPaint, cursorOffsetVertical);
-            } else {
-                layout.draw(canvas, mHighlightPaths, mHighlightPaints, highlight, mHighlightPaint,
-                        cursorOffsetVertical);
-            }
-
-            if (mMarquee != null && mMarquee.shouldDrawGhost()) {
-                final float dx = mMarquee.getGhostOffset();
-                canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
-                layout.draw(canvas, mHighlightPaths, mHighlightPaints, highlight, mHighlightPaint,
-                        cursorOffsetVertical);
-            }
-
-            canvas.restore();
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
         }
+
+        int color = mCurTextColor;
+
+        if (mLayout == null) {
+            assumeLayout();
+        }
+
+        Layout layout = mLayout;
+
+        if (mHint != null && !mHideHint && mText.length() == 0) {
+            if (mHintTextColor != null) {
+                color = mCurHintTextColor;
+            }
+
+            layout = mHintLayout;
+        }
+
+        mTextPaint.setColor(color);
+        mTextPaint.drawableState = getDrawableState();
+
+        canvas.save();
+        /*  Would be faster if we didn't have to do this. Can we chop the
+            (displayable) text so that we don't need to do this ever?
+        */
+
+        int extendedPaddingTop = getExtendedPaddingTop();
+        int extendedPaddingBottom = getExtendedPaddingBottom();
+
+        final int vspace = mBottom - mTop - compoundPaddingBottom - compoundPaddingTop;
+        final int maxScrollY = mLayout.getHeight() - vspace;
+
+        float clipLeft = compoundPaddingLeft + scrollX;
+        float clipTop = (scrollY == 0) ? 0 : extendedPaddingTop + scrollY;
+        float clipRight = right - left - getCompoundPaddingRight() + scrollX;
+        float clipBottom = bottom - top + scrollY
+                - ((scrollY == maxScrollY) ? 0 : extendedPaddingBottom);
+
+        if (mShadowRadius != 0) {
+            clipLeft += Math.min(0, mShadowDx - mShadowRadius);
+            clipRight += Math.max(0, mShadowDx + mShadowRadius);
+
+            clipTop += Math.min(0, mShadowDy - mShadowRadius);
+            clipBottom += Math.max(0, mShadowDy + mShadowRadius);
+        }
+
+        canvas.clipRect(clipLeft, clipTop, clipRight, clipBottom);
+
+        int voffsetText = 0;
+        int voffsetCursor = 0;
+
+        // translate in by our padding
+        /* shortcircuit calling getVerticaOffset() */
+        if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) {
+            voffsetText = getVerticalOffset(false);
+            voffsetCursor = getVerticalOffset(true);
+        }
+        canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText);
+
+        final int layoutDirection = getLayoutDirection();
+        final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
+        if (isMarqueeFadeEnabled()) {
+            if (!mSingleLine && getLineCount() == 1 && canMarquee()
+                    && (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) {
+                final int width = mRight - mLeft;
+                final int padding = getCompoundPaddingLeft() + getCompoundPaddingRight();
+                final float dx = mLayout.getLineRight(0) - (width - padding);
+                canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
+            }
+
+            if (mMarquee != null && mMarquee.isRunning()) {
+                final float dx = -mMarquee.getScroll();
+                canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
+            }
+        }
+
+        final int cursorOffsetVertical = voffsetCursor - voffsetText;
+
+        maybeUpdateHighlightPaths();
+        // If there is a gesture preview highlight, then the selection or cursor is not drawn.
+        Path highlight = hasGesturePreviewHighlight() ? null : getUpdatedHighlightPath();
+        if (mEditor != null) {
+            mEditor.onDraw(canvas, layout, mHighlightPaths, mHighlightPaints, highlight,
+                    mHighlightPaint, cursorOffsetVertical);
+        } else {
+            layout.draw(canvas, mHighlightPaths, mHighlightPaints, highlight, mHighlightPaint,
+                    cursorOffsetVertical);
+        }
+
+        if (mMarquee != null && mMarquee.shouldDrawGhost()) {
+            final float dx = mMarquee.getGhostOffset();
+            canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
+            layout.draw(canvas, mHighlightPaths, mHighlightPaints, highlight, mHighlightPaint,
+                    cursorOffsetVertical);
+        }
+
+        canvas.restore();
     }
 
     @Override
@@ -11260,201 +11254,192 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "TextView.onMeasure");
-        try {
-            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
 
-            int width;
-            int height;
+        int width;
+        int height;
 
-            BoringLayout.Metrics boring = UNKNOWN_BORING;
-            BoringLayout.Metrics hintBoring = UNKNOWN_BORING;
+        BoringLayout.Metrics boring = UNKNOWN_BORING;
+        BoringLayout.Metrics hintBoring = UNKNOWN_BORING;
 
-            if (mTextDir == null) {
-                mTextDir = getTextDirectionHeuristic();
+        if (mTextDir == null) {
+            mTextDir = getTextDirectionHeuristic();
+        }
+
+        int des = -1;
+        boolean fromexisting = false;
+        final float widthLimit = (widthMode == MeasureSpec.AT_MOST)
+                ?  (float) widthSize : Float.MAX_VALUE;
+
+        if (widthMode == MeasureSpec.EXACTLY) {
+            // Parent has told us how big to be. So be it.
+            width = widthSize;
+        } else {
+            if (mLayout != null && mEllipsize == null) {
+                des = desired(mLayout, mUseBoundsForWidth);
             }
 
-            int des = -1;
-            boolean fromexisting = false;
-            final float widthLimit = (widthMode == MeasureSpec.AT_MOST)
-                    ? (float) widthSize : Float.MAX_VALUE;
-
-            if (widthMode == MeasureSpec.EXACTLY) {
-                // Parent has told us how big to be. So be it.
-                width = widthSize;
+            if (des < 0) {
+                boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir,
+                        isFallbackLineSpacingForBoringLayout(), getResolvedMinimumFontMetrics(),
+                        mBoring);
+                if (boring != null) {
+                    mBoring = boring;
+                }
             } else {
-                if (mLayout != null && mEllipsize == null) {
-                    des = desired(mLayout, mUseBoundsForWidth);
-                }
+                fromexisting = true;
+            }
 
+            if (boring == null || boring == UNKNOWN_BORING) {
                 if (des < 0) {
-                    boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir,
-                            isFallbackLineSpacingForBoringLayout(), getResolvedMinimumFontMetrics(),
-                            mBoring);
-                    if (boring != null) {
-                        mBoring = boring;
-                    }
+                    des = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mTransformed, 0,
+                            mTransformed.length(), mTextPaint, mTextDir, widthLimit,
+                            mUseBoundsForWidth));
+                }
+                width = des;
+            } else {
+                if (mUseBoundsForWidth) {
+                    RectF bbox = boring.getDrawingBoundingBox();
+                    float rightMax = Math.max(bbox.right, boring.width);
+                    float leftMin = Math.min(bbox.left, 0);
+                    width = Math.max(boring.width, (int) Math.ceil(rightMax - leftMin));
                 } else {
-                    fromexisting = true;
+                    width = boring.width;
+                }
+            }
+
+            final Drawables dr = mDrawables;
+            if (dr != null) {
+                width = Math.max(width, dr.mDrawableWidthTop);
+                width = Math.max(width, dr.mDrawableWidthBottom);
+            }
+
+            if (mHint != null) {
+                int hintDes = -1;
+                int hintWidth;
+
+                if (mHintLayout != null && mEllipsize == null) {
+                    hintDes = desired(mHintLayout, mUseBoundsForWidth);
                 }
 
-                if (boring == null || boring == UNKNOWN_BORING) {
-                    if (des < 0) {
-                        des = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mTransformed, 0,
-                                mTransformed.length(), mTextPaint, mTextDir, widthLimit,
+                if (hintDes < 0) {
+                    hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir,
+                            isFallbackLineSpacingForBoringLayout(), getResolvedMinimumFontMetrics(),
+                            mHintBoring);
+                    if (hintBoring != null) {
+                        mHintBoring = hintBoring;
+                    }
+                }
+
+                if (hintBoring == null || hintBoring == UNKNOWN_BORING) {
+                    if (hintDes < 0) {
+                        hintDes = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mHint, 0,
+                                mHint.length(), mTextPaint, mTextDir, widthLimit,
                                 mUseBoundsForWidth));
                     }
-                    width = des;
+                    hintWidth = hintDes;
                 } else {
-                    if (mUseBoundsForWidth) {
-                        RectF bbox = boring.getDrawingBoundingBox();
-                        float rightMax = Math.max(bbox.right, boring.width);
-                        float leftMin = Math.min(bbox.left, 0);
-                        width = Math.max(boring.width, (int) Math.ceil(rightMax - leftMin));
-                    } else {
-                        width = boring.width;
-                    }
+                    hintWidth = hintBoring.width;
                 }
 
-                final Drawables dr = mDrawables;
-                if (dr != null) {
-                    width = Math.max(width, dr.mDrawableWidthTop);
-                    width = Math.max(width, dr.mDrawableWidthBottom);
-                }
-
-                if (mHint != null) {
-                    int hintDes = -1;
-                    int hintWidth;
-
-                    if (mHintLayout != null && mEllipsize == null) {
-                        hintDes = desired(mHintLayout, mUseBoundsForWidth);
-                    }
-
-                    if (hintDes < 0) {
-                        hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir,
-                                isFallbackLineSpacingForBoringLayout(),
-                                getResolvedMinimumFontMetrics(),
-                                mHintBoring);
-                        if (hintBoring != null) {
-                            mHintBoring = hintBoring;
-                        }
-                    }
-
-                    if (hintBoring == null || hintBoring == UNKNOWN_BORING) {
-                        if (hintDes < 0) {
-                            hintDes = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mHint, 0,
-                                    mHint.length(), mTextPaint, mTextDir, widthLimit,
-                                    mUseBoundsForWidth));
-                        }
-                        hintWidth = hintDes;
-                    } else {
-                        hintWidth = hintBoring.width;
-                    }
-
-                    if (hintWidth > width) {
-                        width = hintWidth;
-                    }
-                }
-
-                width += getCompoundPaddingLeft() + getCompoundPaddingRight();
-
-                if (mMaxWidthMode == EMS) {
-                    width = Math.min(width, mMaxWidth * getLineHeight());
-                } else {
-                    width = Math.min(width, mMaxWidth);
-                }
-
-                if (mMinWidthMode == EMS) {
-                    width = Math.max(width, mMinWidth * getLineHeight());
-                } else {
-                    width = Math.max(width, mMinWidth);
-                }
-
-                // Check against our minimum width
-                width = Math.max(width, getSuggestedMinimumWidth());
-
-                if (widthMode == MeasureSpec.AT_MOST) {
-                    width = Math.min(widthSize, width);
+                if (hintWidth > width) {
+                    width = hintWidth;
                 }
             }
 
-            int want = width - getCompoundPaddingLeft() - getCompoundPaddingRight();
-            int unpaddedWidth = want;
+            width += getCompoundPaddingLeft() + getCompoundPaddingRight();
 
-            if (mHorizontallyScrolling) want = VERY_WIDE;
-
-            int hintWant = want;
-            int hintWidth = (mHintLayout == null) ? hintWant : mHintLayout.getWidth();
-
-            if (mLayout == null) {
-                makeNewLayout(want, hintWant, boring, hintBoring,
-                        width - getCompoundPaddingLeft() - getCompoundPaddingRight(), false);
+            if (mMaxWidthMode == EMS) {
+                width = Math.min(width, mMaxWidth * getLineHeight());
             } else {
-                final boolean layoutChanged =
-                        (mLayout.getWidth() != want) || (hintWidth != hintWant)
-                                || (mLayout.getEllipsizedWidth()
-                                != width - getCompoundPaddingLeft() - getCompoundPaddingRight());
-
-                final boolean widthChanged = (mHint == null) && (mEllipsize == null)
-                        && (want > mLayout.getWidth())
-                        && (mLayout instanceof BoringLayout
-                        || (fromexisting && des >= 0 && des <= want));
-
-                final boolean maximumChanged =
-                        (mMaxMode != mOldMaxMode) || (mMaximum != mOldMaximum);
-
-                if (layoutChanged || maximumChanged) {
-                    if (!maximumChanged && widthChanged) {
-                        mLayout.increaseWidthTo(want);
-                    } else {
-                        makeNewLayout(want, hintWant, boring, hintBoring,
-                                width - getCompoundPaddingLeft() - getCompoundPaddingRight(),
-                                false);
-                    }
-                } else {
-                    // Nothing has changed
-                }
+                width = Math.min(width, mMaxWidth);
             }
 
-            if (heightMode == MeasureSpec.EXACTLY) {
-                // Parent has told us how big to be. So be it.
-                height = heightSize;
-                mDesiredHeightAtMeasure = -1;
+            if (mMinWidthMode == EMS) {
+                width = Math.max(width, mMinWidth * getLineHeight());
             } else {
-                int desired = getDesiredHeight();
-
-                height = desired;
-                mDesiredHeightAtMeasure = desired;
-
-                if (heightMode == MeasureSpec.AT_MOST) {
-                    height = Math.min(desired, heightSize);
-                }
+                width = Math.max(width, mMinWidth);
             }
 
-            int unpaddedHeight = height - getCompoundPaddingTop() - getCompoundPaddingBottom();
-            if (mMaxMode == LINES && mLayout.getLineCount() > mMaximum) {
-                unpaddedHeight = Math.min(unpaddedHeight, mLayout.getLineTop(mMaximum));
-            }
+            // Check against our minimum width
+            width = Math.max(width, getSuggestedMinimumWidth());
 
-            /*
-             * We didn't let makeNewLayout() register to bring the cursor into view,
-             * so do it here if there is any possibility that it is needed.
-             */
-            if (mMovement != null
-                    || mLayout.getWidth() > unpaddedWidth
-                    || mLayout.getHeight() > unpaddedHeight) {
-                registerForPreDraw();
-            } else {
-                scrollTo(0, 0);
+            if (widthMode == MeasureSpec.AT_MOST) {
+                width = Math.min(widthSize, width);
             }
-
-            setMeasuredDimension(width, height);
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
         }
+
+        int want = width - getCompoundPaddingLeft() - getCompoundPaddingRight();
+        int unpaddedWidth = want;
+
+        if (mHorizontallyScrolling) want = VERY_WIDE;
+
+        int hintWant = want;
+        int hintWidth = (mHintLayout == null) ? hintWant : mHintLayout.getWidth();
+
+        if (mLayout == null) {
+            makeNewLayout(want, hintWant, boring, hintBoring,
+                          width - getCompoundPaddingLeft() - getCompoundPaddingRight(), false);
+        } else {
+            final boolean layoutChanged = (mLayout.getWidth() != want) || (hintWidth != hintWant)
+                    || (mLayout.getEllipsizedWidth()
+                            != width - getCompoundPaddingLeft() - getCompoundPaddingRight());
+
+            final boolean widthChanged = (mHint == null) && (mEllipsize == null)
+                    && (want > mLayout.getWidth())
+                    && (mLayout instanceof BoringLayout
+                            || (fromexisting && des >= 0 && des <= want));
+
+            final boolean maximumChanged = (mMaxMode != mOldMaxMode) || (mMaximum != mOldMaximum);
+
+            if (layoutChanged || maximumChanged) {
+                if (!maximumChanged && widthChanged) {
+                    mLayout.increaseWidthTo(want);
+                } else {
+                    makeNewLayout(want, hintWant, boring, hintBoring,
+                            width - getCompoundPaddingLeft() - getCompoundPaddingRight(), false);
+                }
+            } else {
+                // Nothing has changed
+            }
+        }
+
+        if (heightMode == MeasureSpec.EXACTLY) {
+            // Parent has told us how big to be. So be it.
+            height = heightSize;
+            mDesiredHeightAtMeasure = -1;
+        } else {
+            int desired = getDesiredHeight();
+
+            height = desired;
+            mDesiredHeightAtMeasure = desired;
+
+            if (heightMode == MeasureSpec.AT_MOST) {
+                height = Math.min(desired, heightSize);
+            }
+        }
+
+        int unpaddedHeight = height - getCompoundPaddingTop() - getCompoundPaddingBottom();
+        if (mMaxMode == LINES && mLayout.getLineCount() > mMaximum) {
+            unpaddedHeight = Math.min(unpaddedHeight, mLayout.getLineTop(mMaximum));
+        }
+
+        /*
+         * We didn't let makeNewLayout() register to bring the cursor into view,
+         * so do it here if there is any possibility that it is needed.
+         */
+        if (mMovement != null
+                || mLayout.getWidth() > unpaddedWidth
+                || mLayout.getHeight() > unpaddedHeight) {
+            registerForPreDraw();
+        } else {
+            scrollTo(0, 0);
+        }
+
+        setMeasuredDimension(width, height);
     }
 
     /**
diff --git a/core/java/android/widget/flags/flags.aconfig b/core/java/android/widget/flags/flags.aconfig
index f0ed83b..d9dc36c 100644
--- a/core/java/android/widget/flags/flags.aconfig
+++ b/core/java/android/widget/flags/flags.aconfig
@@ -8,4 +8,12 @@
   metadata {
       purpose: PURPOSE_BUGFIX
     }
-}
\ No newline at end of file
+}
+
+flag {
+  name: "use_wear_material3_ui"
+  namespace: "wear_frameworks"
+  description: "Whether enable material3 style for wear frameworks' widgets."
+  is_exported: true
+  bug: "369480667"
+}
diff --git a/core/java/android/window/BackProgressAnimator.java b/core/java/android/window/BackProgressAnimator.java
index 16eb437..b535eff 100644
--- a/core/java/android/window/BackProgressAnimator.java
+++ b/core/java/android/window/BackProgressAnimator.java
@@ -67,7 +67,6 @@
             .setStiffness(SpringForce.STIFFNESS_MEDIUM)
             .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY);
     private final SpringForce mButtonSpringForce = new SpringForce()
-            .setStiffness(500)
             .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY);
     private final DynamicAnimation.OnAnimationEndListener mOnAnimationEndListener =
             (animation, canceled, value, velocity) -> {
@@ -157,6 +156,7 @@
                 /* frameTime */ System.nanoTime() / TimeUtils.NANOS_PER_MS);
         if (predictiveBackSwipeEdgeNoneApi()) {
             if (event.getSwipeEdge() == EDGE_NONE) {
+                mButtonSpringForce.setStiffness(SpringForce.STIFFNESS_LOW);
                 mSpring.setSpring(mButtonSpringForce);
                 mSpring.animateToFinalPosition(SCALE_FACTOR);
             } else {
@@ -228,6 +228,7 @@
      * @param finishCallback the callback to be invoked when the progress is reach to 0.
      */
     public void onBackCancelled(@NonNull Runnable finishCallback) {
+        mButtonSpringForce.setStiffness(SpringForce.STIFFNESS_MEDIUM);
         mBackCancelledFinishRunnable = finishCallback;
         mSpring.addEndListener(mOnAnimationEndListener);
         mSpring.animateToFinalPosition(0);
diff --git a/core/java/android/window/IBackAnimationHandoffHandler.aidl b/core/java/android/window/IBackAnimationHandoffHandler.aidl
new file mode 100644
index 0000000..577948d
--- /dev/null
+++ b/core/java/android/window/IBackAnimationHandoffHandler.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+
+ */
+
+package android.window;
+
+import android.os.Bundle;
+import android.view.RemoteAnimationTarget;
+import android.window.BackMotionEvent;
+import android.window.WindowAnimationState;
+
+
+/**
+ * Interface that allows an {@link OnBackInvokedCallback} object to hand off an animation to another
+ * handler.
+ *
+ * @hide
+ */
+oneway interface IBackAnimationHandoffHandler {
+    /**
+     * Triggers a handoff of the animation of the given targets and their associated states.
+     * Important: since this is a one-way method, the caller must first make sure that the animation
+     * can indeed be taken over.
+     */
+    oneway void handOffAnimation(in RemoteAnimationTarget[] targets,
+                    in WindowAnimationState[] states);
+}
diff --git a/core/java/android/window/IOnBackInvokedCallback.aidl b/core/java/android/window/IOnBackInvokedCallback.aidl
index e07d4a9..81ad4b7 100644
--- a/core/java/android/window/IOnBackInvokedCallback.aidl
+++ b/core/java/android/window/IOnBackInvokedCallback.aidl
@@ -18,6 +18,7 @@
 package android.window;
 
 import android.window.BackMotionEvent;
+import android.window.IBackAnimationHandoffHandler;
 
 /**
  * Interface that wraps a {@link OnBackInvokedCallback} object, to be stored in window manager
@@ -61,4 +62,9 @@
      * Sets whether the back gesture is past the trigger threshold.
      */
     void setTriggerBack(in boolean triggerBack);
+
+   /**
+    * Sets a {@link IBackAnimationHandoffHandler} that can be used to hand off the back animation.
+    */
+    void setHandoffHandler(in IBackAnimationHandoffHandler handoffHandler);
 }
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index c67b9ca..d478108 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -392,6 +392,11 @@
             // no-op
         }
 
+        @Override
+        public void setHandoffHandler(IBackAnimationHandoffHandler handoffHandler) {
+            // no-op
+        }
+
         private void maybeRunOnAnimationCallback(Consumer<OnBackAnimationCallback> block) {
             if (mCallback instanceof OnBackAnimationCallback) {
                 mHandler.post(() -> block.accept((OnBackAnimationCallback) mCallback));
diff --git a/core/java/android/window/WindowContext.java b/core/java/android/window/WindowContext.java
index fdaab66..2b370b9 100644
--- a/core/java/android/window/WindowContext.java
+++ b/core/java/android/window/WindowContext.java
@@ -94,6 +94,23 @@
         mController.attachToDisplayArea(mType, getDisplayId(), mOptions);
     }
 
+    /**
+     * Updates this context to a new displayId.
+     * <p>
+     * Note that this doesn't re-parent previously attached windows (they should be removed and
+     * re-added manually after this is called). Resources associated with this context will have
+     * the correct value and configuration for the new display after this is called.
+     */
+    @Override
+    public void updateDisplay(int displayId) {
+        if (displayId == getDisplayId()) {
+            return;
+        }
+        super.updateDisplay(displayId);
+        mController.detachIfNeeded();
+        mController.attachToDisplayArea(mType, displayId, mOptions);
+    }
+
     @Override
     public Object getSystemService(String name) {
         if (WINDOW_SERVICE.equals(name)) {
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 0ea4bb4..20e3f6b 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -546,6 +546,11 @@
         }
 
         @Override
+        public void setHandoffHandler(IBackAnimationHandoffHandler handoffHandler) {
+            // no-op
+        }
+
+        @Override
         public void onBackProgressed(BackMotionEvent backEvent) {
             // This is only called in some special cases such as when activity embedding is active
             // or when the activity is letterboxed. Otherwise mProgressAnimator#onBackProgressed is
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index 15adc80..6e76d8d 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -19,6 +19,8 @@
 import static android.window.ConfigurationHelper.isDifferentDisplay;
 import static android.window.ConfigurationHelper.shouldUpdateResources;
 
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
 import android.annotation.AnyThread;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
@@ -104,7 +106,7 @@
      * @param newConfig the updated {@link Configuration}
      * @param newDisplayId the updated {@link android.view.Display} ID
      */
-    @VisibleForTesting
+    @VisibleForTesting(visibility = PACKAGE)
     @MainThread
     public void onConfigurationChanged(Configuration newConfig, int newDisplayId) {
         onConfigurationChanged(newConfig, newDisplayId, true /* shouldReportConfigChange */);
@@ -113,7 +115,7 @@
     /**
      * Posts an {@link #onConfigurationChanged} to the main thread.
      */
-    @VisibleForTesting
+    @VisibleForTesting(visibility = PACKAGE)
     public void postOnConfigurationChanged(@NonNull Configuration newConfig, int newDisplayId) {
         mHandler.post(PooledLambda.obtainRunnable(this::onConfigurationChanged, newConfig,
                 newDisplayId, true /* shouldReportConfigChange */).recycleOnUse());
@@ -232,7 +234,7 @@
     /**
      * Called when the attached window is removed from the display.
      */
-    @VisibleForTesting
+    @VisibleForTesting(visibility = PACKAGE)
     @MainThread
     public void onWindowTokenRemoved() {
         final Context context = mContextRef.get();
diff --git a/core/java/android/window/WindowTokenClientController.java b/core/java/android/window/WindowTokenClientController.java
index abf7bb1..fa34595 100644
--- a/core/java/android/window/WindowTokenClientController.java
+++ b/core/java/android/window/WindowTokenClientController.java
@@ -28,7 +28,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.view.IWindowManager;
 import android.view.WindowManagerGlobal;
@@ -50,9 +50,9 @@
     private final IApplicationThread mAppThread = ActivityThread.currentActivityThread()
             .getApplicationThread();
 
-    /** Mapping from a client defined token to the {@link WindowTokenClient} it represents. */
+    /** Attached {@link WindowTokenClient}. */
     @GuardedBy("mLock")
-    private final ArrayMap<IBinder, WindowTokenClient> mWindowTokenClientMap = new ArrayMap<>();
+    private final ArraySet<WindowTokenClient> mWindowTokenClients = new ArraySet<>();
 
     /** Gets the singleton controller. */
     @NonNull
@@ -85,11 +85,15 @@
     /** Gets the {@link WindowContext} instance for the token. */
     @Nullable
     public Context getWindowContext(@NonNull IBinder clientToken) {
-        final WindowTokenClient windowTokenClient;
-        synchronized (mLock) {
-            windowTokenClient = mWindowTokenClientMap.get(clientToken);
+        if (!(clientToken instanceof WindowTokenClient windowTokenClient)) {
+            return null;
         }
-        return windowTokenClient != null ? windowTokenClient.getContext() : null;
+        synchronized (mLock) {
+            if (!mWindowTokenClients.contains(windowTokenClient)) {
+                return null;
+            }
+        }
+        return windowTokenClient.getContext();
     }
 
     /**
@@ -126,8 +130,14 @@
      */
     public boolean attachToDisplayContent(@NonNull WindowTokenClient client, int displayId) {
         final IWindowManager wms = getWindowManagerService();
-        // #createSystemUiContext may call this method before WindowManagerService is initialized.
         if (wms == null) {
+            // #createSystemUiContext may call this method before WindowManagerService is
+            // initialized.
+            // Regardless of whether or not it is ready, keep track of the token so that when WMS
+            // is initialized later, the SystemUiContext will start reporting from
+            // DisplayContent#registerSystemUiContext, and WindowTokenClientController can report
+            // the Configuration to the correct client.
+            recordWindowContextToken(client);
             return false;
         }
         final WindowContextInfo info;
@@ -170,12 +180,18 @@
     /** Detaches a {@link WindowTokenClient} from associated WindowContainer if there's one. */
     public void detachIfNeeded(@NonNull WindowTokenClient client) {
         synchronized (mLock) {
-            if (mWindowTokenClientMap.remove(client) == null) {
+            if (!mWindowTokenClients.remove(client)) {
                 return;
             }
         }
+        final IWindowManager wms = getWindowManagerService();
+        if (wms == null) {
+            // #createSystemUiContext may call this method before WindowManagerService is
+            // initialized. If it is GC'ed before WMS is initialized, skip calling into WMS.
+            return;
+        }
         try {
-            getWindowManagerService().detachWindowContext(client);
+            wms.detachWindowContext(client);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -183,9 +199,7 @@
 
     private void onWindowContextTokenAttached(@NonNull WindowTokenClient client,
             @NonNull WindowContextInfo info, boolean shouldReportConfigChange) {
-        synchronized (mLock) {
-            mWindowTokenClientMap.put(client, client);
-        }
+        recordWindowContextToken(client);
         if (shouldReportConfigChange) {
             // Should trigger an #onConfigurationChanged callback to the WindowContext. Post the
             // dispatch in the next loop to prevent the callback from being dispatched before
@@ -199,10 +213,16 @@
         }
     }
 
+    private void recordWindowContextToken(@NonNull WindowTokenClient client) {
+        synchronized (mLock) {
+            mWindowTokenClients.add(client);
+        }
+    }
+
     /** Called when receives {@link WindowContextInfoChangeItem}. */
     public void onWindowContextInfoChanged(@NonNull IBinder clientToken,
             @NonNull WindowContextInfo info) {
-        final WindowTokenClient windowTokenClient = getWindowTokenClient(clientToken);
+        final WindowTokenClient windowTokenClient = getWindowTokenClientIfAttached(clientToken);
         if (windowTokenClient != null) {
             windowTokenClient.onConfigurationChanged(info.getConfiguration(), info.getDisplayId());
         }
@@ -210,20 +230,23 @@
 
     /** Called when receives {@link WindowContextWindowRemovalItem}. */
     public void onWindowContextWindowRemoved(@NonNull IBinder clientToken) {
-        final WindowTokenClient windowTokenClient = getWindowTokenClient(clientToken);
+        final WindowTokenClient windowTokenClient = getWindowTokenClientIfAttached(clientToken);
         if (windowTokenClient != null) {
             windowTokenClient.onWindowTokenRemoved();
         }
     }
 
     @Nullable
-    private WindowTokenClient getWindowTokenClient(@NonNull IBinder clientToken) {
-        final WindowTokenClient windowTokenClient;
-        synchronized (mLock) {
-            windowTokenClient = mWindowTokenClientMap.get(clientToken);
+    private WindowTokenClient getWindowTokenClientIfAttached(@NonNull IBinder clientToken) {
+        if (!(clientToken instanceof WindowTokenClient windowTokenClient)) {
+            Log.e(TAG, "getWindowTokenClient failed for non-window token " + clientToken);
+            return null;
         }
-        if (windowTokenClient == null) {
-            Log.w(TAG, "Can't find attached WindowTokenClient for " + clientToken);
+        synchronized (mLock) {
+            if (!mWindowTokenClients.contains(windowTokenClient)) {
+                Log.w(TAG, "Can't find attached WindowTokenClient for " + clientToken);
+                return null;
+            }
         }
         return windowTokenClient;
     }
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index c7d5a9f..8019e67 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -242,6 +242,13 @@
 }
 
 flag {
+    name: "enable_desktop_windowing_app_handle_education_integration"
+    namespace: "lse_desktop_experience"
+    description: "Enables desktop windowing app handle education and integrates new APIs"
+    bug: "380272815"
+}
+
+flag {
     name: "enable_desktop_windowing_transitions"
     namespace: "lse_desktop_experience"
     description: "Enables desktop windowing transition & motion polish changes"
@@ -253,6 +260,13 @@
     namespace: "lse_desktop_experience"
     description: "Enables enter desktop windowing transition & motion polish changes"
     bug: "369763947"
+}
+
+flag {
+    name: "enable_desktop_windowing_enter_transition_bugfix"
+    namespace: "lse_desktop_experience"
+    description: "Enables enter desktop windowing transition & motion polish changes"
+    bug: "380224875"
     metadata {
         purpose: PURPOSE_BUGFIX
     }
@@ -263,6 +277,13 @@
     namespace: "lse_desktop_experience"
     description: "Enables exit desktop windowing transition & motion polish changes"
     bug: "353650462"
+}
+
+flag {
+    name: "enable_desktop_windowing_exit_transitions_bugfix"
+    namespace: "lse_desktop_experience"
+    description: "Enables exit desktop windowing transition & motion polish changes"
+    bug: "380224768"
     metadata {
         purpose: PURPOSE_BUGFIX
     }
@@ -349,6 +370,13 @@
     namespace: "lse_desktop_experience"
     description: "Enables custom transitions for alt-tab app launches in Desktop Mode."
     bug: "370735595"
+}
+
+flag {
+    name: "enable_desktop_app_launch_alttab_transitions_bugfix"
+    namespace: "lse_desktop_experience"
+    description: "Enables custom transitions for alt-tab app launches in Desktop Mode."
+    bug: "380225486"
     metadata {
         purpose: PURPOSE_BUGFIX
     }
@@ -359,6 +387,13 @@
     namespace: "lse_desktop_experience"
     description: "Enables custom transitions for app launches in Desktop Mode."
     bug: "375992828"
+}
+
+flag {
+    name: "enable_desktop_app_launch_transitions_bugfix"
+    namespace: "lse_desktop_experience"
+    description: "Enables custom transitions for app launches in Desktop Mode."
+    bug: "380224832"
     metadata {
         purpose: PURPOSE_BUGFIX
     }
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 86bbeb8..ebbe483 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -441,3 +441,11 @@
     description: "Enable Predictive Back Animation for 3-button-nav"
     bug: "373544911"
 }
+
+flag {
+    name: "predictive_back_default_enable_sdk_36"
+    namespace: "systemui"
+    description: "Enable Predictive Back by default with targetSdk>=36"
+    is_fixed_read_only: true
+    bug: "376407910"
+}
diff --git a/core/java/com/android/internal/content/om/OverlayConfig.java b/core/java/com/android/internal/content/om/OverlayConfig.java
index 07e178c..38593b4 100644
--- a/core/java/com/android/internal/content/om/OverlayConfig.java
+++ b/core/java/com/android/internal/content/om/OverlayConfig.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.pm.PackagePartitions;
+import android.content.res.AssetManager;
 import android.os.Build;
 import android.os.Trace;
 import android.util.ArrayMap;
@@ -533,7 +534,7 @@
      */
     @NonNull
     public String[] createImmutableFrameworkIdmapsInZygote() {
-        final String targetPath = "/system/framework/framework-res.apk";
+        final String targetPath = AssetManager.FRAMEWORK_APK_PATH;
         final ArrayList<String> idmapPaths = new ArrayList<>();
         final ArrayList<IdmapInvocation> idmapInvocations =
                 getImmutableFrameworkOverlayIdmapInvocations();
diff --git a/core/java/com/android/internal/content/om/OverlayManagerImpl.java b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
index c462449..fa5cf2a 100644
--- a/core/java/com/android/internal/content/om/OverlayManagerImpl.java
+++ b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
@@ -35,6 +35,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.parsing.FrameworkParsingPackageUtils;
+import android.content.res.AssetManager;
 import android.os.FabricatedOverlayInfo;
 import android.os.FabricatedOverlayInternal;
 import android.os.FabricatedOverlayInternalEntry;
@@ -60,8 +61,8 @@
 import java.util.Objects;
 
 /**
- * This class provides the functionalities of registering an overlay, unregistering an overlay, and
- * getting the list of overlays information.
+ * This class provides the functionalities for managing self-targeting overlays, including
+ * registering an overlay, unregistering an overlay, and getting the list of overlays information.
  */
 public class OverlayManagerImpl {
     private static final String TAG = "OverlayManagerImpl";
@@ -234,14 +235,17 @@
         Preconditions.checkArgument(!entryList.isEmpty(), "overlay entries shouldn't be empty");
         final String overlayName = checkOverlayNameValid(overlayInternal.overlayName);
         checkPackageName(overlayInternal.packageName);
-        checkPackageName(overlayInternal.targetPackageName);
-        Preconditions.checkStringNotEmpty(
-                overlayInternal.targetOverlayable,
-                "Target overlayable should be neither null nor empty string.");
+        Preconditions.checkStringNotEmpty(overlayInternal.targetPackageName);
 
         final ApplicationInfo applicationInfo = mContext.getApplicationInfo();
-        final String targetPackage = Preconditions.checkStringNotEmpty(
-                applicationInfo.getBaseCodePath());
+        String targetPackage = null;
+        if (TextUtils.equals(overlayInternal.targetPackageName, "android")) {
+            targetPackage = AssetManager.FRAMEWORK_APK_PATH;
+        } else {
+            targetPackage = Preconditions.checkStringNotEmpty(
+                    applicationInfo.getBaseCodePath());
+        }
+
         final Path frroPath = mBasePath.resolve(overlayName + FRRO_EXTENSION);
         final Path idmapPath = mBasePath.resolve(overlayName + IDMAP_EXTENSION);
 
diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
index ac4c066..5fbb92d 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
@@ -16,6 +16,7 @@
 
 package com.android.internal.inputmethod;
 
+import android.graphics.Region;
 import android.net.Uri;
 import android.view.inputmethod.ImeTracker;
 import android.view.inputmethod.InputMethodSubtype;
@@ -51,4 +52,5 @@
     void resetStylusHandwriting(int requestId);
     void switchKeyboardLayoutAsync(int direction);
     void setHandwritingSurfaceNotTouchable(boolean notTouchable);
+    void setHandwritingTouchableRegion(in Region region);
 }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index b009c99..36333a9 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -20,6 +20,7 @@
 import android.annotation.DrawableRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.graphics.Region;
 import android.inputmethodservice.InputMethodService.BackDispositionMode;
 import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.net.Uri;
@@ -159,6 +160,25 @@
         }
     }
 
+
+    /**
+     * Calls {@link IInputMethodPrivilegedOperations#setHandwritingTouchableRegion(Region)}.
+     *
+     * @param region {@link Region} to set handwritable.
+     */
+    @AnyThread
+    public void setHandwritingTouchableRegion(Region region) {
+        final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
+        if (ops == null) {
+            return;
+        }
+        try {
+            ops.setHandwritingTouchableRegion(region);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     /**
      * Calls {@link IInputMethodPrivilegedOperations#createInputContentUriToken(Uri, String,
      * AndroidFuture)}.
diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
index 1204ef3..fc41537 100644
--- a/core/java/com/android/internal/jank/Cuj.java
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -235,8 +235,19 @@
      */
     public static final int CUJ_DESKTOP_MODE_SNAP_RESIZE = 118;
 
+    /**
+     * Track unmaximize window interaction in desktop mode.
+     *
+     * <p> Tracking starts when the maximize button or option is clicked {@link
+     * com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel#onClick}
+     * and finishes when the animation finishes {@link
+     * com.android.wm.shell.windowdecor.ToggleResizeDesktopTaskTransitionHandler#startAnimation}
+     * </p>
+     */
+    public static final int CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW = 119;
+
     // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
-    @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_SNAP_RESIZE;
+    @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW;
 
     /** @hide */
     @IntDef({
@@ -346,7 +357,8 @@
             CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH,
             CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE,
             CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE,
-            CUJ_DESKTOP_MODE_SNAP_RESIZE
+            CUJ_DESKTOP_MODE_SNAP_RESIZE,
+            CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {}
@@ -467,6 +479,7 @@
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_SNAP_RESIZE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_SNAP_RESIZE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_UNMAXIMIZE_WINDOW;
     }
 
     private Cuj() {
@@ -699,6 +712,8 @@
                 return "DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE";
             case CUJ_DESKTOP_MODE_SNAP_RESIZE:
                 return "DESKTOP_MODE_SNAP_RESIZE";
+            case CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW:
+                return "DESKTOP_MODE_UNMAXIMIZE_WINDOW";
         }
         return "UNKNOWN";
     }
diff --git a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java
index 48d0d6c..5ec5762 100644
--- a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java
+++ b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java
@@ -392,6 +392,10 @@
     private int memtagMode;
     @ApplicationInfo.NativeHeapZeroInitialized
     private int nativeHeapZeroInitialized;
+
+    @ApplicationInfo.PageSizeAppCompatFlags private int mPageSizeAppCompatFlags =
+            ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED;
+
     @Nullable
     @DataClass.ParcelWith(Parcelling.BuiltIn.ForBoolean.class)
     private Boolean requestRawExternalStorageAccess;
@@ -1118,6 +1122,12 @@
         return nativeHeapZeroInitialized;
     }
 
+    @ApplicationInfo.PageSizeAppCompatFlags
+    @Override
+    public int getPageSizeAppCompatFlags() {
+        return mPageSizeAppCompatFlags;
+    }
+
     @Override
     public int getNetworkSecurityConfigResourceId() {
         return networkSecurityConfigRes;
@@ -2221,6 +2231,12 @@
     }
 
     @Override
+    public PackageImpl setPageSizeAppCompatFlags(@ApplicationInfo.PageSizeAppCompatFlags int flag) {
+        mPageSizeAppCompatFlags = flag;
+        return this;
+    }
+
+    @Override
     public PackageImpl setNetworkSecurityConfigResourceId(int value) {
         networkSecurityConfigRes = value;
         return this;
@@ -2703,6 +2719,7 @@
             appInfo.setKnownActivityEmbeddingCerts(mKnownActivityEmbeddingCerts);
         }
         appInfo.allowCrossUidActivitySwitchFromBelow = mAllowCrossUidActivitySwitchFromBelow;
+        appInfo.setPageSizeAppCompatFlags(mPageSizeAppCompatFlags);
 
         return appInfo;
     }
@@ -3305,6 +3322,7 @@
         dest.writeInt(this.mIntentMatchingFlags);
         dest.writeIntArray(this.mAlternateLauncherIconResIds);
         dest.writeIntArray(this.mAlternateLauncherLabelResIds);
+        dest.writeInt(this.mPageSizeAppCompatFlags);
     }
 
     private void writeFeatureFlagState(@NonNull Parcel dest) {
@@ -3499,6 +3517,7 @@
         this.mIntentMatchingFlags = in.readInt();
         this.mAlternateLauncherIconResIds = in.createIntArray();
         this.mAlternateLauncherLabelResIds = in.createIntArray();
+        this.mPageSizeAppCompatFlags = in.readInt();
 
         assignDerivedFields();
         assignDerivedFields2();
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java
index 67b985a..5062d58 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java
@@ -31,7 +31,6 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 
-import com.android.internal.R;
 import com.android.internal.pm.parsing.pkg.ParsedPackage;
 import com.android.internal.pm.pkg.component.ParsedActivity;
 import com.android.internal.pm.pkg.component.ParsedApexSystemService;
@@ -280,6 +279,9 @@
     ParsingPackage setNativeHeapZeroInitialized(
             @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized);
 
+    /** Manifest option pageSizeCompat will populate this field */
+    ParsingPackage setPageSizeAppCompatFlags(@ApplicationInfo.PageSizeAppCompatFlags int value);
+
     ParsingPackage setRequestRawExternalStorageAccess(
             @Nullable Boolean requestRawExternalStorageAccess);
 
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index 8a6e6be..0f93e6e 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -541,6 +541,7 @@
 
         pkg.setGwpAsanMode(-1);
         pkg.setMemtagMode(-1);
+        pkg.setPageSizeAppCompatFlags(ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED);
 
         afterParseBaseApplication(pkg);
 
@@ -2182,6 +2183,13 @@
 
             pkg.setGwpAsanMode(sa.getInt(R.styleable.AndroidManifestApplication_gwpAsanMode, -1));
             pkg.setMemtagMode(sa.getInt(R.styleable.AndroidManifestApplication_memtagMode, -1));
+
+            if (Flags.appCompatOption16kb()) {
+                pkg.setPageSizeAppCompatFlags(
+                        sa.getInt(R.styleable.AndroidManifestApplication_pageSizeCompat,
+                                ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED));
+            }
+
             if (sa.hasValue(R.styleable.AndroidManifestApplication_nativeHeapZeroInitialized)) {
                 final boolean v = sa.getBoolean(
                         R.styleable.AndroidManifestApplication_nativeHeapZeroInitialized, false);
@@ -2377,6 +2385,7 @@
      * Flags are separated by type and by default value. They are sorted alphabetically within each
      * section.
      */
+    @SuppressWarnings("AndroidFrameworkCompatChange")
     private void parseBaseAppBasicFlags(ParsingPackage pkg, TypedArray sa) {
         int targetSdk = pkg.getTargetSdkVersion();
         //@formatter:off
@@ -2414,12 +2423,20 @@
                 .setResetEnabledSettingsOnAppDataCleared(bool(false,
                         R.styleable.AndroidManifestApplication_resetEnabledSettingsOnAppDataCleared,
                         sa))
-                .setOnBackInvokedCallbackEnabled(bool(false, R.styleable.AndroidManifestApplication_enableOnBackInvokedCallback, sa))
                 // targetSdkVersion gated
                 .setAllowAudioPlaybackCapture(bool(targetSdk >= Build.VERSION_CODES.Q, R.styleable.AndroidManifestApplication_allowAudioPlaybackCapture, sa))
                 .setHardwareAccelerated(bool(targetSdk >= Build.VERSION_CODES.ICE_CREAM_SANDWICH, R.styleable.AndroidManifestApplication_hardwareAccelerated, sa))
                 .setRequestLegacyExternalStorage(bool(targetSdk < Build.VERSION_CODES.Q, R.styleable.AndroidManifestApplication_requestLegacyExternalStorage, sa))
                 .setCleartextTrafficAllowed(bool(targetSdk < Build.VERSION_CODES.P, R.styleable.AndroidManifestApplication_usesCleartextTraffic, sa))
+                // CompatChange.isChangeEnabled() can't be used here because this is called during
+                // PackageManagerService initialization. PlatformCompat can't be used because this
+                // code is not guaranteed to be called from the system_server process. Therefore
+                // accessing Build.VERSION_CODES directly and suppressing
+                // AndroidFrameworkCompatChange warning
+                .setOnBackInvokedCallbackEnabled(bool(
+                        com.android.window.flags.Flags.predictiveBackDefaultEnableSdk36()
+                            && targetSdk > Build.VERSION_CODES.VANILLA_ICE_CREAM,
+                        R.styleable.AndroidManifestApplication_enableOnBackInvokedCallback, sa))
                 // Ints Default 0
                 .setUiOptions(anInt(R.styleable.AndroidManifestApplication_uiOptions, sa))
                 // Ints
diff --git a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
index 8771cde..be3bbb2 100644
--- a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
@@ -70,7 +70,7 @@
     private final TraceBuffer mBuffer;
     private final LegacyProtoLogViewerConfigReader mViewerConfig;
     private final Map<String, IProtoLogGroup> mLogGroups = new TreeMap<>();
-    private final Runnable mCacheUpdater;
+    private final ProtoLogCacheUpdater mCacheUpdater;
     private final int mPerChunkSize;
 
     private boolean mProtoLogEnabled;
@@ -78,14 +78,14 @@
     private final Object mProtoLogEnabledLock = new Object();
 
     public LegacyProtoLogImpl(String outputFile, String viewerConfigFilename,
-            Runnable cacheUpdater) {
+            ProtoLogCacheUpdater cacheUpdater) {
         this(new File(outputFile), viewerConfigFilename, BUFFER_CAPACITY,
                 new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, cacheUpdater);
     }
 
     public LegacyProtoLogImpl(File file, String viewerConfigFilename, int bufferCapacity,
             LegacyProtoLogViewerConfigReader viewerConfig, int perChunkSize,
-            Runnable cacheUpdater) {
+            ProtoLogCacheUpdater cacheUpdater) {
         mLogFile = file;
         mBuffer = new TraceBuffer(bufferCapacity);
         mLegacyViewerConfigFilename = viewerConfigFilename;
@@ -298,7 +298,7 @@
             }
         }
 
-        mCacheUpdater.run();
+        mCacheUpdater.update(this);
         return 0;
     }
 
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index eb682df..05a33fe 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -51,7 +51,6 @@
 import android.os.ShellCommand;
 import android.os.SystemClock;
 import android.text.TextUtils;
-import android.tracing.perfetto.DataSourceParams;
 import android.tracing.perfetto.InitArguments;
 import android.tracing.perfetto.Producer;
 import android.tracing.perfetto.TracingContext;
@@ -86,7 +85,6 @@
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.stream.Stream;
 
 /**
  * A service for the ProtoLog logging system.
@@ -98,10 +96,12 @@
 
     @NonNull
     protected final ProtoLogDataSource mDataSource;
+    @Nullable
+    protected final IProtoLogConfigurationService mConfigurationService;
     @NonNull
     protected final TreeMap<String, IProtoLogGroup> mLogGroups = new TreeMap<>();
     @NonNull
-    private final Runnable mCacheUpdater;
+    private final ProtoLogCacheUpdater mCacheUpdater;
 
     @NonNull
     private final int[] mDefaultLogLevelCounts = new int[LogLevel.values().length];
@@ -117,10 +117,10 @@
     private boolean mLogcatReady = false;
 
     protected PerfettoProtoLogImpl(
-            @NonNull Runnable cacheUpdater,
+            @NonNull ProtoLogDataSource dataSource,
+            @NonNull ProtoLogCacheUpdater cacheUpdater,
             @NonNull IProtoLogGroup[] groups) throws ServiceManager.ServiceNotFoundException {
-        this(cacheUpdater, groups,
-                ProtoLogDataSource::new,
+        this(dataSource, cacheUpdater, groups,
                 android.tracing.Flags.clientSideProtoLogging() ?
                     IProtoLogConfigurationService.Stub.asInterface(
                         ServiceManager.getServiceOrThrow(PROTOLOG_CONFIGURATION_SERVICE)
@@ -129,47 +129,60 @@
     }
 
     protected PerfettoProtoLogImpl(
-            @NonNull Runnable cacheUpdater,
+            @NonNull ProtoLogDataSource dataSource,
+            @NonNull ProtoLogCacheUpdater cacheUpdater,
             @NonNull IProtoLogGroup[] groups,
-            @NonNull ProtoLogDataSourceBuilder dataSourceBuilder,
             @Nullable IProtoLogConfigurationService configurationService) {
-        mDataSource = dataSourceBuilder.build(
-                this::onTracingInstanceStart,
-                this::onTracingFlush,
-                this::onTracingInstanceStop);
-        Producer.init(InitArguments.DEFAULTS);
-        DataSourceParams params =
-                new DataSourceParams.Builder()
-                        .setBufferExhaustedPolicy(
-                                DataSourceParams
-                                        .PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
-                        .build();
-        // NOTE: Registering that datasource is an async operation, so there may be no data traced
-        // for some messages logged right after the construction of this class.
-        mDataSource.register(params);
-
-        this.mCacheUpdater = cacheUpdater;
+        mDataSource = dataSource;
+        mCacheUpdater = cacheUpdater;
+        mConfigurationService = configurationService;
 
         registerGroupsLocally(groups);
+    }
+
+    /**
+     * To be called to enable the ProtoLogImpl to start tracing to ProtoLog and register with all
+     * the expected ProtoLog components.
+     */
+    public void enable() {
+        Producer.init(InitArguments.DEFAULTS);
 
         if (android.tracing.Flags.clientSideProtoLogging()) {
-            Objects.requireNonNull(configurationService,
-                    "A null ProtoLog Configuration Service was provided!");
-
-            try {
-                var args = createConfigurationServiceRegisterClientArgs();
-
-                final var groupArgs = Stream.of(groups)
-                        .map(group -> new RegisterClientArgs
-                                .GroupConfig(group.name(), group.isLogToLogcat()))
-                        .toArray(RegisterClientArgs.GroupConfig[]::new);
-                args.setGroups(groupArgs);
-
-                configurationService.registerClient(this, args);
-            } catch (RemoteException e) {
-                throw new RuntimeException("Failed to register ProtoLog client");
-            }
+            connectToConfigurationService();
         }
+
+        mDataSource.registerOnStartCallback(this::onTracingInstanceStart);
+        mDataSource.registerOnFlushCallback(this::onTracingFlush);
+        mDataSource.registerOnStopCallback(this::onTracingInstanceStop);
+    }
+
+    private void connectToConfigurationService() {
+        Objects.requireNonNull(mConfigurationService,
+                "A null ProtoLog Configuration Service was provided!");
+
+        try {
+            var args = createConfigurationServiceRegisterClientArgs();
+
+            final var groupArgs = mLogGroups.values().stream()
+                    .map(group -> new RegisterClientArgs
+                            .GroupConfig(group.name(), group.isLogToLogcat()))
+                    .toArray(RegisterClientArgs.GroupConfig[]::new);
+            args.setGroups(groupArgs);
+
+            mConfigurationService.registerClient(this, args);
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed to register ProtoLog client");
+        }
+    }
+
+    /**
+     * Should be called when we no longer want to use the ProtoLog logger to unlink ourselves from
+     * the datasource and the configuration service to ensure we no longer receive the callback.
+     */
+    public void disable() {
+        mDataSource.unregisterOnStartCallback(this::onTracingInstanceStart);
+        mDataSource.unregisterOnFlushCallback(this::onTracingFlush);
+        mDataSource.unregisterOnStopCallback(this::onTracingInstanceStop);
     }
 
     @NonNull
@@ -703,7 +716,7 @@
             }
         }
 
-        mCacheUpdater.run();
+        mCacheUpdater.update(this);
         return 0;
     }
 
@@ -746,7 +759,7 @@
             }
         }
 
-        mCacheUpdater.run();
+        mCacheUpdater.update(this);
 
         this.mTracingInstances.incrementAndGet();
 
@@ -786,7 +799,7 @@
             }
         }
 
-        mCacheUpdater.run();
+        mCacheUpdater.update(this);
         Log.d(LOG_TAG, "Finished onTracingInstanceStop");
     }
 
diff --git a/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java
index 967a5ed..e0a77d2 100644
--- a/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java
@@ -42,10 +42,11 @@
     private final String mViewerConfigFilePath;
 
     public ProcessedPerfettoProtoLogImpl(
+            @NonNull ProtoLogDataSource datasource,
             @NonNull String viewerConfigFilePath,
-            @NonNull Runnable cacheUpdater,
+            @NonNull ProtoLogCacheUpdater cacheUpdater,
             @NonNull IProtoLogGroup[] groups) throws ServiceManager.ServiceNotFoundException {
-        this(viewerConfigFilePath, new ViewerConfigInputStreamProvider() {
+        this(datasource, viewerConfigFilePath, new ViewerConfigInputStreamProvider() {
                     @NonNull
                     @Override
                     public AutoClosableProtoInputStream getInputStream() {
@@ -64,11 +65,12 @@
 
     @VisibleForTesting
     public ProcessedPerfettoProtoLogImpl(
+            @NonNull ProtoLogDataSource datasource,
             @NonNull String viewerConfigFilePath,
             @NonNull ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
-            @NonNull Runnable cacheUpdater,
+            @NonNull ProtoLogCacheUpdater cacheUpdater,
             @NonNull IProtoLogGroup[] groups) throws ServiceManager.ServiceNotFoundException {
-        super(cacheUpdater, groups);
+        super(datasource, cacheUpdater, groups);
 
         this.mViewerConfigFilePath = viewerConfigFilePath;
 
@@ -80,15 +82,15 @@
 
     @VisibleForTesting
     public ProcessedPerfettoProtoLogImpl(
+            @NonNull ProtoLogDataSource datasource,
             @NonNull String viewerConfigFilePath,
             @NonNull ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
             @NonNull ProtoLogViewerConfigReader viewerConfigReader,
-            @NonNull Runnable cacheUpdater,
+            @NonNull ProtoLogCacheUpdater cacheUpdater,
             @NonNull IProtoLogGroup[] groups,
-            @NonNull ProtoLogDataSourceBuilder dataSourceBuilder,
             @Nullable IProtoLogConfigurationService configurationService)
             throws ServiceManager.ServiceNotFoundException {
-        super(cacheUpdater, groups, dataSourceBuilder, configurationService);
+        super(datasource, cacheUpdater, groups, configurationService);
 
         this.mViewerConfigFilePath = viewerConfigFilePath;
 
diff --git a/core/java/com/android/internal/protolog/ProtoLog.java b/core/java/com/android/internal/protolog/ProtoLog.java
index d117e93..c81af95 100644
--- a/core/java/com/android/internal/protolog/ProtoLog.java
+++ b/core/java/com/android/internal/protolog/ProtoLog.java
@@ -17,6 +17,9 @@
 package com.android.internal.protolog;
 
 import android.os.ServiceManager;
+import android.tracing.perfetto.DataSourceParams;
+import android.tracing.perfetto.InitArguments;
+import android.tracing.perfetto.Producer;
 
 import com.android.internal.protolog.common.IProtoLog;
 import com.android.internal.protolog.common.IProtoLogGroup;
@@ -54,6 +57,8 @@
 
     private static IProtoLog sProtoLogInstance;
 
+    private static ProtoLogDataSource sDataSource;
+
     private static final Object sInitLock = new Object();
 
     /**
@@ -69,26 +74,45 @@
         // files to extract out the log strings. Otherwise, the trace calls are replaced with calls
         // directly to the generated tracing implementations.
         if (android.tracing.Flags.perfettoProtologTracing()) {
-            synchronized (sInitLock) {
-                final var allGroups = new HashSet<>(Arrays.stream(groups).toList());
-                if (sProtoLogInstance != null) {
-                    // The ProtoLog instance has already been initialized in this process
-                    final var alreadyRegisteredGroups = sProtoLogInstance.getRegisteredGroups();
-                    allGroups.addAll(alreadyRegisteredGroups);
-                }
-
-                try {
-                    sProtoLogInstance = new UnprocessedPerfettoProtoLogImpl(
-                            allGroups.toArray(new IProtoLogGroup[0]));
-                } catch (ServiceManager.ServiceNotFoundException e) {
-                    throw new RuntimeException(e);
-                }
-            }
+            initializePerfettoProtoLog(groups);
         } else {
             sProtoLogInstance = new LogcatOnlyProtoLogImpl();
         }
     }
 
+    private static void initializePerfettoProtoLog(IProtoLogGroup... groups) {
+        var datasource = getSharedSingleInstanceDataSource();
+
+        synchronized (sInitLock) {
+            final var allGroups = new HashSet<>(Arrays.stream(groups).toList());
+            final var previousProtoLogImpl = sProtoLogInstance;
+            if (previousProtoLogImpl != null) {
+                // The ProtoLog instance has already been initialized in this process
+                final var alreadyRegisteredGroups = previousProtoLogImpl.getRegisteredGroups();
+                allGroups.addAll(alreadyRegisteredGroups);
+            }
+
+            sProtoLogInstance = createAndEnableNewPerfettoProtoLogImpl(
+                    datasource, allGroups.toArray(new IProtoLogGroup[0]));
+            if (previousProtoLogImpl instanceof PerfettoProtoLogImpl) {
+                ((PerfettoProtoLogImpl) previousProtoLogImpl).disable();
+            }
+        }
+    }
+
+    private static PerfettoProtoLogImpl createAndEnableNewPerfettoProtoLogImpl(
+            ProtoLogDataSource datasource, IProtoLogGroup[] groups) {
+        try {
+            var unprocessedPerfettoProtoLogImpl =
+                    new UnprocessedPerfettoProtoLogImpl(datasource, groups);
+            unprocessedPerfettoProtoLogImpl.enable();
+
+            return unprocessedPerfettoProtoLogImpl;
+        } catch (ServiceManager.ServiceNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     /**
      * DEBUG level log.
      *
@@ -190,6 +214,32 @@
         return sProtoLogInstance;
     }
 
+    /**
+     * Gets or creates if it doesn't exist yet the protolog datasource to use in this process.
+     * We should re-use the same datasource to avoid registering the datasource multiple times in
+     * the same process, since there is no way to unregister the datasource after registration.
+     *
+     * @return The single ProtoLog datasource instance to be shared across all ProtoLog tracing
+     *         objects.
+     */
+    public static synchronized ProtoLogDataSource getSharedSingleInstanceDataSource() {
+        if (sDataSource == null) {
+            Producer.init(InitArguments.DEFAULTS);
+            sDataSource = new ProtoLogDataSource();
+            DataSourceParams params =
+                    new DataSourceParams.Builder()
+                            .setBufferExhaustedPolicy(
+                                    DataSourceParams
+                                            .PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
+                            .build();
+            // NOTE: Registering that datasource is an async operation, so there may be no data
+            // traced for some messages logged right after the construction of this class.
+            sDataSource.register(params);
+        }
+
+        return sDataSource;
+    }
+
     private static void logStringMessage(LogLevel logLevel, IProtoLogGroup group,
             String stringMessage, Object... args) {
         if (sProtoLogInstance == null) {
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/core/java/com/android/internal/protolog/ProtoLogCacheUpdater.java
similarity index 61%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to core/java/com/android/internal/protolog/ProtoLogCacheUpdater.java
index 5a04169..4f8655c 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/core/java/com/android/internal/protolog/ProtoLogCacheUpdater.java
@@ -14,8 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.internal.protolog;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import com.android.internal.protolog.common.IProtoLog;
+
+public interface ProtoLogCacheUpdater {
+    /**
+     * Update the cache based on the latest state of the active tracing configurations.
+     *
+     * @param protoLogInstance the instance to use to query the latest state of tracing.
+     */
+    void update(IProtoLog protoLogInstance);
 }
diff --git a/core/java/com/android/internal/protolog/ProtoLogConfigurationServiceImpl.java b/core/java/com/android/internal/protolog/ProtoLogConfigurationServiceImpl.java
index e9a8770..23f7c2a 100644
--- a/core/java/com/android/internal/protolog/ProtoLogConfigurationServiceImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogConfigurationServiceImpl.java
@@ -34,9 +34,6 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
-import android.tracing.perfetto.DataSourceParams;
-import android.tracing.perfetto.InitArguments;
-import android.tracing.perfetto.Producer;
 import android.util.Log;
 import android.util.proto.ProtoInputStream;
 import android.util.proto.ProtoOutputStream;
@@ -110,39 +107,31 @@
     private final ViewerConfigFileTracer mViewerConfigFileTracer;
 
     public ProtoLogConfigurationServiceImpl() {
-        this(ProtoLogDataSource::new, ProtoLogConfigurationServiceImpl::dumpViewerConfig);
+        this(ProtoLog.getSharedSingleInstanceDataSource(),
+                ProtoLogConfigurationServiceImpl::dumpViewerConfig);
     }
 
     @VisibleForTesting
-    public ProtoLogConfigurationServiceImpl(@NonNull ProtoLogDataSourceBuilder dataSourceBuilder) {
-        this(dataSourceBuilder, ProtoLogConfigurationServiceImpl::dumpViewerConfig);
+    public ProtoLogConfigurationServiceImpl(@NonNull ProtoLogDataSource datasource) {
+        this(datasource, ProtoLogConfigurationServiceImpl::dumpViewerConfig);
     }
 
     @VisibleForTesting
     public ProtoLogConfigurationServiceImpl(@NonNull ViewerConfigFileTracer tracer) {
-        this(ProtoLogDataSource::new, tracer);
+        this(ProtoLog.getSharedSingleInstanceDataSource(), tracer);
     }
 
     @VisibleForTesting
     public ProtoLogConfigurationServiceImpl(
-            @NonNull ProtoLogDataSourceBuilder dataSourceBuilder,
+            @NonNull ProtoLogDataSource datasource,
             @NonNull ViewerConfigFileTracer tracer) {
-        mDataSource = dataSourceBuilder.build(
-            this::onTracingInstanceStart,
-            this::onTracingInstanceFlush,
-            this::onTracingInstanceStop
-        );
-
-        // Initialize the Perfetto producer and register the Perfetto ProtoLog datasource to be
-        // receive the lifecycle callbacks of the datasource and write the viewer configs if and
-        // when required to the datasource.
-        Producer.init(InitArguments.DEFAULTS);
-        final var params = new DataSourceParams.Builder()
-                .setBufferExhaustedPolicy(DataSourceParams.PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
-                .build();
-        mDataSource.register(params);
-
         mViewerConfigFileTracer = tracer;
+
+        datasource.registerOnStartCallback(this::onTracingInstanceStart);
+        datasource.registerOnFlushCallback(this::onTracingInstanceFlush);
+        datasource.registerOnStopCallback(this::onTracingInstanceStop);
+
+        mDataSource = datasource;
     }
 
     public static class RegisterClientArgs extends IRegisterClientArgs.Stub {
diff --git a/core/java/com/android/internal/protolog/ProtoLogDataSource.java b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
index 0afb135..ea45249 100644
--- a/core/java/com/android/internal/protolog/ProtoLogDataSource.java
+++ b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
@@ -46,36 +46,30 @@
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 
 public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
         ProtoLogDataSource.TlsState,
         ProtoLogDataSource.IncrementalState> {
     private static final String DATASOURCE_NAME = "android.protolog";
 
-    @NonNull
-    private final Instance.TracingInstanceStartCallback mOnStart;
-    @NonNull
-    private final Runnable mOnFlush;
-    @NonNull
-    private final Instance.TracingInstanceStopCallback mOnStop;
+    private final Map<Integer, ProtoLogConfig> mRunningInstances = new TreeMap<>();
 
-    public ProtoLogDataSource(
-            @NonNull Instance.TracingInstanceStartCallback onStart,
-            @NonNull Runnable onFlush,
-            @NonNull Instance.TracingInstanceStopCallback onStop) {
-        this(onStart, onFlush, onStop, DATASOURCE_NAME);
+    @NonNull
+    private final Set<Instance.TracingInstanceStartCallback> mOnStartCallbacks = new HashSet<>();
+    @NonNull
+    private final Set<Runnable> mOnFlushCallbacks = new HashSet<>();
+    @NonNull
+    private final Set<Instance.TracingInstanceStopCallback> mOnStopCallbacks = new HashSet<>();
+
+    public ProtoLogDataSource() {
+        this(DATASOURCE_NAME);
     }
 
     @VisibleForTesting
     public ProtoLogDataSource(
-            @NonNull Instance.TracingInstanceStartCallback onStart,
-            @NonNull Runnable onFlush,
-            @NonNull Instance.TracingInstanceStopCallback onStop,
             @NonNull String dataSourceName) {
         super(dataSourceName);
-        this.mOnStart = onStart;
-        this.mOnFlush = onFlush;
-        this.mOnStop = onStop;
     }
 
     @Override
@@ -106,7 +100,8 @@
         }
 
         return new Instance(
-                this, instanceIndex, config, mOnStart, mOnFlush, mOnStop);
+                this, instanceIndex, config, this::executeOnStartCallbacks,
+                this::executeOnFlushCallbacks, this::executeOnStopCallbacks);
     }
 
     @Override
@@ -128,6 +123,84 @@
         return new IncrementalState();
     }
 
+    /**
+     * Register an onStart callback that will be called when a tracing instance is started.
+     * The callback will be called immediately for all currently running tracing instances on
+     * registration.
+     * @param onStartCallback The callback to call on starting a tracing instance.
+     */
+    public synchronized void registerOnStartCallback(
+            Instance.TracingInstanceStartCallback onStartCallback) {
+        mOnStartCallbacks.add(onStartCallback);
+
+        for (var instanceIndex : mRunningInstances.keySet()) {
+            var config = mRunningInstances.get(instanceIndex);
+            onStartCallback.run(instanceIndex, config);
+        }
+    }
+
+    /**
+     * Register an onFlush callback that will be called when a tracing instance is about to flush.
+     * @param onFlushCallback The callback to call on flushing a tracing instance
+     */
+    public void registerOnFlushCallback(Runnable onFlushCallback) {
+        mOnFlushCallbacks.add(onFlushCallback);
+    }
+
+    /**
+     * Register an onStop callback that will be called when a tracing instance is being stopped.
+     * @param onStopCallback The callback to call on stopping a tracing instance.
+     */
+    public void registerOnStopCallback(Instance.TracingInstanceStopCallback onStopCallback) {
+        mOnStopCallbacks.add(onStopCallback);
+    }
+
+    /**
+     * Unregister an onStart callback.
+     * @param onStartCallback The callback object to unregister.
+     */
+    public void unregisterOnStartCallback(Instance.TracingInstanceStartCallback onStartCallback) {
+        mOnStartCallbacks.add(onStartCallback);
+    }
+
+    /**
+     * Unregister an onFlush callback.
+     * @param onFlushCallback The callback object to unregister.
+     */
+    public void unregisterOnFlushCallback(Runnable onFlushCallback) {
+        mOnFlushCallbacks.add(onFlushCallback);
+    }
+
+    /**
+     * Unregister an onStop callback.
+     * @param onStopCallback The callback object to unregister.
+     */
+    public void unregisterOnStopCallback(Instance.TracingInstanceStopCallback onStopCallback) {
+        mOnStopCallbacks.add(onStopCallback);
+    }
+
+    private synchronized void executeOnStartCallbacks(int instanceIdx, ProtoLogConfig config) {
+        mRunningInstances.put(instanceIdx, config);
+
+        for (var onStart : mOnStartCallbacks) {
+            onStart.run(instanceIdx, config);
+        }
+    }
+
+    private void executeOnFlushCallbacks() {
+        for (var onFlush : mOnFlushCallbacks) {
+            onFlush.run();
+        }
+    }
+
+    private synchronized void executeOnStopCallbacks(int instanceIdx, ProtoLogConfig config) {
+        mRunningInstances.remove(instanceIdx, config);
+
+        for (var onStop : mOnStopCallbacks) {
+            onStop.run(instanceIdx, config);
+        }
+    }
+
     public static class TlsState {
         @NonNull
         private final ProtoLogConfig mConfig;
diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java
index 3378d08..c2d4b21 100644
--- a/core/java/com/android/internal/protolog/ProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java
@@ -56,7 +56,7 @@
     private static TreeMap<String, IProtoLogGroup> sLogGroups;
 
     @ProtoLogToolInjected(CACHE_UPDATER)
-    private static Runnable sCacheUpdater;
+    private static ProtoLogCacheUpdater sCacheUpdater;
 
     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
     public static void d(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
@@ -93,7 +93,12 @@
      * and log level.
      */
     public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
-        return getSingleInstance().isEnabled(group, level);
+        return isEnabled(getSingleInstance(), group, level);
+    }
+
+    private static boolean isEnabled(
+            IProtoLog protoLogInstance, IProtoLogGroup group, LogLevel level) {
+        return protoLogInstance.isEnabled(group, level);
     }
 
     /**
@@ -106,36 +111,37 @@
 
             final var groups = sLogGroups.values().toArray(new IProtoLogGroup[0]);
             if (android.tracing.Flags.perfettoProtologTracing()) {
-                sServiceInstance = createProtoLogImpl(groups);
+                var viewerConfigFile = new File(sViewerConfigPath);
+                if (!viewerConfigFile.exists()) {
+                    // TODO(b/353530422): Remove - temporary fix to unblock b/352290057
+                    // In robolectric tests the viewer config file isn't current available, so we
+                    // cannot use the ProcessedPerfettoProtoLogImpl.
+                    Log.e(LOG_TAG, "Failed to find viewer config file " + sViewerConfigPath
+                            + " when setting up " + ProtoLogImpl.class.getSimpleName() + ". "
+                            + "ProtoLog will not work here!");
+
+                    sServiceInstance = new NoViewerConfigProtoLogImpl();
+                } else {
+                    var datasource = ProtoLog.getSharedSingleInstanceDataSource();
+                    try {
+                        var processedProtoLogImpl =
+                                new ProcessedPerfettoProtoLogImpl(datasource, sViewerConfigPath,
+                                        sCacheUpdater, groups);
+                        sServiceInstance = processedProtoLogImpl;
+                        processedProtoLogImpl.enable();
+                    } catch (ServiceManager.ServiceNotFoundException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
             } else {
                 sServiceInstance = createLegacyProtoLogImpl(groups);
             }
 
-            sCacheUpdater.run();
+            sCacheUpdater.update(sServiceInstance);
         }
         return sServiceInstance;
     }
 
-    private static IProtoLog createProtoLogImpl(IProtoLogGroup[] groups) {
-        try {
-            File f = new File(sViewerConfigPath);
-            if (!f.exists()) {
-                // TODO(b/353530422): Remove - temporary fix to unblock b/352290057
-                // In robolectric tests the viewer config file isn't current available, so we cannot
-                // use the ProcessedPerfettoProtoLogImpl.
-                Log.e(LOG_TAG, "Failed to find viewer config file " + sViewerConfigPath
-                        + " when setting up " + ProtoLogImpl.class.getSimpleName() + ". "
-                        + "ProtoLog will not work here!");
-
-                return new NoViewerConfigProtoLogImpl();
-            } else {
-                return new ProcessedPerfettoProtoLogImpl(sViewerConfigPath, sCacheUpdater, groups);
-            }
-        } catch (ServiceManager.ServiceNotFoundException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     private static LegacyProtoLogImpl createLegacyProtoLogImpl(IProtoLogGroup[] groups) {
         var protologImpl = new LegacyProtoLogImpl(
                 sLegacyOutputFilePath, sLegacyViewerConfigPath, sCacheUpdater);
diff --git a/core/java/com/android/internal/protolog/UnprocessedPerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/UnprocessedPerfettoProtoLogImpl.java
index f3fe580..ebb07a04 100644
--- a/core/java/com/android/internal/protolog/UnprocessedPerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/UnprocessedPerfettoProtoLogImpl.java
@@ -23,14 +23,10 @@
 import com.android.internal.protolog.common.IProtoLogGroup;
 
 public class UnprocessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl {
-    public UnprocessedPerfettoProtoLogImpl(@NonNull IProtoLogGroup[] groups)
+    public UnprocessedPerfettoProtoLogImpl(
+            @NonNull ProtoLogDataSource dataSource, @NonNull IProtoLogGroup[] groups)
             throws ServiceManager.ServiceNotFoundException {
-        this(() -> {}, groups);
-    }
-
-    public UnprocessedPerfettoProtoLogImpl(@NonNull Runnable cacheUpdater,
-            @NonNull IProtoLogGroup[] groups) throws ServiceManager.ServiceNotFoundException {
-        super(cacheUpdater, groups);
+        super(dataSource, (instance) -> {}, groups);
         readyToLogToLogcat();
     }
 
diff --git a/core/java/com/android/internal/vibrator/persistence/SerializedCompositionPrimitive.java b/core/java/com/android/internal/vibrator/persistence/SerializedCompositionPrimitive.java
index 862f7cb..5eedec6 100644
--- a/core/java/com/android/internal/vibrator/persistence/SerializedCompositionPrimitive.java
+++ b/core/java/com/android/internal/vibrator/persistence/SerializedCompositionPrimitive.java
@@ -17,6 +17,7 @@
 package com.android.internal.vibrator.persistence;
 
 import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_DELAY_MS;
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_DELAY_TYPE;
 import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_NAME;
 import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_SCALE;
 import static com.android.internal.vibrator.persistence.XmlConstants.NAMESPACE;
@@ -25,9 +26,11 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.VibrationEffect;
+import android.os.vibrator.Flags;
 import android.os.vibrator.PrimitiveSegment;
 
 import com.android.internal.vibrator.persistence.SerializedComposedEffect.SerializedSegment;
+import com.android.internal.vibrator.persistence.XmlConstants.PrimitiveDelayType;
 import com.android.internal.vibrator.persistence.XmlConstants.PrimitiveEffectName;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
@@ -46,17 +49,26 @@
     private final PrimitiveEffectName mPrimitiveName;
     private final float mPrimitiveScale;
     private final int mPrimitiveDelayMs;
+    @Nullable
+    private final PrimitiveDelayType mDelayType;
 
-    SerializedCompositionPrimitive(PrimitiveEffectName primitiveName, float scale, int delayMs) {
+    SerializedCompositionPrimitive(PrimitiveEffectName primitiveName, float scale, int delayMs,
+            @Nullable PrimitiveDelayType delayType) {
         mPrimitiveName = primitiveName;
         mPrimitiveScale = scale;
         mPrimitiveDelayMs = delayMs;
+        mDelayType = delayType;
     }
 
     @Override
     public void deserializeIntoComposition(@NonNull VibrationEffect.Composition composition) {
-        composition.addPrimitive(mPrimitiveName.getPrimitiveId(), mPrimitiveScale,
-                mPrimitiveDelayMs);
+        if (Flags.primitiveCompositionAbsoluteDelay() && mDelayType != null) {
+            composition.addPrimitive(mPrimitiveName.getPrimitiveId(), mPrimitiveScale,
+                    mPrimitiveDelayMs, mDelayType.getDelayType());
+        } else {
+            composition.addPrimitive(mPrimitiveName.getPrimitiveId(), mPrimitiveScale,
+                    mPrimitiveDelayMs);
+        }
     }
 
     @Override
@@ -72,6 +84,12 @@
             serializer.attributeInt(NAMESPACE, ATTRIBUTE_DELAY_MS, mPrimitiveDelayMs);
         }
 
+        if (Flags.primitiveCompositionAbsoluteDelay() && mDelayType != null) {
+            if (mDelayType.getDelayType() != PrimitiveSegment.DEFAULT_DELAY_TYPE) {
+                serializer.attribute(NAMESPACE, ATTRIBUTE_DELAY_TYPE, mDelayType.toString());
+            }
+        }
+
         serializer.endTag(NAMESPACE, TAG_PRIMITIVE_EFFECT);
     }
 
@@ -81,6 +99,7 @@
                 + "name=" + mPrimitiveName
                 + ", scale=" + mPrimitiveScale
                 + ", delayMs=" + mPrimitiveDelayMs
+                + ", delayType=" + mDelayType
                 + '}';
     }
 
@@ -91,8 +110,14 @@
         static SerializedCompositionPrimitive parseNext(@NonNull TypedXmlPullParser parser)
                 throws XmlParserException, IOException {
             XmlValidator.checkStartTag(parser, TAG_PRIMITIVE_EFFECT);
-            XmlValidator.checkTagHasNoUnexpectedAttributes(parser,
-                    ATTRIBUTE_NAME, ATTRIBUTE_DELAY_MS, ATTRIBUTE_SCALE);
+
+            if (Flags.primitiveCompositionAbsoluteDelay()) {
+                XmlValidator.checkTagHasNoUnexpectedAttributes(parser,
+                        ATTRIBUTE_NAME, ATTRIBUTE_DELAY_MS, ATTRIBUTE_SCALE, ATTRIBUTE_DELAY_TYPE);
+            } else {
+                XmlValidator.checkTagHasNoUnexpectedAttributes(parser,
+                        ATTRIBUTE_NAME, ATTRIBUTE_DELAY_MS, ATTRIBUTE_SCALE);
+            }
 
             PrimitiveEffectName primitiveName = parsePrimitiveName(
                     parser.getAttributeValue(NAMESPACE, ATTRIBUTE_NAME));
@@ -100,11 +125,13 @@
                     parser, ATTRIBUTE_SCALE, 0, 1, PrimitiveSegment.DEFAULT_SCALE);
             int delayMs = XmlReader.readAttributeIntNonNegative(
                     parser, ATTRIBUTE_DELAY_MS, PrimitiveSegment.DEFAULT_DELAY_MILLIS);
+            PrimitiveDelayType delayType = parseDelayType(
+                    parser.getAttributeValue(NAMESPACE, ATTRIBUTE_DELAY_TYPE));
 
             // Consume tag
             XmlReader.readEndTag(parser);
 
-            return new SerializedCompositionPrimitive(primitiveName, scale, delayMs);
+            return new SerializedCompositionPrimitive(primitiveName, scale, delayMs, delayType);
         }
 
         @NonNull
@@ -119,5 +146,21 @@
             }
             return effectName;
         }
+
+        @Nullable
+        private static PrimitiveDelayType parseDelayType(@Nullable String name)
+                throws XmlParserException {
+            if (name == null) {
+                return null;
+            }
+            if (!Flags.primitiveCompositionAbsoluteDelay()) {
+                throw new XmlParserException("Unexpected primitive delay type " + name);
+            }
+            PrimitiveDelayType delayType = PrimitiveDelayType.findByName(name);
+            if (delayType == null) {
+                throw new XmlParserException("Unexpected primitive delay type " + name);
+            }
+            return delayType;
+        }
     }
 }
diff --git a/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java b/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java
index d74a23d..cb834a5 100644
--- a/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java
+++ b/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java
@@ -27,6 +27,7 @@
 
 import com.android.internal.vibrator.persistence.SerializedComposedEffect.SerializedSegment;
 import com.android.internal.vibrator.persistence.XmlConstants.PredefinedEffectName;
+import com.android.internal.vibrator.persistence.XmlConstants.PrimitiveDelayType;
 import com.android.internal.vibrator.persistence.XmlConstants.PrimitiveEffectName;
 
 import java.util.List;
@@ -170,8 +171,20 @@
         XmlValidator.checkSerializerCondition(primitiveName != null,
                 "Unsupported primitive effect id %s", primitive.getPrimitiveId());
 
+        PrimitiveDelayType delayType = null;
+
+        if (Flags.primitiveCompositionAbsoluteDelay()) {
+            delayType = PrimitiveDelayType.findByType(primitive.getDelayType());
+            XmlValidator.checkSerializerCondition(delayType != null,
+                    "Unsupported primitive delay type %s", primitive.getDelayType());
+        } else {
+            XmlValidator.checkSerializerCondition(
+                    primitive.getDelayType() == PrimitiveSegment.DEFAULT_DELAY_TYPE,
+                    "Unsupported primitive delay type %s", primitive.getDelayType());
+        }
+
         return new SerializedCompositionPrimitive(
-                primitiveName, primitive.getScale(), primitive.getDelay());
+                primitiveName, primitive.getScale(), primitive.getDelay(), delayType);
     }
 
     private static int toAmplitudeInt(float amplitude) {
diff --git a/core/java/com/android/internal/vibrator/persistence/XmlConstants.java b/core/java/com/android/internal/vibrator/persistence/XmlConstants.java
index 2a55d99..4122215 100644
--- a/core/java/com/android/internal/vibrator/persistence/XmlConstants.java
+++ b/core/java/com/android/internal/vibrator/persistence/XmlConstants.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.VibrationEffect;
+import android.os.VibrationEffect.Composition.DelayType;
 import android.os.VibrationEffect.Composition.PrimitiveType;
 
 import java.lang.annotation.Retention;
@@ -51,6 +52,7 @@
     public static final String ATTRIBUTE_AMPLITUDE = "amplitude";
     public static final String ATTRIBUTE_SCALE = "scale";
     public static final String ATTRIBUTE_DELAY_MS = "delayMs";
+    public static final String ATTRIBUTE_DELAY_TYPE = "delayType";
 
     public static final String VALUE_AMPLITUDE_DEFAULT = "default";
 
@@ -87,7 +89,7 @@
 
         /**
          * Return the {@link PrimitiveEffectName} that represents given primitive id, or null if
-         * none of the available names maps to the given id.
+         * none of the available names map to the given id.
          */
         @Nullable
         public static PrimitiveEffectName findById(int primitiveId) {
@@ -200,4 +202,53 @@
             return name().toLowerCase(Locale.ROOT);
         }
     }
+
+    /** Represent supported values for attribute delay type in {@link #TAG_PRIMITIVE_EFFECT}  */
+    public enum PrimitiveDelayType {
+        PAUSE(VibrationEffect.Composition.DELAY_TYPE_PAUSE),
+        RELATIVE_START_OFFSET(VibrationEffect.Composition.DELAY_TYPE_RELATIVE_START_OFFSET);
+
+        @DelayType private final int mDelayType;
+
+        PrimitiveDelayType(@DelayType int type) {
+            mDelayType = type;
+        }
+
+        /**
+         * Return the {@link PrimitiveEffectName} that represents given primitive id, or null if
+         * none of the available names maps to the given id.
+         */
+        @Nullable
+        public static PrimitiveDelayType findByType(int delayType) {
+            for (PrimitiveDelayType type : PrimitiveDelayType.values()) {
+                if (type.mDelayType == delayType) {
+                    return type;
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Return the {@link PrimitiveEffectName} that represents given primitive name, or null if
+         * none of the available names maps to the given name.
+         */
+        @Nullable
+        public static PrimitiveDelayType findByName(@NonNull String delayType) {
+            try {
+                return PrimitiveDelayType.valueOf(delayType.toUpperCase(Locale.ROOT));
+            } catch (IllegalArgumentException e) {
+                return null;
+            }
+        }
+
+        @DelayType
+        public int getDelayType() {
+            return mDelayType;
+        }
+
+        @Override
+        public String toString() {
+            return name().toLowerCase(Locale.ROOT);
+        }
+    }
 }
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index 97a2d3b..4305ba7 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -261,7 +261,7 @@
         MessagingGroup createdGroup = sInstancePool.acquire();
         if (createdGroup == null) {
             createdGroup = (MessagingGroup) LayoutInflater.from(layout.getContext()).inflate(
-                    R.layout.notification_template_messaging_group, layout,
+                    getMessagingGroupLayoutResource(), layout,
                     false);
             createdGroup.addOnLayoutChangeListener(MessagingLayout.MESSAGING_PROPERTY_ANIMATOR);
         }
@@ -269,6 +269,14 @@
         return createdGroup;
     }
 
+    private static int getMessagingGroupLayoutResource() {
+        if (Flags.notificationsRedesignTemplates()) {
+            return R.layout.notification_2025_messaging_group;
+        } else {
+            return R.layout.notification_template_messaging_group;
+        }
+    }
+
     public void removeMessage(MessagingMessage messagingMessage,
             ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
         View view = messagingMessage.getView();
diff --git a/core/java/com/android/internal/widget/NotificationProgressBar.java b/core/java/com/android/internal/widget/NotificationProgressBar.java
index 7a21275..8cd7843 100644
--- a/core/java/com/android/internal/widget/NotificationProgressBar.java
+++ b/core/java/com/android/internal/widget/NotificationProgressBar.java
@@ -68,12 +68,18 @@
 
     @Nullable
     private Drawable mTracker = null;
+
+    /** @see R.styleable#NotificationProgressBar_trackerHeight */
     private final int mTrackerHeight;
     private int mTrackerWidth;
     private int mTrackerPos;
     private final Matrix mMatrix = new Matrix();
     private Matrix mTrackerDrawMatrix = null;
 
+    private float mScale = 0;
+    /** Indicates whether mTrackerPos needs to be recalculated before the tracker is drawn. */
+    private boolean mTrackerPosIsDirty = false;
+
     public NotificationProgressBar(Context context) {
         this(context, null);
     }
@@ -107,8 +113,8 @@
         final Drawable tracker = a.getDrawable(R.styleable.NotificationProgressBar_tracker);
         setTracker(tracker);
 
-        // If this is configured to be non-zero, will scale the tracker drawable and ensure its
-        // aspect ration is between 2:1 to 1:2.
+        // If this is configured to be a non-zero size, will scale and crop the tracker drawable to
+        // ensure its aspect ratio is between 2:1 to 1:2.
         mTrackerHeight = a.getDimensionPixelSize(R.styleable.NotificationProgressBar_trackerHeight,
                 0);
     }
@@ -200,8 +206,9 @@
     }
 
     private void setTracker(@Nullable Drawable tracker) {
-        final boolean needUpdate = mTracker != null && tracker != mTracker;
-        if (needUpdate) {
+        if (tracker == mTracker) return;
+
+        if (mTracker != null) {
             mTracker.setCallback(null);
         }
 
@@ -214,33 +221,41 @@
             if (canResolveLayoutDirection()) {
                 tracker.setLayoutDirection(getLayoutDirection());
             }
-
-            // If we're updating get the new states
-            if (needUpdate && (tracker.getIntrinsicWidth() != mTracker.getIntrinsicWidth()
-                    || tracker.getIntrinsicHeight() != mTracker.getIntrinsicHeight())) {
-                requestLayout();
-            }
         }
 
+        final boolean trackerSizeChanged = trackerSizeChanged(tracker, mTracker);
+
         mTracker = tracker;
         if (mNotificationProgressDrawable != null) {
             mNotificationProgressDrawable.setHasTrackerIcon(mTracker != null);
         }
 
         configureTrackerBounds();
+        updateTrackerAndBarPos(getWidth(), getHeight());
+
+        // Change in tracker size may lead to change in measured view size.
+        // @see #onMeasure.
+        if (trackerSizeChanged) requestLayout();
 
         invalidate();
 
-        if (needUpdate) {
-            updateTrackerAndBarPos(getWidth(), getHeight());
-            if (tracker != null && tracker.isStateful()) {
-                // Note that if the states are different this won't work.
-                // For now, let's consider that an app bug.
-                tracker.setState(getDrawableState());
-            }
+        if (tracker != null && tracker.isStateful()) {
+            // Note that if the states are different this won't work.
+            // For now, let's consider that an app bug.
+            tracker.setState(getDrawableState());
         }
     }
 
+    private static boolean trackerSizeChanged(@Nullable Drawable newTracker,
+            @Nullable Drawable oldTracker) {
+        if (newTracker == null && oldTracker == null) return false;
+        if (newTracker == null && oldTracker != null) return true;
+        if (newTracker != null && oldTracker == null) return true;
+
+        return newTracker.getIntrinsicWidth() != oldTracker.getIntrinsicWidth()
+                || newTracker.getIntrinsicHeight() != oldTracker.getIntrinsicHeight();
+    }
+
     private void configureTrackerBounds() {
         // Reset the tracker draw matrix to null
         mTrackerDrawMatrix = null;
@@ -279,6 +294,44 @@
     }
 
     @Override
+    public synchronized void setProgress(int progress) {
+        super.setProgress(progress);
+
+        onMaybeVisualProgressChanged();
+    }
+
+    @Override
+    public void setProgress(int progress, boolean animate) {
+        // Animation isn't supported by NotificationProgressBar.
+        super.setProgress(progress, false);
+
+        onMaybeVisualProgressChanged();
+    }
+
+    @Override
+    public synchronized void setMin(int min) {
+        super.setMin(min);
+
+        onMaybeVisualProgressChanged();
+    }
+
+    @Override
+    public synchronized void setMax(int max) {
+        super.setMax(max);
+
+        onMaybeVisualProgressChanged();
+    }
+
+    private void onMaybeVisualProgressChanged() {
+        float scale = getScale();
+        if (mScale == scale) return;
+
+        mScale = scale;
+        mTrackerPosIsDirty = true;
+        invalidate();
+    }
+
+    @Override
     protected boolean verifyDrawable(@NonNull Drawable who) {
         return who == mTracker || super.verifyDrawable(who);
     }
@@ -328,7 +381,7 @@
         // parameter does.
         final int barHeight = Math.min(getMaxHeight(), paddedHeight);
         final int trackerHeight = tracker == null ? 0
-                : ((mTrackerHeight == 0) ? tracker.getIntrinsicHeight() : mTrackerHeight);
+                : ((mTrackerHeight <= 0) ? tracker.getIntrinsicHeight() : mTrackerHeight);
 
         // Apply offset to whichever item is taller.
         final int barOffsetY;
@@ -349,7 +402,7 @@
         }
 
         if (tracker != null) {
-            setTrackerPos(w, tracker, getScale(), trackerOffsetY);
+            setTrackerPos(w, tracker, mScale, trackerOffsetY);
         }
     }
 
@@ -373,7 +426,7 @@
         int available = w - mPaddingLeft - mPaddingRight;
         final int trackerWidth = tracker.getIntrinsicWidth();
         final int trackerHeight = tracker.getIntrinsicHeight();
-        available -= ((mTrackerHeight == 0) ? trackerWidth : mTrackerWidth);
+        available -= ((mTrackerHeight <= 0) ? trackerWidth : mTrackerWidth);
 
         final int trackerPos = (int) (scale * available + 0.5f);
 
@@ -401,6 +454,8 @@
 
         // Canvas will be translated, so 0,0 is where we start drawing
         tracker.setBounds(left, top, right, bottom);
+
+        mTrackerPosIsDirty = false;
     }
 
     @Override
@@ -424,18 +479,26 @@
      * Draw the tracker.
      */
     private void drawTracker(Canvas canvas) {
-        if (mTracker != null) {
-            final int saveCount = canvas.save();
-            // Translate the canvas origin to tracker position to make the draw matrix and the RtL
-            // transformations work.
-            canvas.translate(mPaddingLeft + mTrackerPos, mPaddingTop);
-            canvas.clipRect(0, 0, mTrackerWidth, mTrackerHeight);
-            if (mTrackerDrawMatrix != null) {
-                canvas.concat(mTrackerDrawMatrix);
-            }
-            mTracker.draw(canvas);
-            canvas.restoreToCount(saveCount);
+        if (mTracker == null) return;
+
+        if (mTrackerPosIsDirty) {
+            setTrackerPos(getWidth(), mTracker, mScale, Integer.MIN_VALUE);
         }
+
+        final int saveCount = canvas.save();
+        // Translate the canvas origin to tracker position to make the draw matrix and the RtL
+        // transformations work.
+        canvas.translate(mPaddingLeft + mTrackerPos, mPaddingTop);
+
+        if (mTrackerHeight > 0) {
+            canvas.clipRect(0, 0, mTrackerWidth, mTrackerHeight);
+        }
+
+        if (mTrackerDrawMatrix != null) {
+            canvas.concat(mTrackerDrawMatrix);
+        }
+        mTracker.draw(canvas);
+        canvas.restoreToCount(saveCount);
     }
 
     @Override
@@ -468,7 +531,7 @@
 
         final Drawable tracker = mTracker;
         if (tracker != null) {
-            setTrackerPos(getWidth(), tracker, getScale(), Integer.MIN_VALUE);
+            setTrackerPos(getWidth(), tracker, mScale, Integer.MIN_VALUE);
 
             // Since we draw translated, the drawable's bounds that it signals
             // for invalidation won't be the actual bounds we want invalidated,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operation.java b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
index 102003e..6f6a0a8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
@@ -18,19 +18,19 @@
 import android.annotation.NonNull;
 
 /** Base interface for RemoteCompose operations */
-public interface Operation {
+public abstract class Operation {
 
     /** add the operation to the buffer */
-    void write(@NonNull WireBuffer buffer);
+    public abstract void write(@NonNull WireBuffer buffer);
 
     /**
      * paint an operation
      *
      * @param context the paint context used to paint the operation
      */
-    void apply(@NonNull RemoteContext context);
+    public abstract void apply(@NonNull RemoteContext context);
 
     /** Debug utility to display an operation + indentation */
     @NonNull
-    String deepToString(@NonNull String indent);
+    public abstract String deepToString(@NonNull String indent);
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/OperationInterface.java b/core/java/com/android/internal/widget/remotecompose/core/OperationInterface.java
new file mode 100644
index 0000000..741303a
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/OperationInterface.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core;
+
+import android.annotation.NonNull;
+
+/** Base interface for RemoteCompose operations */
+public interface OperationInterface {
+
+    /** add the operation to the buffer */
+    void write(@NonNull WireBuffer buffer);
+
+    /**
+     * paint an operation
+     *
+     * @param context the paint context used to paint the operation
+     */
+    void apply(@NonNull RemoteContext context);
+
+    /** Debug utility to display an operation + indentation */
+    @NonNull
+    String deepToString(@NonNull String indent);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index 687a99b..006fe3a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -55,7 +55,10 @@
 import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
 import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
 import com.android.internal.widget.remotecompose.core.operations.PaintData;
+import com.android.internal.widget.remotecompose.core.operations.PathAppend;
+import com.android.internal.widget.remotecompose.core.operations.PathCreate;
 import com.android.internal.widget.remotecompose.core.operations.PathData;
+import com.android.internal.widget.remotecompose.core.operations.PathTween;
 import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
 import com.android.internal.widget.remotecompose.core.operations.RootContentDescription;
 import com.android.internal.widget.remotecompose.core.operations.ShaderData;
@@ -178,6 +181,9 @@
     public static final int TEXT_MEASURE = 155;
     public static final int TEXT_LENGTH = 156;
     public static final int TOUCH_EXPRESSION = 157;
+    public static final int PATH_TWEEN = 158;
+    public static final int PATH_CREATE = 159;
+    public static final int PATH_ADD = 160;
 
     ///////////////////////////////////////// ======================
 
@@ -353,5 +359,8 @@
         map.put(TEXT_MEASURE, TextMeasure::read);
         map.put(TEXT_LENGTH, TextLength::read);
         map.put(TOUCH_EXPRESSION, TouchExpression::read);
+        map.put(PATH_TWEEN, PathTween::read);
+        map.put(PATH_CREATE, PathCreate::read);
+        map.put(PATH_ADD, PathAppend::read);
     }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
index 38b08e9..7ecd118 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
@@ -157,6 +157,8 @@
     public abstract void drawTweenPath(
             int path1Id, int path2Id, float tween, float start, float stop);
 
+    public abstract void tweenPath(int out, int path1, int path2, float tween);
+
     /**
      * This applies changes to the current paint
      *
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
index 9999182..cfdd522 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
@@ -21,7 +21,7 @@
  * PaintOperation interface, used for operations aimed at painting (while any operation _can_ paint,
  * this make it a little more explicit)
  */
-public abstract class PaintOperation implements Operation {
+public abstract class PaintOperation extends Operation {
 
     @Override
     public void apply(@NonNull RemoteContext context) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index c05079e..3a5d68d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -59,7 +59,10 @@
 import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
 import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
 import com.android.internal.widget.remotecompose.core.operations.PaintData;
+import com.android.internal.widget.remotecompose.core.operations.PathAppend;
+import com.android.internal.widget.remotecompose.core.operations.PathCreate;
 import com.android.internal.widget.remotecompose.core.operations.PathData;
+import com.android.internal.widget.remotecompose.core.operations.PathTween;
 import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
 import com.android.internal.widget.remotecompose.core.operations.RootContentDescription;
 import com.android.internal.widget.remotecompose.core.operations.TextData;
@@ -644,6 +647,37 @@
     }
 
     /**
+     * interpolate the two paths to produce a 3rd
+     *
+     * @param pid1 the first path
+     * @param pid2 the second path
+     * @param tween path is the path1+(pat2-path1)*tween
+     * @return id of the tweened path
+     */
+    public int pathTween(int pid1, int pid2, float tween) {
+        int out = mRemoteComposeState.nextId();
+        PathTween.apply(mBuffer, out, pid1, pid2, tween);
+        return out;
+    }
+
+    /**
+     * Create a path with an initial moveTo
+     *
+     * @param x x coordinate of the moveto
+     * @param y y coordinate of the moveto
+     * @return id of the created path
+     */
+    public int pathCreate(float x, float y) {
+        int out = mRemoteComposeState.nextId();
+        PathCreate.apply(mBuffer, out, x, y);
+        return out;
+    }
+
+    public void pathAppend(int id, float... path) {
+        PathAppend.apply(mBuffer, id, path);
+    }
+
+    /**
      * Draw the specified path
      *
      * @param pathId
@@ -1154,6 +1188,16 @@
     }
 
     /**
+     * Reserve a float and returns a NaN number pointing to that float
+     *
+     * @return the nan id of float
+     */
+    public float reserveFloatVariable() {
+        int id = mRemoteComposeState.cacheFloat(0f);
+        return Utils.asNan(id);
+    }
+
+    /**
      * Add a Integer return an id number pointing to that float.
      *
      * @param value adds an integer and assigns it an id
@@ -1651,8 +1695,8 @@
      */
     public void addModifierScroll(int direction, float positionId, int notches) {
         // TODO: add support for non-notch behaviors etc.
-        float max = this.addFloat(0f);
-        float notchMax = this.addFloat(0f);
+        float max = this.reserveFloatVariable();
+        float notchMax = this.reserveFloatVariable();
         float touchExpressionDirection =
                 direction != 0 ? RemoteContext.FLOAT_TOUCH_POS_X : RemoteContext.FLOAT_TOUCH_POS_Y;
         this.addTouchExpression(
@@ -1807,8 +1851,8 @@
         ClipRectModifierOperation.apply(mBuffer);
     }
 
-    public void addLoopStart(float count, float from, float step, int indexId) {
-        LoopOperation.apply(mBuffer, count, from, step, indexId);
+    public void addLoopStart(int indexId, float from, float step, float until) {
+        LoopOperation.apply(mBuffer, indexId, from, step, until);
     }
 
     public void addLoopEnd() {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeOperation.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeOperation.java
index e60695f..97487e6 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeOperation.java
@@ -15,4 +15,4 @@
  */
 package com.android.internal.widget.remotecompose.core;
 
-public interface RemoteComposeOperation extends Operation {}
+public interface RemoteComposeOperation {}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
index a903e6e..f5f9e21 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
@@ -131,6 +131,16 @@
         }
     }
 
+    private final IntMap<float[]> mPathData = new IntMap<>();
+
+    public void putPathData(int id, float[] data) {
+        mPathData.put(id, data);
+    }
+
+    public float[] getPathData(int id) {
+        return mPathData.get(id);
+    }
+
     /**
      * Adds a data Override.
      *
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index 26305bf..6eb8463 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -93,12 +93,20 @@
     /**
      * Load a path under an id. Paths can be use in clip drawPath and drawTweenPath
      *
-     * @param instanceId
-     * @param floatPath
+     * @param instanceId the id to save this path under
+     * @param floatPath the path as a float array
      */
     public abstract void loadPathData(int instanceId, @NonNull float[] floatPath);
 
     /**
+     * Load a path under an id. Paths can be use in clip drawPath and drawTweenPath
+     *
+     * @param instanceId
+     * @return the a
+     */
+    public abstract @Nullable float[] getPathData(int instanceId);
+
+    /**
      * Associate a name with a give id.
      *
      * @param varName the name
diff --git a/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java
index a64b706..2f1502c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java
@@ -28,11 +28,17 @@
     int mStartingIndex = 0;
     int mSize = 0;
 
+    /**
+     * Create a wire buffer
+     *
+     * @param size the initial size of the buffer
+     */
     public WireBuffer(int size) {
         mMaxSize = size;
         mBuffer = new byte[mMaxSize];
     }
 
+    /** Create a wire buffer of default size */
     public WireBuffer() {
         this(BUFFER_SIZE);
     }
@@ -44,37 +50,74 @@
         }
     }
 
+    /**
+     * get the wire buffer's underlying byte array. Note the array will be bigger that the used
+     * portion
+     *
+     * @return byte array of the wire buffer
+     */
     public @NonNull byte[] getBuffer() {
         return mBuffer;
     }
 
+    /**
+     * The current mix size of the buffer
+     *
+     * @return max size
+     */
     public int getMax_size() {
         return mMaxSize;
     }
 
+    /**
+     * The current point in the buffer which will be written to
+     *
+     * @return index pointing into the buffer
+     */
     public int getIndex() {
         return mIndex;
     }
 
+    /**
+     * The size of the buffer
+     *
+     * @return the size of the buffer
+     */
     public int getSize() {
         return mSize;
     }
 
+    /**
+     * Reposition the pointer
+     *
+     * @param index the new position of the index
+     */
     public void setIndex(int index) {
         this.mIndex = index;
     }
 
+    /**
+     * Write a byte representing the command into the buffer
+     *
+     * @param type the command id
+     */
     public void start(int type) {
         mStartingIndex = mIndex;
         writeByte(type);
     }
 
+    /**
+     * Unused Todo remove?
+     *
+     * @param type the type of object to write
+     */
     public void startWithSize(int type) {
         mStartingIndex = mIndex;
         writeByte(type);
         mIndex += 4; // skip ahead for the future size
     }
 
+    /** Unused Todo remove? */
     public void endWithSize() {
         int size = mIndex - mStartingIndex;
         int currentIndex = mIndex;
@@ -97,10 +140,20 @@
         }
     }
 
+    /**
+     * return the size of the buffer todo rename to getSize
+     *
+     * @return the size of the buffer
+     */
     public int size() {
         return mSize;
     }
 
+    /**
+     * Bytes available
+     *
+     * @return the size - index
+     */
     public boolean available() {
         return mSize - mIndex > 0;
     }
@@ -109,28 +162,53 @@
     // Read values
     ///////////////////////////////////////////////////////////////////////////
 
+    /**
+     * read the operation type (reads a single byte)
+     *
+     * @return the byte cast to an integer
+     */
     public int readOperationType() {
         return readByte();
     }
 
+    /**
+     * Read a boolean (stored as a byte 1 = true)
+     *
+     * @return boolean of the byte
+     */
     public boolean readBoolean() {
         byte value = mBuffer[mIndex];
         mIndex++;
         return (value == 1);
     }
 
+    /**
+     * read a single byte byte
+     *
+     * @return byte from 0..255 as an Integer
+     */
     public int readByte() {
         int value = 0xFF & mBuffer[mIndex];
         mIndex++;
         return value;
     }
 
+    /**
+     * read a short [byte n] << 8 | [byte n+1]; index increast by 2
+     *
+     * @return return a short cast as an integer
+     */
     public int readShort() {
         int v1 = (mBuffer[mIndex++] & 0xFF) << 8;
         int v2 = (mBuffer[mIndex++] & 0xFF) << 0;
         return v1 + v2;
     }
 
+    /**
+     * Read an integer without incrementing the index
+     *
+     * @return the integer
+     */
     public int peekInt() {
         int tmp = mIndex;
         int v1 = (mBuffer[tmp++] & 0xFF) << 24;
@@ -140,6 +218,11 @@
         return v1 + v2 + v3 + v4;
     }
 
+    /**
+     * Read an integer. index increased by 4
+     *
+     * @return integer
+     */
     public int readInt() {
         int v1 = (mBuffer[mIndex++] & 0xFF) << 24;
         int v2 = (mBuffer[mIndex++] & 0xFF) << 16;
@@ -148,6 +231,11 @@
         return v1 + v2 + v3 + v4;
     }
 
+    /**
+     * Read a long index is increased by 8
+     *
+     * @return long
+     */
     public long readLong() {
         long v1 = (mBuffer[mIndex++] & 0xFFL) << 56;
         long v2 = (mBuffer[mIndex++] & 0xFFL) << 48;
@@ -160,14 +248,30 @@
         return v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
     }
 
+    /**
+     * Read a 32 bit float IEEE standard index is increased by 4
+     *
+     * @return the float
+     */
     public float readFloat() {
         return java.lang.Float.intBitsToFloat(readInt());
     }
 
+    /**
+     * Read a 64 bit double index is increased by 8
+     *
+     * @return double
+     */
     public double readDouble() {
         return java.lang.Double.longBitsToDouble(readLong());
     }
 
+    /**
+     * Read a byte buffer bytes are encoded as 4 byte length followed by length bytes index is
+     * increased by 4 + number of bytes
+     *
+     * @return byte array
+     */
     public @NonNull byte[] readBuffer() {
         int count = readInt();
         byte[] b = Arrays.copyOfRange(mBuffer, mIndex, mIndex + count);
@@ -175,6 +279,13 @@
         return b;
     }
 
+    /**
+     * Read a byte buffer limited to max size. bytes are encoded as 4 byte length followed by length
+     * bytes index is increased by 4 + number of bytes Throw an exception if the read excedes the
+     * max size. This is the preferred form of read buffer.
+     *
+     * @return byte array
+     */
     public @NonNull byte[] readBuffer(int maxSize) {
         int count = readInt();
         if (count < 0 || count > maxSize) {
@@ -186,12 +297,23 @@
         return b;
     }
 
+    /**
+     * Read a string encoded in UTF8 The buffer is red with readBuffer and converted to a String
+     *
+     * @return unicode string
+     */
     @NonNull
     public String readUTF8() {
         byte[] stringBuffer = readBuffer();
         return new String(stringBuffer);
     }
 
+    /**
+     * Read a string encoded in UTF8 The buffer is red with readBuffer and converted to a String
+     * This is the preferred readUTF8 because it catches errors
+     *
+     * @return unicode string
+     */
     @NonNull
     public String readUTF8(int maxSize) {
         byte[] stringBuffer = readBuffer(maxSize);
@@ -202,18 +324,33 @@
     // Write values
     ///////////////////////////////////////////////////////////////////////////
 
+    /**
+     * Write a boolean value. (written as a byte 1=true)
+     *
+     * @param value value to write
+     */
     public void writeBoolean(boolean value) {
         resize(1);
         mBuffer[mIndex++] = (byte) (value ? 1 : 0);
         mSize++;
     }
 
+    /**
+     * Write a byte value
+     *
+     * @param value value to write
+     */
     public void writeByte(int value) {
         resize(1);
         mBuffer[mIndex++] = (byte) value;
         mSize++;
     }
 
+    /**
+     * Write a short value
+     *
+     * @param value value to write
+     */
     public void writeShort(int value) {
         int need = 2;
         resize(need);
@@ -222,6 +359,11 @@
         mSize += need;
     }
 
+    /**
+     * Write a int (4 byte) value
+     *
+     * @param value value to write
+     */
     public void writeInt(int value) {
         int need = 4;
         resize(need);
@@ -232,6 +374,11 @@
         mSize += need;
     }
 
+    /**
+     * Write a long (8 byte) value
+     *
+     * @param value value to write
+     */
     public void writeLong(long value) {
         int need = 8;
         resize(need);
@@ -246,14 +393,29 @@
         mSize += need;
     }
 
+    /**
+     * Write a 32 bit IEEE float value
+     *
+     * @param value value to write
+     */
     public void writeFloat(float value) {
         writeInt(Float.floatToRawIntBits(value));
     }
 
+    /**
+     * Write a 64 bit IEEE double value
+     *
+     * @param value value to write
+     */
     public void writeDouble(double value) {
         writeLong(Double.doubleToRawLongBits(value));
     }
 
+    /**
+     * Write a buffer The buffer length is first written followed by the bytes
+     *
+     * @param b array of bytes write
+     */
     public void writeBuffer(@NonNull byte[] b) {
         resize(b.length + 4);
         writeInt(b.length);
@@ -263,6 +425,11 @@
         mSize += b.length;
     }
 
+    /**
+     * Write a string is encoded as UTF8
+     *
+     * @param content the string to write
+     */
     public void writeUTF8(@NonNull String content) {
         byte[] buffer = content.getBytes();
         writeBuffer(buffer);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java
index 9480076..27ba652 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java
@@ -36,7 +36,7 @@
  * Operation to deal with bitmap data On getting an Image during a draw call the bitmap is
  * compressed and saved in playback the image is decompressed
  */
-public class BitmapData implements Operation, SerializableToString {
+public class BitmapData extends Operation implements SerializableToString {
     private static final int OP_CODE = Operations.DATA_BITMAP;
     private static final String CLASS_NAME = "BitmapData";
     int mImageId;
@@ -85,6 +85,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -119,6 +124,12 @@
         buffer.writeBuffer(bitmap);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int imageId = buffer.readInt();
         int width = buffer.readInt();
@@ -133,6 +144,11 @@
         operations.add(new BitmapData(imageId, width, height, bitmap));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Data Operations", OP_CODE, CLASS_NAME)
                 .description("Bitmap data")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java
index 310b194..5e5e565 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java
@@ -28,7 +28,7 @@
 import java.util.List;
 
 /** Add a click area to the document */
-public class ClickArea implements RemoteComposeOperation {
+public class ClickArea extends Operation implements RemoteComposeOperation {
     private static final int OP_CODE = Operations.CLICK_AREA;
     private static final String CLASS_NAME = "ClickArea";
     int mId;
@@ -118,6 +118,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -141,6 +146,12 @@
         buffer.writeInt(metadata);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         int contentDescription = buffer.readInt();
@@ -154,6 +165,11 @@
         operations.add(clickArea);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Define a region you can click on")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java
index db93829..2fe56d3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java
@@ -69,6 +69,12 @@
         return "ClipPath " + mId + ";";
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int pack = buffer.readInt();
         int id = pack & 0xFFFFF;
@@ -82,6 +88,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -91,6 +102,11 @@
         buffer.writeInt(id);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Intersect the current clip with the path")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java
index df54fb1..defa656 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java
@@ -31,11 +31,22 @@
     public static final int OP_CODE = Operations.CLIP_RECT;
     public static final String CLASS_NAME = "ClipRect";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = ClipRect::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -50,6 +61,11 @@
         apply(buffer, v1, v2, v3, v4);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("Intersect the current clip with rectangle")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
index 34e93f5..d86576d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
@@ -29,12 +29,22 @@
 import java.util.List;
 
 /** Operation that defines a simple Color based on ID Mainly for colors in theming. */
-public class ColorConstant implements Operation {
+public class ColorConstant extends Operation {
     private static final int OP_CODE = Operations.COLOR_CONSTANT;
     private static final String CLASS_NAME = "ColorConstant";
+
+    /** the id of the color */
     public int mColorId;
+
+    /** the color value (AARRGGBB) */
     public int mColor;
 
+    /**
+     * Creat a color constant
+     *
+     * @param colorId id of color
+     * @param color AARRGGBB value
+     */
     public ColorConstant(int colorId, int color) {
         this.mColorId = colorId;
         this.mColor = color;
@@ -56,6 +66,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -73,12 +88,23 @@
         buffer.writeInt(color);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int colorId = buffer.readInt();
         int color = buffer.readInt();
         operations.add(new ColorConstant(colorId, color));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("Define a Color")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java
index c947d11..66f128f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java
@@ -34,7 +34,7 @@
  * Operation to Colors Color modes mMode = 0 two colors and a tween mMode = 1 color1 is a colorID.
  * mMode = 2 color2 is a colorID. mMode = 3 color1 & color2 are ids mMode = 4 H S V mode
  */
-public class ColorExpression implements Operation, VariableSupport {
+public class ColorExpression extends Operation implements VariableSupport {
     private static final int OP_CODE = Operations.COLOR_EXPRESSIONS;
     private static final String CLASS_NAME = "ColorExpression";
     public int mId;
@@ -204,6 +204,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -228,6 +233,12 @@
         buffer.writeFloat(tween);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         int mode = buffer.readInt();
@@ -238,6 +249,11 @@
         operations.add(new ColorExpression(id, mode, color1, color2, tween));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("A Color defined by an expression")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java
index b0ccd187..19c219b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java
@@ -30,7 +30,7 @@
 
 import java.util.List;
 
-public class ComponentValue implements Operation, SerializableToString {
+public class ComponentValue extends Operation implements SerializableToString {
     public static final int OP_CODE = Operations.COMPONENT_VALUE;
     public static final String CLASS_NAME = "ComponentValue";
 
@@ -41,6 +41,11 @@
     private int mComponentID = -1;
     private int mValueId = -1;
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -78,6 +83,12 @@
         // Nothing
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int type = buffer.readInt();
         int componentId = buffer.readInt();
@@ -86,6 +97,11 @@
         operations.add(op);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("Encode a component-related value (eg its width, height etc.)")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java
index bfaf139..ac6271c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java
@@ -32,7 +32,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-public class DataListFloat implements VariableSupport, ArrayAccess, Operation {
+public class DataListFloat extends Operation implements VariableSupport, ArrayAccess {
     private static final int OP_CODE = Operations.FLOAT_LIST;
     private static final String CLASS_NAME = "IdListData";
     private final int mId;
@@ -79,6 +79,12 @@
         }
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         int len = buffer.readInt();
@@ -93,6 +99,11 @@
         operations.add(data);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Data Operations", OP_CODE, CLASS_NAME)
                 .description("a list of Floats")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java
index 9b286b9..47cbff3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java
@@ -33,7 +33,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-public class DataListIds implements VariableSupport, ArrayAccess, Operation {
+public class DataListIds extends Operation implements VariableSupport, ArrayAccess {
     private static final int OP_CODE = Operations.ID_LIST;
     private static final String CLASS_NAME = "IdListData";
     private final int mId;
@@ -71,6 +71,12 @@
         }
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         int len = buffer.readInt();
@@ -85,6 +91,11 @@
         operations.add(data);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Data Operations", OP_CODE, CLASS_NAME)
                 .description("a list of id's")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java
index 643afc8..e888074 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java
@@ -31,7 +31,7 @@
 import java.util.List;
 
 /** This is a map of strings to type & Id */
-public class DataMapIds implements Operation {
+public class DataMapIds extends Operation {
     private static final int OP_CODE = Operations.ID_MAP;
     private static final String CLASS_NAME = "DataMapIds";
     int mId;
@@ -105,6 +105,12 @@
         }
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         int len = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java
index eae532c..9af2343 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java
@@ -31,7 +31,7 @@
 import java.util.List;
 
 /** This can lookup in a map given a string writing the results to an id. */
-public class DataMapLookup implements Operation {
+public class DataMapLookup extends Operation {
     private static final int OP_CODE = Operations.DATA_MAP_LOOKUP;
     private static final String CLASS_NAME = "DataMapLookup";
     public int mId;
@@ -109,12 +109,17 @@
         operations.add(new DataMapLookup(id, mapId, stringId));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
-                .description("A float and its associated id")
+                .description("Look up a value in a data map")
                 .field(INT, "id", "id of float")
                 .field(INT, "dataMapId", "32-bit float value")
-                .field(INT, "value", "32-bit float value");
+                .field(INT, "stringId", "32-bit float value");
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java
index 629f786..3f95f02 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java
@@ -30,11 +30,22 @@
     public static final int OP_CODE = Operations.DRAW_ARC;
     private static final String CLASS_NAME = "DrawArc";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = DrawArc::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -79,6 +90,11 @@
         apply(buffer, v1, v2, v3, v4, v5, v6);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description(
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java
index 9c23c95..69f5cc5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java
@@ -100,15 +100,21 @@
                 + ";";
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         float sLeft = buffer.readFloat();
         float srcTop = buffer.readFloat();
         float srcRight = buffer.readFloat();
         float srcBottom = buffer.readFloat();
-        int discriptionId = buffer.readInt();
+        int descriptionId = buffer.readInt();
 
-        DrawBitmap op = new DrawBitmap(id, sLeft, srcTop, srcRight, srcBottom, discriptionId);
+        DrawBitmap op = new DrawBitmap(id, sLeft, srcTop, srcRight, srcBottom, descriptionId);
         operations.add(op);
     }
 
@@ -117,6 +123,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -138,6 +149,11 @@
         buffer.writeInt(descriptionId);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
                 .description("Draw a bitmap")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java
index da9fe24..66646d7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java
@@ -111,6 +111,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -140,6 +145,12 @@
         buffer.writeInt(cdId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int imageId = buffer.readInt();
         int sLeft = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java
index e9f81d5..1701486 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java
@@ -196,6 +196,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -232,6 +237,12 @@
         buffer.writeInt(cdId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int imageId = buffer.readInt();
 
@@ -265,6 +276,11 @@
         operations.add(op);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
                 .description("Draw a bitmap using integer coordinates")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java
index 11bd49a..e6aecdb 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java
@@ -30,11 +30,22 @@
     private static final int OP_CODE = Operations.DRAW_CIRCLE;
     private static final String CLASS_NAME = "DrawCircle";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = DrawCircle::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -44,6 +55,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Draw a Circle")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java
index 7310a9d..04f3264 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java
@@ -32,11 +32,22 @@
     private static final int OP_CODE = Operations.DRAW_LINE;
     private static final String CLASS_NAME = "DrawLine";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = DrawLine::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -46,6 +57,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Draw a line segment")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java
index aa5116e..0a50042 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java
@@ -30,11 +30,22 @@
     private static final int OP_CODE = Operations.DRAW_OVAL;
     private static final String CLASS_NAME = "DrawOval";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = DrawOval::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -44,6 +55,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Draw the specified oval")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java
index d35094b..41b8243 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java
@@ -50,6 +50,12 @@
         return "DrawPath " + "[" + mId + "]" + ", " + mStart + ", " + mEnd;
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         DrawPath op = new DrawPath(id);
@@ -61,6 +67,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.DRAW_PATH;
     }
@@ -70,6 +81,11 @@
         buffer.writeInt(id);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
                 .description("Draw a bitmap using integer coordinates")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java
index db7633c..7e22550 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java
@@ -31,11 +31,22 @@
     private static final int OP_CODE = Operations.DRAW_RECT;
     private static final String CLASS_NAME = "DrawRect";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = DrawRect::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -45,6 +56,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Draw the specified rectangle")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java
index c306e2b..a41e46e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java
@@ -31,11 +31,22 @@
     private static final int OP_CODE = Operations.DRAW_ROUND_RECT;
     private static final String CLASS_NAME = "DrawRoundRect";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = DrawRoundRect::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -80,6 +91,11 @@
         apply(buffer, v1, v2, v3, v4, v5, v6);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Draw the specified round-rect")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java
index 3b60df7..7616df0 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java
@@ -30,11 +30,22 @@
     public static final int OP_CODE = Operations.DRAW_SECTOR;
     private static final String CLASS_NAME = "DrawSector";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = DrawSector::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -79,6 +90,11 @@
         apply(buffer, v1, v2, v3, v4, v5, v6);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description(
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java
index 9c587ab..2c5d790 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java
@@ -101,6 +101,12 @@
                 + floatToString(mY, mOutY);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int text = buffer.readInt();
         int start = buffer.readInt();
@@ -120,6 +126,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -158,6 +169,11 @@
         buffer.writeBoolean(rtl);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Draw Operations", id(), CLASS_NAME)
                 .description("Draw a run of text, all in a single direction")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java
index 8b70181..7de52b8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java
@@ -111,6 +111,12 @@
         return Float.toString(v);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int textID = buffer.readInt();
         float x = buffer.readFloat();
@@ -129,6 +135,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -161,6 +172,11 @@
         buffer.writeInt(flags);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
                 .description("Draw text centered about an anchor point")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java
index e90122b..18d9fdf 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java
@@ -83,6 +83,12 @@
                 + Utils.floatToString(mVOffset, mOutVOffset);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int textId = buffer.readInt();
         int pathId = buffer.readInt();
@@ -97,6 +103,11 @@
         return "DrawTextOnPath";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.DRAW_TEXT_ON_PATH;
     }
@@ -110,6 +121,11 @@
         buffer.writeFloat(hOffset);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
                 .description("Draw text along path object")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java
index 0aaaf42..b83e4c2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java
@@ -92,6 +92,12 @@
                 + floatToString(mStop, mOutStop);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int path1Id = buffer.readInt();
         int path2Id = buffer.readInt();
@@ -107,6 +113,11 @@
         return "DrawTweenPath";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.DRAW_TWEEN_PATH;
     }
@@ -126,6 +137,11 @@
         buffer.writeFloat(stop);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
                 .description("Draw text along path object")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java
index 17aaf3b..7dd435a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java
@@ -29,7 +29,7 @@
 import java.util.List;
 
 /** Operation to deal with Text data */
-public class FloatConstant implements com.android.internal.widget.remotecompose.core.Operation {
+public class FloatConstant extends Operation {
     private static final int OP_CODE = Operations.DATA_FLOAT;
     private static final String CLASS_NAME = "FloatConstant";
     public int mTextId;
@@ -56,6 +56,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -73,6 +78,12 @@
         buffer.writeFloat(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int textId = buffer.readInt();
 
@@ -80,6 +91,11 @@
         operations.add(new FloatConstant(textId, value));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("A float and its associated id")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
index eef9746..3d92e12 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
@@ -42,7 +42,7 @@
  * like injecting the width of the component int draw rect As well as supporting generalized
  * animation floats. The floats represent a RPN style calculator
  */
-public class FloatExpression implements Operation, VariableSupport {
+public class FloatExpression extends Operation implements VariableSupport {
     private static final int OP_CODE = Operations.ANIMATED_FLOAT;
     private static final String CLASS_NAME = "FloatExpression";
     public int mId;
@@ -146,16 +146,19 @@
         if (Float.isNaN(mLastChange)) {
             mLastChange = t;
         }
-        if (mFloatAnimation != null) {
+        if (mFloatAnimation != null && !Float.isNaN(mLastCalculatedValue)) {
             float f = mFloatAnimation.get(t - mLastChange);
             context.loadFloat(mId, f);
         } else if (mSpring != null) {
             float f = mSpring.get(t - mLastChange);
             context.loadFloat(mId, f);
         } else {
-            context.loadFloat(
-                    mId,
-                    mExp.eval(context.getCollectionsAccess(), mPreCalcValue, mPreCalcValue.length));
+            float v =
+                    mExp.eval(context.getCollectionsAccess(), mPreCalcValue, mPreCalcValue.length);
+            if (mFloatAnimation != null) {
+                mFloatAnimation.setTargetValue(v);
+            }
+            context.loadFloat(mId, v);
         }
     }
 
@@ -207,6 +210,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -243,12 +251,18 @@
         }
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         int len = buffer.readInt();
         int valueLen = len & 0xFFFF;
         if (valueLen > MAX_EXPRESSION_SIZE) {
-            throw new RuntimeException("Float expression to long");
+            throw new RuntimeException("Float expression too long");
         }
         int animLen = (len >> 16) & 0xFFFF;
         float[] values = new float[valueLen];
@@ -268,6 +282,11 @@
         operations.add(new FloatExpression(id, values, animation));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("A Float expression")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
index 009aa03..04e4346 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
@@ -35,7 +35,7 @@
  * <p>It encodes the version of the document (following semantic versioning) as well as the
  * dimensions of the document in pixels.
  */
-public class Header implements RemoteComposeOperation {
+public class Header extends Operation implements RemoteComposeOperation {
     private static final int OP_CODE = Operations.HEADER;
     private static final String CLASS_NAME = "Header";
     public static final int MAJOR_VERSION = 0;
@@ -120,6 +120,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -136,6 +141,12 @@
         buffer.writeLong(capabilities);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int majorVersion = buffer.readInt();
         int minorVersion = buffer.readInt();
@@ -157,6 +168,11 @@
         operations.add(header);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Protocol Operations", OP_CODE, CLASS_NAME)
                 .description(
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java
index c49f74d..67274af 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java
@@ -38,7 +38,7 @@
  * like injecting the width of the component int draw rect As well as supporting generalized
  * animation floats. The floats represent a RPN style calculator
  */
-public class IntegerExpression implements Operation, VariableSupport {
+public class IntegerExpression extends Operation implements VariableSupport {
     private static final int OP_CODE = Operations.INTEGER_EXPRESSION;
     private static final String CLASS_NAME = "IntegerExpression";
     public int mId;
@@ -141,6 +141,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -163,6 +168,12 @@
         }
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         int mask = buffer.readInt();
@@ -178,6 +189,11 @@
         operations.add(new IntegerExpression(id, mask, values));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Data Operations", OP_CODE, CLASS_NAME)
                 .description("Expression that computes an integer")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java
index 4e7ee4d..aed597a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java
@@ -37,6 +37,12 @@
         apply(buffer);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         MatrixRestore op = new MatrixRestore();
         operations.add(op);
@@ -53,6 +59,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -61,6 +72,11 @@
         buffer.start(OP_CODE);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Restore the matrix and clip");
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java
index 438a2aa..fece143 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java
@@ -30,6 +30,12 @@
     public static final int OP_CODE = Operations.MATRIX_ROTATE;
     private static final String CLASS_NAME = "MatrixRotate";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m =
                 new Maker() {
@@ -42,6 +48,11 @@
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -51,6 +62,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("apply rotation to matrix")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java
index 09f54a5..7eb7b3f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java
@@ -41,6 +41,12 @@
         return "MatrixSave;";
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         MatrixSave op = new MatrixSave();
         operations.add(op);
@@ -51,6 +57,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -59,6 +70,11 @@
         buffer.start(Operations.MATRIX_SAVE);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Save the matrix and clip to a stack");
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java
index 6304584..49bdd1b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java
@@ -30,11 +30,22 @@
     public static final int OP_CODE = Operations.MATRIX_SCALE;
     public static final String CLASS_NAME = "MatrixScale";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = MatrixScale::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -49,9 +60,14 @@
         apply(buffer, v1, v2, v3, v4);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
-                .description("Draw the specified Oval")
+                .description("Scale the following draw commands")
                 .field(DocumentedOperation.FLOAT, "scaleX", "The amount to scale in X")
                 .field(DocumentedOperation.FLOAT, "scaleY", "The amount to scale in Y")
                 .field(DocumentedOperation.FLOAT, "pivotX", "The x-coordinate for the pivot point")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java
index 675cf0d..54b6fd1 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java
@@ -31,11 +31,22 @@
     public static final int OP_CODE = Operations.MATRIX_SKEW;
     public static final String CLASS_NAME = "MatrixSkew";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = MatrixSkew::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -50,6 +61,11 @@
         apply(buffer, v1, v2);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
                 .description("Current matrix with the specified skew.")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java
index b0a7d35..b57d83b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java
@@ -30,11 +30,22 @@
     public static final int OP_CODE = Operations.MATRIX_TRANSLATE;
     public static final String CLASS_NAME = "MatrixTranslate";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = MatrixTranslate::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -49,6 +60,11 @@
         apply(buffer, v1, v2);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Canvas Operations", OP_CODE, "MatrixTranslate")
                 .description("Preconcat the current matrix with the specified translation")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
index 5ca91af..3c82f2b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
@@ -30,7 +30,7 @@
 import java.util.List;
 
 /** Operation to deal with Text data */
-public class NamedVariable implements Operation {
+public class NamedVariable extends Operation {
     private static final int OP_CODE = Operations.NAMED_VARIABLE;
     private static final String CLASS_NAME = "NamedVariable";
     public final int mVarId;
@@ -69,6 +69,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -89,6 +94,12 @@
         buffer.writeUTF8(text);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int varId = buffer.readInt();
         int varType = buffer.readInt();
@@ -96,6 +107,11 @@
         operations.add(new NamedVariable(varId, varType, text));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Data Operations", OP_CODE, CLASS_NAME)
                 .description("Add a string name for an ID")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java
index b24df8a..3c0a842 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java
@@ -66,6 +66,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -75,6 +80,12 @@
         paintBundle.writeBundle(buffer);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         PaintData data = new PaintData();
         data.mPaintData.readBundle(buffer);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java
new file mode 100644
index 0000000..2b00001
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java
@@ -0,0 +1,230 @@
+/*
+ * 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.internal.widget.remotecompose.core.operations;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY;
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class PathAppend extends PaintOperation implements VariableSupport {
+    private static final int OP_CODE = Operations.PATH_ADD;
+    private static final String CLASS_NAME = "PathAppend";
+    int mInstanceId;
+    float[] mFloatPath;
+    float[] mOutputPath;
+
+    PathAppend(int instanceId, float[] floatPath) {
+        mInstanceId = instanceId;
+        mFloatPath = floatPath;
+        mOutputPath = Arrays.copyOf(mFloatPath, mFloatPath.length);
+    }
+
+    @Override
+    public void updateVariables(@NonNull RemoteContext context) {
+        for (int i = 0; i < mFloatPath.length; i++) {
+            float v = mFloatPath[i];
+            if (Utils.isVariable(v)) {
+                mOutputPath[i] = Float.isNaN(v) ? context.getFloat(Utils.idFromNan(v)) : v;
+            } else {
+                mOutputPath[i] = v;
+            }
+        }
+    }
+
+    @Override
+    public void registerListening(@NonNull RemoteContext context) {
+        for (float v : mFloatPath) {
+            if (Float.isNaN(v)) {
+                context.listensTo(Utils.idFromNan(v), this);
+            }
+        }
+    }
+
+    @Override
+    public void write(@NonNull WireBuffer buffer) {
+        apply(buffer, mInstanceId, mOutputPath);
+    }
+
+    @NonNull
+    @Override
+    public String deepToString(String indent) {
+        return PathData.pathString(mFloatPath);
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "PathAppend[" + mInstanceId + "] += " + "\"" + pathString(mOutputPath) + "\"";
+    }
+
+    /**
+     * public float[] getFloatPath(PaintContext context) { float[] ret = mRetFloats; // Assume
+     * retFloats is declared elsewhere if (ret == null) { return mFloatPath; // Assume floatPath is
+     * declared elsewhere } float[] localRef = mRef; // Assume ref is of type Float[] if (localRef
+     * == null) { for (int i = 0; i < mFloatPath.length; i++) { ret[i] = mFloatPath[i]; } } else {
+     * for (int i = 0; i < mFloatPath.length; i++) { float lr = localRef[i]; if (Float.isNaN(lr)) {
+     * ret[i] = Utils.getActualValue(lr); } else { ret[i] = mFloatPath[i]; } } } return ret; }
+     */
+    public static final int MOVE = 10;
+
+    public static final int LINE = 11;
+    public static final int QUADRATIC = 12;
+    public static final int CONIC = 13;
+    public static final int CUBIC = 14;
+    public static final int CLOSE = 15;
+    public static final int DONE = 16;
+    public static final float MOVE_NAN = Utils.asNan(MOVE);
+    public static final float LINE_NAN = Utils.asNan(LINE);
+    public static final float QUADRATIC_NAN = Utils.asNan(QUADRATIC);
+    public static final float CONIC_NAN = Utils.asNan(CONIC);
+    public static final float CUBIC_NAN = Utils.asNan(CUBIC);
+    public static final float CLOSE_NAN = Utils.asNan(CLOSE);
+    public static final float DONE_NAN = Utils.asNan(DONE);
+
+    @NonNull
+    public static String name() {
+        return CLASS_NAME;
+    }
+
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
+    public static int id() {
+        return OP_CODE;
+    }
+
+    public static void apply(@NonNull WireBuffer buffer, int id, @NonNull float[] data) {
+        buffer.start(OP_CODE);
+        buffer.writeInt(id);
+        buffer.writeInt(data.length);
+        for (float datum : data) {
+            buffer.writeFloat(datum);
+        }
+    }
+
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
+    public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+        int id = buffer.readInt();
+        int len = buffer.readInt();
+        float[] data = new float[len];
+        for (int i = 0; i < data.length; i++) {
+            data[i] = buffer.readFloat();
+        }
+        operations.add(new PathAppend(id, data));
+    }
+
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
+    public static void documentation(@NonNull DocumentationBuilder doc) {
+        doc.operation("Data Operations", OP_CODE, CLASS_NAME)
+                .description("Append to a Path")
+                .field(DocumentedOperation.INT, "id", "id string")
+                .field(INT, "length", "id string")
+                .field(FLOAT_ARRAY, "pathData", "length", "path encoded as floats");
+    }
+
+    @Override
+    public void paint(PaintContext context) {}
+
+    @Override
+    public void apply(@NonNull RemoteContext context) {
+        updateVariables(context);
+        float[] data = context.getPathData(mInstanceId);
+        float[] out = mOutputPath;
+        if (data != null) {
+            out = new float[data.length + mOutputPath.length];
+
+            for (int i = 0; i < data.length; i++) {
+                out[i] = data[i];
+            }
+            for (int i = 0; i < mOutputPath.length; i++) {
+                out[i + data.length] = mOutputPath[i];
+            }
+        } else {
+            System.out.println(">>>>>>>>>>> DATA IS NULL");
+        }
+        context.loadPathData(mInstanceId, out);
+    }
+
+    @NonNull
+    public static String pathString(@Nullable float[] path) {
+        if (path == null) {
+            return "null";
+        }
+        StringBuilder str = new StringBuilder();
+        for (int i = 0; i < path.length; i++) {
+            if (Float.isNaN(path[i])) {
+                int id = Utils.idFromNan(path[i]); // Assume idFromNan is defined elsewhere
+                if (id <= DONE) { // Assume DONE is a constant
+                    switch (id) {
+                        case MOVE:
+                            str.append("M");
+                            break;
+                        case LINE:
+                            str.append("L");
+                            break;
+                        case QUADRATIC:
+                            str.append("Q");
+                            break;
+                        case CONIC:
+                            str.append("R");
+                            break;
+                        case CUBIC:
+                            str.append("C");
+                            break;
+                        case CLOSE:
+                            str.append("Z");
+                            break;
+                        case DONE:
+                            str.append(".");
+                            break;
+                        default:
+                            str.append("[" + id + "]");
+                            break;
+                    }
+                } else {
+                    str.append("(" + id + ")");
+                }
+            }
+        }
+        return str.toString();
+    }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java
new file mode 100644
index 0000000..b62f36b
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java
@@ -0,0 +1,206 @@
+/*
+ * 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.internal.widget.remotecompose.core.operations;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class PathCreate extends PaintOperation implements VariableSupport {
+    private static final int OP_CODE = Operations.PATH_CREATE;
+    private static final String CLASS_NAME = "PathCreate";
+    int mInstanceId;
+    float[] mFloatPath;
+    float[] mOutputPath;
+
+    PathCreate(int instanceId, float startX, float startY) {
+        mInstanceId = instanceId;
+        mFloatPath = new float[] {PathData.MOVE_NAN, startX, startY};
+        mOutputPath = Arrays.copyOf(mFloatPath, mFloatPath.length);
+    }
+
+    @Override
+    public void updateVariables(@NonNull RemoteContext context) {
+        for (int i = 0; i < mFloatPath.length; i++) {
+            float v = mFloatPath[i];
+            if (Utils.isVariable(v)) {
+                mOutputPath[i] = Float.isNaN(v) ? context.getFloat(Utils.idFromNan(v)) : v;
+            } else {
+                mOutputPath[i] = v;
+            }
+        }
+    }
+
+    @Override
+    public void registerListening(@NonNull RemoteContext context) {
+        for (float v : mFloatPath) {
+            if (Float.isNaN(v)) {
+                context.listensTo(Utils.idFromNan(v), this);
+            }
+        }
+    }
+
+    @Override
+    public void write(@NonNull WireBuffer buffer) {
+        apply(buffer, mInstanceId, mFloatPath[1], mFloatPath[2]);
+    }
+
+    @NonNull
+    @Override
+    public String deepToString(String indent) {
+        return pathString(mFloatPath);
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "PathCreate[" + mInstanceId + "] = " + "\"" + deepToString(" ") + "\"";
+    }
+
+    public static final int MOVE = 10;
+    public static final int LINE = 11;
+    public static final int QUADRATIC = 12;
+    public static final int CONIC = 13;
+    public static final int CUBIC = 14;
+    public static final int CLOSE = 15;
+    public static final int DONE = 16;
+    public static final float MOVE_NAN = Utils.asNan(MOVE);
+    public static final float LINE_NAN = Utils.asNan(LINE);
+    public static final float QUADRATIC_NAN = Utils.asNan(QUADRATIC);
+    public static final float CONIC_NAN = Utils.asNan(CONIC);
+    public static final float CUBIC_NAN = Utils.asNan(CUBIC);
+    public static final float CLOSE_NAN = Utils.asNan(CLOSE);
+    public static final float DONE_NAN = Utils.asNan(DONE);
+
+    @NonNull
+    public static String name() {
+        return CLASS_NAME;
+    }
+
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
+    public static int id() {
+        return OP_CODE;
+    }
+
+    public static void apply(@NonNull WireBuffer buffer, int id, float startX, float startY) {
+        buffer.start(OP_CODE);
+        buffer.writeInt(id);
+        buffer.writeFloat(startX);
+        buffer.writeFloat(startY);
+    }
+
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
+    public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+
+        int id = buffer.readInt();
+        float startX = buffer.readFloat();
+        float startY = buffer.readFloat();
+        operations.add(new PathCreate(id, startX, startY));
+    }
+
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
+    public static void documentation(@NonNull DocumentationBuilder doc) {
+        doc.operation("Data Operations", OP_CODE, CLASS_NAME)
+                .description("Encode a Path ")
+                .field(DocumentedOperation.INT, "id", "id of path")
+                .field(FLOAT, "startX", "initial start x")
+                .field(FLOAT, "startX", "initial start y");
+    }
+
+    @NonNull
+    public static String pathString(@Nullable float[] path) {
+        if (path == null) {
+            return "null";
+        }
+        StringBuilder str = new StringBuilder();
+        for (int i = 0; i < path.length; i++) {
+            if (i != 0) {
+                str.append(" ");
+            }
+            if (Float.isNaN(path[i])) {
+                int id = Utils.idFromNan(path[i]); // Assume idFromNan is defined elsewhere
+                if (id <= DONE) { // Assume DONE is a constant
+                    switch (id) {
+                        case MOVE:
+                            str.append("M");
+                            break;
+                        case LINE:
+                            str.append("L");
+                            break;
+                        case QUADRATIC:
+                            str.append("Q");
+                            break;
+                        case CONIC:
+                            str.append("R");
+                            break;
+                        case CUBIC:
+                            str.append("C");
+                            break;
+                        case CLOSE:
+                            str.append("Z");
+                            break;
+                        case DONE:
+                            str.append(".");
+                            break;
+                        default:
+                            str.append("[" + id + "]");
+                            break;
+                    }
+                } else {
+                    str.append("(" + id + ")");
+                }
+            } else {
+                str.append(path[i]);
+            }
+        }
+        return str.toString();
+    }
+
+    @Override
+    public void paint(PaintContext context) {}
+
+    @Override
+    public void apply(@NonNull RemoteContext context) {
+        context.loadPathData(mInstanceId, mOutputPath);
+    }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
index 509f362..4ec5436 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
@@ -32,7 +32,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-public class PathData implements Operation, VariableSupport {
+public class PathData extends Operation implements VariableSupport {
     private static final int OP_CODE = Operations.DATA_PATH;
     private static final String CLASS_NAME = "PathData";
     int mInstanceId;
@@ -112,6 +112,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -125,6 +130,12 @@
         }
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int imageId = buffer.readInt();
         int len = buffer.readInt();
@@ -135,6 +146,11 @@
         operations.add(new PathData(imageId, data));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Data Operations", OP_CODE, CLASS_NAME)
                 .description("Encode a Path ")
@@ -143,6 +159,12 @@
                 .field(FLOAT_ARRAY, "pathData", "length", "path encoded as floats");
     }
 
+    /**
+     * Render a path as a string
+     *
+     * @param path path as a array of floats
+     * @return string describing the path
+     */
     @NonNull
     public static String pathString(@Nullable float[] path) {
         if (path == null) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathTween.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathTween.java
new file mode 100644
index 0000000..a6fa680
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathTween.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString;
+
+import android.annotation.NonNull;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+
+import java.util.List;
+
+/** Operation to deal with Path data */
+public class PathTween extends PaintOperation implements VariableSupport {
+    private static final int OP_CODE = Operations.PATH_TWEEN;
+    private static final String CLASS_NAME = "PathTween";
+    public int mOutId;
+    public int mPathId1;
+    public int mPathId2;
+    public float mTween;
+    public float mTweenOut;
+
+    public PathTween(int outId, int pathId1, int pathId2, float tween) {
+        this.mOutId = outId;
+        this.mPathId1 = pathId1;
+        this.mPathId2 = pathId2;
+        this.mTween = tween;
+        this.mTweenOut = mTween;
+    }
+
+    @Override
+    public void updateVariables(@NonNull RemoteContext context) {
+        mTweenOut = Float.isNaN(mTween) ? context.getFloat(Utils.idFromNan(mTween)) : mTween;
+    }
+
+    @Override
+    public void registerListening(@NonNull RemoteContext context) {
+        if (Float.isNaN(mTween)) {
+            context.listensTo(Utils.idFromNan(mTween), this);
+        }
+    }
+
+    @Override
+    public void write(@NonNull WireBuffer buffer) {
+        apply(buffer, mOutId, mPathId1, mPathId2, mTween);
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "PathTween["
+                + mOutId
+                + "] = ["
+                + mPathId1
+                + " ] + [ "
+                + mPathId2
+                + "], "
+                + floatToString(mTween, mTweenOut);
+    }
+
+    @NonNull
+    public static String name() {
+        return CLASS_NAME;
+    }
+
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
+    public static int id() {
+        return OP_CODE;
+    }
+
+    /**
+     * Writes out the operation to the buffer
+     *
+     * @param buffer buffer to write to
+     * @param outId id of the path
+     * @param pathId1 source path 1
+     * @param pathId2 source path 2
+     * @param tween interpolate between two paths
+     */
+    public static void apply(
+            @NonNull WireBuffer buffer, int outId, int pathId1, int pathId2, float tween) {
+        buffer.start(OP_CODE);
+        buffer.writeInt(outId);
+        buffer.writeInt(pathId1);
+        buffer.writeInt(pathId2);
+        buffer.writeFloat(tween);
+    }
+
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
+    public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+        int outId1 = buffer.readInt();
+        int pathId1 = buffer.readInt();
+        int pathId2 = buffer.readInt();
+        float tween = buffer.readFloat();
+
+        operations.add(new PathTween(outId1, pathId1, pathId2, tween));
+    }
+
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
+    public static void documentation(@NonNull DocumentationBuilder doc) {
+        doc.operation("Data Operations", OP_CODE, CLASS_NAME)
+                .description("Merge two string into one")
+                .field(DocumentedOperation.INT, "pathId", "id of the path")
+                .field(INT, "srcPathId1", "id of the path")
+                .field(INT, "srcPathId1", "x Shift of the path");
+    }
+
+    @NonNull
+    @Override
+    public String deepToString(String indent) {
+        return indent + toString();
+    }
+
+    @Override
+    public void paint(PaintContext context) {
+        context.tweenPath(mOutId, mPathId1, mPathId2, mTweenOut);
+    }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
index 8494126..aaa7176 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
@@ -33,7 +33,7 @@
  * <p>It encodes the version of the document (following semantic versioning) as well as the
  * dimensions of the document in pixels.
  */
-public class RootContentBehavior implements RemoteComposeOperation {
+public class RootContentBehavior extends Operation implements RemoteComposeOperation {
     private static final int OP_CODE = Operations.ROOT_CONTENT_BEHAVIOR;
     private static final String CLASS_NAME = "RootContentBehavior";
     int mScroll = NONE;
@@ -205,6 +205,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -218,6 +223,12 @@
         buffer.writeInt(mode);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int scroll = buffer.readInt();
         int alignment = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
index 109945f..e92daa3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
@@ -28,7 +28,7 @@
 import java.util.List;
 
 /** Describe a content description for the document */
-public class RootContentDescription implements RemoteComposeOperation {
+public class RootContentDescription extends Operation implements RemoteComposeOperation {
     private static final int OP_CODE = Operations.ROOT_CONTENT_DESCRIPTION;
     private static final String CLASS_NAME = "RootContentDescription";
     int mContentDescription;
@@ -69,6 +69,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -78,12 +83,23 @@
         buffer.writeInt(contentDescription);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int contentDescription = buffer.readInt();
         RootContentDescription header = new RootContentDescription(contentDescription);
         operations.add(header);
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Protocol Operations", OP_CODE, CLASS_NAME)
                 .description("Content description of root")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java
index e967ff4..e2502fe 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java
@@ -41,7 +41,7 @@
  * Operation to deal with bitmap data On getting an Image during a draw call the bitmap is
  * compressed and saved in playback the image is decompressed
  */
-public class ShaderData implements Operation, VariableSupport {
+public class ShaderData extends Operation implements VariableSupport {
     private static final int OP_CODE = Operations.DATA_SHADER;
     private static final String CLASS_NAME = "ShaderData";
     int mShaderTextId; // the actual text of a shader
@@ -203,6 +203,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -266,6 +271,12 @@
         }
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int shaderID = buffer.readInt();
         int shaderTextId = buffer.readInt();
@@ -318,6 +329,11 @@
         operations.add(new ShaderData(shaderID, shaderTextId, floatMap, intMap, bitmapMap));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Data Operations", OP_CODE, CLASS_NAME)
                 .description("Shader")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java
index ade008e..3f679bf 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java
@@ -31,7 +31,7 @@
 import java.util.List;
 
 /** Operation to deal with Text data */
-public class TextData implements Operation, SerializableToString {
+public class TextData extends Operation implements SerializableToString {
     private static final int OP_CODE = Operations.DATA_TEXT;
     private static final String CLASS_NAME = "TextData";
     public final int mTextId;
@@ -59,6 +59,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -69,6 +74,12 @@
         buffer.writeUTF8(text);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int textId = buffer.readInt();
 
@@ -76,6 +87,11 @@
         operations.add(new TextData(textId, text));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Data Operations", OP_CODE, CLASS_NAME)
                 .description("Encode a string ")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java
index 865ee81f..4d01e0c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java
@@ -36,7 +36,7 @@
  * [command][textID][before,after][flags] before and after define number of digits before and after
  * the decimal point
  */
-public class TextFromFloat implements Operation, VariableSupport {
+public class TextFromFloat extends Operation implements VariableSupport {
     private static final int OP_CODE = Operations.TEXT_FROM_FLOAT;
     private static final String CLASS_NAME = "TextFromFloat";
     public int mTextId;
@@ -127,6 +127,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -155,6 +160,12 @@
         buffer.writeInt(flags);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int textId = buffer.readInt();
         float value = buffer.readFloat();
@@ -166,6 +177,11 @@
         operations.add(new TextFromFloat(textId, value, pre, post, flags));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("Draw text along path object")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java
index 6ff687b..37ea567 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java
@@ -28,7 +28,7 @@
 import java.util.List;
 
 /** Operation to measure the length of the text */
-public class TextLength implements Operation {
+public class TextLength extends Operation {
     private static final int OP_CODE = Operations.TEXT_LENGTH;
     private static final String CLASS_NAME = "TextLength";
     public int mLengthId;
@@ -54,6 +54,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -71,12 +76,23 @@
         buffer.writeInt(textId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int lengthId = buffer.readInt();
         int textId = buffer.readInt();
         operations.add(new TextLength(lengthId, textId));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("get the length of the text and store in float table")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java
index cc812a8..3ec6f01 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java
@@ -34,7 +34,7 @@
  * [command][textID][before,after][flags] before and after define number of digits before and after
  * the decimal point
  */
-public class TextLookup implements Operation, VariableSupport {
+public class TextLookup extends Operation implements VariableSupport {
     private static final int OP_CODE = Operations.TEXT_LOOKUP;
     private static final String CLASS_NAME = "TextFromFloat";
     public int mTextId;
@@ -84,6 +84,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -103,6 +108,12 @@
         buffer.writeFloat(index);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int textId = buffer.readInt();
         int dataSetId = buffer.readInt();
@@ -110,6 +121,11 @@
         operations.add(new TextLookup(textId, dataSetId, index));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("Look an array and turn into a text object")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java
index 74be698..9c0ee53 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java
@@ -30,7 +30,7 @@
 import java.util.List;
 
 /** Operation convert int index of a list to text */
-public class TextLookupInt implements Operation, VariableSupport {
+public class TextLookupInt extends Operation implements VariableSupport {
     private static final int OP_CODE = Operations.TEXT_LOOKUP_INT;
     private static final String CLASS_NAME = "TextFromINT";
     public int mTextId;
@@ -77,6 +77,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -96,6 +101,12 @@
         buffer.writeInt(indexId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int textId = buffer.readInt();
         int dataSetId = buffer.readInt();
@@ -103,6 +114,11 @@
         operations.add(new TextLookupInt(textId, dataSetId, indexId));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("Look up an array and turn into a text object")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java
index 6d48f67..d51b389 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java
@@ -70,6 +70,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -89,6 +94,12 @@
         buffer.writeInt(type);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         int textId = buffer.readInt();
@@ -96,9 +107,14 @@
         operations.add(new TextMeasure(id, textId, type));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
-                .description("A float and its associated id")
+                .description("Measure text")
                 .field(INT, "id", "id of float result of the measure")
                 .field(INT, "textId", "id of text")
                 .field(INT, "type", "type: measure 0=width,1=height");
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java
index ecd5baa..5b0c38f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java
@@ -29,7 +29,7 @@
 import java.util.List;
 
 /** Operation to deal with Text data */
-public class TextMerge implements Operation {
+public class TextMerge extends Operation {
     private static final int OP_CODE = Operations.TEXT_MERGE;
     private static final String CLASS_NAME = "TextMerge";
     public int mTextId;
@@ -58,6 +58,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -77,6 +82,12 @@
         buffer.writeInt(srcId2);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int textId = buffer.readInt();
         int srcId1 = buffer.readInt();
@@ -85,6 +96,11 @@
         operations.add(new TextMerge(textId, srcId1, srcId2));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Data Operations", OP_CODE, CLASS_NAME)
                 .description("Merge two string into one")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
index d265070..e329c38d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
@@ -33,7 +33,7 @@
  * "tag" the subsequent operations to a given theme. On playback, we can then filter operations
  * depending on the chosen theme.
  */
-public class Theme implements RemoteComposeOperation {
+public class Theme extends Operation implements RemoteComposeOperation {
     private static final int OP_CODE = Operations.THEME;
     private static final String CLASS_NAME = "Theme";
     int mTheme;
@@ -77,6 +77,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -86,11 +91,22 @@
         buffer.writeInt(theme);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int theme = buffer.readInt();
         operations.add(new Theme(theme));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Protocol Operations", OP_CODE, CLASS_NAME)
                 .description("Set a theme")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
index 1bb7b2a..e2e20bc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
@@ -42,12 +42,12 @@
  * touch behaviours. Including animating to Notched, positions. and tweaking the dynamics of the
  * animation.
  */
-public class TouchExpression implements Operation, VariableSupport, TouchListener {
+public class TouchExpression extends Operation implements VariableSupport, TouchListener {
     private static final int OP_CODE = Operations.TOUCH_EXPRESSION;
     private static final String CLASS_NAME = "TouchExpression";
     private float mDefValue;
     private float mOutDefValue;
-    public int mId;
+    private int mId;
     public float[] mSrcExp;
     int mMode = 1; // 0 = delta, 1 = absolute
     float mMax = 1;
@@ -56,11 +56,14 @@
     float mOutMin = 1;
     float mValue = 0;
     boolean mUnmodified = true;
-    public float[] mPreCalcValue;
+    private float[] mPreCalcValue;
     private float mLastChange = Float.NaN;
     private float mLastCalculatedValue = Float.NaN;
     AnimatedFloatExpression mExp = new AnimatedFloatExpression();
+
+    /** The maximum number of floats in the expression */
     public static final int MAX_EXPRESSION_SIZE = 32;
+
     private VelocityEasing mEasyTouch = new VelocityEasing();
     private boolean mEasingToStop = false;
     private float mTouchUpTime = 0;
@@ -495,6 +498,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -505,6 +513,14 @@
      * @param buffer The buffer to write to
      * @param id the id of the resulting float
      * @param value the float expression array
+     * @param min the minimum allowed value
+     * @param max the maximum allowed value
+     * @param velocityId the velocity id
+     * @param touchEffects the type touch effect
+     * @param exp the expression the maps touch drags to movement
+     * @param touchMode the touch mode e.g. notch modes
+     * @param touchSpec the spec of the touch modes
+     * @param easingSpec the spec of when the object comes to an easing
      */
     public static void apply(
             WireBuffer buffer,
@@ -549,7 +565,13 @@
         }
     }
 
-    public static void read(WireBuffer buffer, List<Operation> operations) {
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
+    public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
         float startValue = buffer.readFloat();
         float min = buffer.readFloat();
@@ -594,6 +616,11 @@
                         easingData));
     }
 
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
     public static void documentation(DocumentationBuilder doc) {
         doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
                 .description("A Float expression")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
index baca3e0..de43b90 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
@@ -19,34 +19,60 @@
 
 /** Utilities to be used across all core operations */
 public class Utils {
+    /**
+     * Convert an integer id into a float
+     *
+     * @param v the integer id to convert
+     * @return the id as an float
+     */
     public static float asNan(int v) {
         return Float.intBitsToFloat(v | -0x800000);
     }
 
+    /**
+     * convert a float into an integer id
+     *
+     * @param value the float id to convert
+     * @return the id as an integer
+     */
     public static int idFromNan(float value) {
         int b = Float.floatToRawIntBits(value);
         return b & 0x3FFFFF;
     }
 
+    /**
+     * convert a long into an ID
+     *
+     * @param v the long to convert
+     * @return the id still as a long
+     */
     public static long idFromLong(long v) {
         return v - 0x100000000L;
     }
 
+    /**
+     * convert a float id and turn it into a string
+     *
+     * @param value float to convert
+     * @return string form of an id
+     */
     @NonNull
     public static String idStringFromNan(float value) {
         int b = Float.floatToRawIntBits(value) & 0x3FFFFF;
         return idString(b);
     }
 
+    /**
+     * print an id as a string
+     *
+     * @param b the id
+     * @return the id as a string
+     */
     @NonNull
     public static String idString(int b) {
         return (b > 0xFFFFF) ? "A_" + (b & 0xFFFFF) : "" + b;
     }
 
-    public static float getActualValue(float lr) {
-        return 0;
-    }
-
     /**
      * trim a string to n characters if needing to trim end in "..."
      *
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java
index 7f1d101..0f84059 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java
@@ -18,12 +18,11 @@
 import android.annotation.NonNull;
 
 import com.android.internal.widget.remotecompose.core.CoreDocument;
-import com.android.internal.widget.remotecompose.core.Operation;
 import com.android.internal.widget.remotecompose.core.RemoteContext;
 import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
 
 /** Operations representing actions on the document */
-public interface ActionOperation extends Operation {
+public interface ActionOperation {
     void serializeToString(int indent, @NonNull StringSerializer serializer);
 
     void runAction(
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
index aa8f7580..121b180 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
@@ -46,6 +46,11 @@
         return "CanvasContent";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.LAYOUT_CANVAS_CONTENT;
     }
@@ -61,6 +66,12 @@
         buffer.writeInt(componentId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int componentId = buffer.readInt();
         operations.add(new CanvasContent(componentId, 0, 0, 0, 0, null, -1));
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
index f44e20d..34c4249 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
@@ -182,6 +182,12 @@
         buffer.start(OP_CODE);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         operations.add(new ClickModifierOperation());
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
index fbfc796..faa259f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
@@ -26,7 +26,6 @@
 import com.android.internal.widget.remotecompose.core.SerializableToString;
 import com.android.internal.widget.remotecompose.core.VariableSupport;
 import com.android.internal.widget.remotecompose.core.WireBuffer;
-import com.android.internal.widget.remotecompose.core.operations.BitmapData;
 import com.android.internal.widget.remotecompose.core.operations.ComponentValue;
 import com.android.internal.widget.remotecompose.core.operations.TextData;
 import com.android.internal.widget.remotecompose.core.operations.layout.animation.AnimateMeasure;
@@ -468,11 +467,6 @@
         value[0] += mX;
         value[1] += mY;
         if (mParent != null) {
-            if (mParent instanceof LayoutComponent) {
-                LayoutComponent parent = (LayoutComponent) mParent;
-                value[0] += parent.getMarginLeft() + parent.getPaddingLeft();
-                value[1] += parent.getMarginTop() + parent.getPaddingTop();
-            }
             mParent.getLocationInWindow(value);
         }
     }
@@ -658,12 +652,7 @@
             debugBox(this, context);
         }
         for (Operation op : mList) {
-            if (op instanceof BitmapData) {
-                ((BitmapData) op).apply(context.getContext());
-            }
-            if (op instanceof PaintOperation) {
-                ((PaintOperation) op).paint(context);
-            }
+            op.apply(context.getContext());
         }
         context.restore();
         context.getContext().mLastComponent = prev;
@@ -701,7 +690,7 @@
         if (applyAnimationAsNeeded(context)) {
             return;
         }
-        if (mVisibility == Visibility.GONE) {
+        if (mVisibility == Visibility.GONE || mVisibility == Visibility.INVISIBLE) {
             return;
         }
         paintingComponent(context);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
index 476b73c..396644c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
@@ -25,7 +25,7 @@
 
 import java.util.List;
 
-public class ComponentEnd implements Operation {
+public class ComponentEnd extends Operation {
 
     @Override
     public void write(@NonNull WireBuffer buffer) {
@@ -54,6 +54,11 @@
         return "ComponentEnd";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.COMPONENT_END;
     }
@@ -66,6 +71,12 @@
         return 1 + 4 + 4 + 4;
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         operations.add(new ComponentEnd());
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
index def9f78..a85ae27 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
@@ -28,7 +28,7 @@
 
 import java.util.List;
 
-public class ComponentStart implements ComponentStartOperation {
+public class ComponentStart extends Operation implements ComponentStartOperation {
 
     int mType = DEFAULT;
     float mX;
@@ -162,6 +162,11 @@
         return "ComponentStart";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.COMPONENT_START;
     }
@@ -179,6 +184,12 @@
         return 1 + 4 + 4 + 4;
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int type = buffer.readInt();
         int componentId = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java
index abf2356a..a257d46 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java
@@ -15,6 +15,4 @@
  */
 package com.android.internal.widget.remotecompose.core.operations.layout;
 
-import com.android.internal.widget.remotecompose.core.Operation;
-
-public interface ComponentStartOperation extends Operation {}
+public interface ComponentStartOperation {}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
index 0041582..7b0e4a2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
@@ -19,8 +19,10 @@
 import android.annotation.Nullable;
 
 import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.OperationInterface;
 import com.android.internal.widget.remotecompose.core.PaintContext;
 import com.android.internal.widget.remotecompose.core.operations.BitmapData;
+import com.android.internal.widget.remotecompose.core.operations.FloatExpression;
 import com.android.internal.widget.remotecompose.core.operations.MatrixRestore;
 import com.android.internal.widget.remotecompose.core.operations.MatrixSave;
 import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
@@ -47,12 +49,6 @@
     @Nullable protected ZIndexModifierOperation mZIndexModifier = null;
     @Nullable protected GraphicsLayerModifierOperation mGraphicsLayerModifier = null;
 
-    // Margins
-    protected float mMarginLeft = 0f;
-    protected float mMarginRight = 0f;
-    protected float mMarginTop = 0f;
-    protected float mMarginBottom = 0f;
-
     protected float mPaddingLeft = 0f;
     protected float mPaddingRight = 0f;
     protected float mPaddingTop = 0f;
@@ -76,22 +72,6 @@
         super(parent, componentId, animationId, x, y, width, height);
     }
 
-    public float getMarginLeft() {
-        return mMarginLeft;
-    }
-
-    public float getMarginRight() {
-        return mMarginRight;
-    }
-
-    public float getMarginTop() {
-        return mMarginTop;
-    }
-
-    public float getMarginBottom() {
-        return mMarginBottom;
-    }
-
     public float getPaddingLeft() {
         return mPaddingLeft;
     }
@@ -133,8 +113,7 @@
 
     public void inflate() {
         ArrayList<TextData> data = new ArrayList<>();
-        ArrayList<TouchExpression> touchExpressions = new ArrayList<>();
-        ArrayList<PaintData> paintData = new ArrayList<>();
+        ArrayList<Operation> supportedOperations = new ArrayList<>();
 
         for (Operation op : mList) {
             if (op instanceof LayoutComponentContent) {
@@ -179,10 +158,10 @@
                 mComponentModifiers.add((ModifierOperation) op);
             } else if (op instanceof TextData) {
                 data.add((TextData) op);
-            } else if (op instanceof TouchExpression) {
-                touchExpressions.add((TouchExpression) op);
-            } else if (op instanceof PaintData) {
-                paintData.add((PaintData) op);
+            } else if (op instanceof TouchExpression
+                    || (op instanceof PaintData)
+                    || (op instanceof FloatExpression)) {
+                supportedOperations.add(op);
             } else {
                 // nothing
             }
@@ -190,8 +169,7 @@
 
         mList.clear();
         mList.addAll(data);
-        mList.addAll(touchExpressions);
-        mList.addAll(paintData);
+        mList.addAll(supportedOperations);
         mList.add(mComponentModifiers);
         for (Component c : mChildrenComponents) {
             c.mParent = this;
@@ -203,10 +181,6 @@
 
         mX = 0f;
         mY = 0f;
-        mMarginLeft = 0f;
-        mMarginTop = 0f;
-        mMarginRight = 0f;
-        mMarginBottom = 0f;
         mPaddingLeft = 0f;
         mPaddingTop = 0f;
         mPaddingRight = 0f;
@@ -214,7 +188,7 @@
 
         boolean applyHorizontalMargin = true;
         boolean applyVerticalMargin = true;
-        for (Operation op : mComponentModifiers.getList()) {
+        for (OperationInterface op : mComponentModifiers.getList()) {
             if (op instanceof PaddingModifierOperation) {
                 // We are accumulating padding modifiers to compute the margin
                 // until we hit a dimension; the computed padding for the
@@ -223,31 +197,17 @@
                 float right = ((PaddingModifierOperation) op).getRight();
                 float top = ((PaddingModifierOperation) op).getTop();
                 float bottom = ((PaddingModifierOperation) op).getBottom();
-                if (applyHorizontalMargin) {
-                    mMarginLeft += left;
-                    mMarginRight += right;
-                }
-                if (applyVerticalMargin) {
-                    mMarginTop += top;
-                    mMarginBottom += bottom;
-                }
                 mPaddingLeft += left;
                 mPaddingTop += top;
                 mPaddingRight += right;
                 mPaddingBottom += bottom;
-            }
-            if (op instanceof WidthModifierOperation && mWidthModifier == null) {
+            } else if (op instanceof WidthModifierOperation && mWidthModifier == null) {
                 mWidthModifier = (WidthModifierOperation) op;
-                applyHorizontalMargin = false;
-            }
-            if (op instanceof HeightModifierOperation && mHeightModifier == null) {
+            } else if (op instanceof HeightModifierOperation && mHeightModifier == null) {
                 mHeightModifier = (HeightModifierOperation) op;
-                applyVerticalMargin = false;
-            }
-            if (op instanceof ZIndexModifierOperation) {
+            } else if (op instanceof ZIndexModifierOperation) {
                 mZIndexModifier = (ZIndexModifierOperation) op;
-            }
-            if (op instanceof GraphicsLayerModifierOperation) {
+            } else if (op instanceof GraphicsLayerModifierOperation) {
                 mGraphicsLayerModifier = (GraphicsLayerModifierOperation) op;
             }
         }
@@ -339,7 +299,7 @@
         float s = 0f;
         float e = 0f;
         float w = 0f;
-        for (Operation c : mComponentModifiers.getList()) {
+        for (OperationInterface c : mComponentModifiers.getList()) {
             if (c instanceof WidthModifierOperation) {
                 WidthModifierOperation o = (WidthModifierOperation) c;
                 if (o.getType() == DimensionModifierOperation.Type.EXACT
@@ -366,7 +326,7 @@
     public float computeModifierDefinedPaddingWidth(@NonNull float[] padding) {
         float s = 0f;
         float e = 0f;
-        for (Operation c : mComponentModifiers.getList()) {
+        for (OperationInterface c : mComponentModifiers.getList()) {
             if (c instanceof PaddingModifierOperation) {
                 PaddingModifierOperation pop = (PaddingModifierOperation) c;
                 s += pop.getLeft();
@@ -383,7 +343,7 @@
         float t = 0f;
         float b = 0f;
         float h = 0f;
-        for (Operation c : mComponentModifiers.getList()) {
+        for (OperationInterface c : mComponentModifiers.getList()) {
             if (c instanceof HeightModifierOperation) {
                 HeightModifierOperation o = (HeightModifierOperation) c;
                 if (o.getType() == DimensionModifierOperation.Type.EXACT
@@ -410,7 +370,7 @@
     public float computeModifierDefinedPaddingHeight(@NonNull float[] padding) {
         float t = 0f;
         float b = 0f;
-        for (Operation c : mComponentModifiers.getList()) {
+        for (OperationInterface c : mComponentModifiers.getList()) {
             if (c instanceof PaddingModifierOperation) {
                 PaddingModifierOperation pop = (PaddingModifierOperation) c;
                 t += pop.getTop();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
index 7eea885..20e4688 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
@@ -46,6 +46,11 @@
         return "LayoutContent";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.LAYOUT_CONTENT;
     }
@@ -61,6 +66,12 @@
         buffer.writeInt(componentId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int componentId = buffer.readInt();
         operations.add(new LayoutComponentContent(componentId, 0, 0, 0, 0, null, -1));
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java
index 71de285..d88f711 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java
@@ -25,7 +25,7 @@
 
 import java.util.List;
 
-public class LoopEnd implements Operation {
+public class LoopEnd extends Operation {
 
     @Override
     public void write(@NonNull WireBuffer buffer) {
@@ -54,6 +54,11 @@
         return "LoopEnd";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.LOOP_END;
     }
@@ -62,6 +67,12 @@
         buffer.start(id());
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         operations.add(new LoopEnd());
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
index d88382d..83a2f0e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
@@ -21,31 +21,57 @@
 import com.android.internal.widget.remotecompose.core.Operations;
 import com.android.internal.widget.remotecompose.core.PaintContext;
 import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
 import com.android.internal.widget.remotecompose.core.VariableSupport;
 import com.android.internal.widget.remotecompose.core.WireBuffer;
 import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+import com.android.internal.widget.remotecompose.core.operations.Utils;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /** Represents a loop of operations */
-public class LoopOperation extends PaintOperation {
+public class LoopOperation extends PaintOperation implements VariableSupport {
     private static final int OP_CODE = Operations.LOOP_START;
 
     @NonNull public ArrayList<Operation> mList = new ArrayList<>();
 
     int mIndexVariableId;
-    float mUntil = 12;
-    float mFrom = 0;
-    float mStep = 1;
+    float mUntil;
+    float mFrom;
+    float mStep;
+    float mUntilOut;
+    float mFromOut;
+    float mStepOut;
 
     public LoopOperation(int count, int indexId) {
         mUntil = count;
         mIndexVariableId = indexId;
     }
 
-    public LoopOperation(float count, float from, float step, int indexId) {
-        mUntil = count;
+    @Override
+    public void registerListening(RemoteContext context) {
+        if (Float.isNaN(mUntil)) {
+            context.listensTo(Utils.idFromNan(mUntil), this);
+        }
+        if (Float.isNaN(mFrom)) {
+            context.listensTo(Utils.idFromNan(mFrom), this);
+        }
+        if (Float.isNaN(mStep)) {
+            context.listensTo(Utils.idFromNan(mStep), this);
+        }
+    }
+
+    @Override
+    public void updateVariables(RemoteContext context) {
+        mUntilOut = Float.isNaN(mUntil) ? context.getFloat(Utils.idFromNan(mUntil)) : mUntil;
+        mFromOut = Float.isNaN(mFrom) ? context.getFloat(Utils.idFromNan(mFrom)) : mFrom;
+        mStepOut = Float.isNaN(mStep) ? context.getFloat(Utils.idFromNan(mStep)) : mStep;
+    }
+
+    public LoopOperation(int indexId, float from, float step, float until) {
+        mUntil = until;
         mFrom = from;
         mStep = step;
         mIndexVariableId = indexId;
@@ -58,13 +84,19 @@
 
     @Override
     public void write(@NonNull WireBuffer buffer) {
-        apply(buffer, mUntil, mFrom, mStep, mIndexVariableId);
+        apply(buffer, mIndexVariableId, mFrom, mStep, mUntil);
     }
 
     @NonNull
     @Override
     public String toString() {
-        return "LoopOperation";
+        StringBuilder builder = new StringBuilder("LoopOperation\n");
+        for (Operation operation : mList) {
+            builder.append("  ");
+            builder.append(operation);
+            builder.append("\n");
+        }
+        return builder.toString();
     }
 
     @NonNull
@@ -76,13 +108,13 @@
     @Override
     public void paint(@NonNull PaintContext context) {
         if (mIndexVariableId == 0) {
-            for (float i = mFrom; i < mUntil; i += mStep) {
+            for (float i = mFromOut; i < mUntilOut; i += mStepOut) {
                 for (Operation op : mList) {
                     op.apply(context.getContext());
                 }
             }
         } else {
-            for (float i = mFrom; i < mUntil; i += mStep) {
+            for (float i = mFromOut; i < mUntilOut; i += mStepOut) {
                 context.getContext().loadFloat(mIndexVariableId, i);
                 for (Operation op : mList) {
                     if (op instanceof VariableSupport) {
@@ -100,24 +132,34 @@
     }
 
     public static void apply(
-            @NonNull WireBuffer buffer, float count, float from, float step, int indexId) {
+            @NonNull WireBuffer buffer, int indexId, float from, float step, float until) {
         buffer.start(OP_CODE);
-        buffer.writeFloat(count);
+        buffer.writeInt(indexId);
         buffer.writeFloat(from);
         buffer.writeFloat(step);
-        buffer.writeInt(indexId);
+        buffer.writeFloat(until);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
-        float count = buffer.readFloat();
+        int indexId = buffer.readInt();
         float from = buffer.readFloat();
         float step = buffer.readFloat();
-        int indexId = buffer.readInt();
-        operations.add(new LoopOperation(count, from, step, indexId));
+        float until = buffer.readFloat();
+        operations.add(new LoopOperation(indexId, from, step, until));
     }
 
     public static void documentation(@NonNull DocumentationBuilder doc) {
         doc.operation("Operations", OP_CODE, name())
-                .description("Loop. This operation execute" + " a list of action in a loop");
+                .description("Loop. This operation execute" + " a list of action in a loop")
+                .field(DocumentedOperation.INT, "id", "if not 0 write value")
+                .field(DocumentedOperation.FLOAT, "from", "values starts at")
+                .field(DocumentedOperation.FLOAT, "step", "value step")
+                .field(DocumentedOperation.FLOAT, "until", "stops less than or equal");
     }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java
index ca79003..99b7e68 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java
@@ -25,7 +25,7 @@
 
 import java.util.List;
 
-public class OperationsListEnd implements Operation {
+public class OperationsListEnd extends Operation {
 
     @Override
     public void write(@NonNull WireBuffer buffer) {
@@ -54,6 +54,11 @@
         return "ListEnd";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.OPERATIONS_LIST_END;
     }
@@ -62,6 +67,12 @@
         buffer.start(id());
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         operations.add(new OperationsListEnd());
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
index 85c7153..fd16287 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
@@ -197,6 +197,11 @@
         return "RootLayout";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.LAYOUT_ROOT;
     }
@@ -206,6 +211,12 @@
         buffer.writeInt(componentId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int componentId = buffer.readInt();
         operations.add(new RootLayoutComponent(componentId, 0, 0, 0, 0, null, -1));
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java
index 0316f96..3185bb5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java
@@ -84,6 +84,12 @@
         buffer.start(OP_CODE);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(WireBuffer buffer, List<Operation> operations) {
         operations.add(new TouchCancelModifierOperation());
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
index 6fb7059..b230b09 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
@@ -29,7 +29,7 @@
 import java.util.List;
 
 /** Basic component animation spec */
-public class AnimationSpec implements Operation {
+public class AnimationSpec extends Operation {
     int mAnimationId = -1;
     int mMotionDuration = 300;
     int mMotionEasingType = GeneralEasing.CUBIC_STANDARD;
@@ -142,6 +142,11 @@
         return "AnimationSpec";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.ANIMATION_SPEC;
     }
@@ -193,6 +198,12 @@
         buffer.writeInt(animationToInt(exitAnimation));
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int animationId = buffer.readInt();
         int motionDuration = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
index 47a9421..01cd7cc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
@@ -108,6 +108,8 @@
             @NonNull PaintContext context,
             float maxWidth,
             float maxHeight,
+            boolean horizontalWrap,
+            boolean verticalWrap,
             @NonNull MeasurePass measure,
             @NonNull Size size) {
         for (Component c : mChildrenComponents) {
@@ -175,6 +177,11 @@
         return "BoxLayout";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.LAYOUT_BOX;
     }
@@ -192,6 +199,12 @@
         buffer.writeInt(verticalPositioning);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int componentId = buffer.readInt();
         int animationId = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java
index 476b1a66..665db26 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java
@@ -77,6 +77,11 @@
         return "CanvasLayout";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.LAYOUT_CANVAS;
     }
@@ -87,6 +92,12 @@
         buffer.writeInt(animationId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int componentId = buffer.readInt();
         int animationId = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
index 68e18c6..5b9ee0f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
@@ -125,17 +125,21 @@
             @NonNull PaintContext context,
             float maxWidth,
             float maxHeight,
+            boolean horizontalWrap,
+            boolean verticalWrap,
             @NonNull MeasurePass measure,
             @NonNull Size size) {
         DebugLog.s(() -> "COMPUTE WRAP SIZE in " + this + " (" + mComponentId + ")");
         int visibleChildrens = 0;
+        float currentMaxHeight = maxHeight;
         for (Component c : mChildrenComponents) {
-            c.measure(context, 0f, maxWidth, 0f, maxHeight, measure);
+            c.measure(context, 0f, maxWidth, 0f, currentMaxHeight, measure);
             ComponentMeasure m = measure.get(c);
             if (m.getVisibility() != Visibility.GONE) {
                 size.setWidth(Math.max(size.getWidth(), m.getW()));
                 size.setHeight(size.getHeight() + m.getH());
                 visibleChildrens++;
+                currentMaxHeight -= m.getH();
             }
         }
         if (!mChildrenComponents.isEmpty()) {
@@ -342,6 +346,11 @@
         return "ColumnLayout";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.LAYOUT_COLUMN;
     }
@@ -361,6 +370,12 @@
         buffer.writeFloat(spacedBy);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int componentId = buffer.readInt();
         int animationId = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
index 3b5aaf3..6a15b7f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
@@ -53,6 +53,8 @@
             @NonNull PaintContext context,
             float maxWidth,
             float maxHeight,
+            boolean horizontalWrap,
+            boolean verticalWrap,
             @NonNull MeasurePass measure,
             @NonNull Size size) {
         // nothing here
@@ -129,42 +131,67 @@
             float maxHeight,
             @NonNull MeasurePass measure) {
         boolean hasWrap = true;
-        float measuredWidth =
-                Math.min(maxWidth, computeModifierDefinedWidth() - mMarginLeft - mMarginRight);
-        float measuredHeight =
-                Math.min(maxHeight, computeModifierDefinedHeight() - mMarginTop - mMarginBottom);
-        float insetMaxWidth = maxWidth - mMarginLeft - mMarginRight;
-        float insetMaxHeight = maxHeight - mMarginTop - mMarginBottom;
+
+        float measuredWidth = Math.min(maxWidth, computeModifierDefinedWidth());
+        float measuredHeight = Math.min(maxHeight, computeModifierDefinedHeight());
+        float insetMaxWidth = maxWidth - mPaddingLeft - mPaddingRight;
+        float insetMaxHeight = maxHeight - mPaddingTop - mPaddingBottom;
+
         if (mWidthModifier.isIntrinsicMin()) {
             maxWidth = intrinsicWidth();
         }
         if (mHeightModifier.isIntrinsicMin()) {
             maxHeight = intrinsicHeight();
         }
-        if (mWidthModifier.isWrap() || mHeightModifier.isWrap()) { // TODO: potential npe -- bbade@
+
+        boolean hasHorizontalWrap = mWidthModifier.isWrap();
+        boolean hasVerticalWrap = mHeightModifier.isWrap();
+        if (hasHorizontalWrap || hasVerticalWrap) { // TODO: potential npe -- bbade@
             mCachedWrapSize.setWidth(0f);
             mCachedWrapSize.setHeight(0f);
-            computeWrapSize(context, maxWidth, maxHeight, measure, mCachedWrapSize);
+            float wrapMaxWidth = insetMaxWidth;
+            float wrapMaxHeight = insetMaxHeight;
+            if (hasHorizontalWrap) {
+                wrapMaxWidth = insetMaxWidth - mPaddingLeft - mPaddingRight;
+            }
+            if (hasVerticalWrap) {
+                wrapMaxHeight = insetMaxHeight - mPaddingTop - mPaddingBottom;
+            }
+            computeWrapSize(
+                    context,
+                    wrapMaxWidth,
+                    wrapMaxHeight,
+                    mWidthModifier.isWrap(),
+                    mHeightModifier.isWrap(),
+                    measure,
+                    mCachedWrapSize);
             measuredWidth = mCachedWrapSize.getWidth();
+            if (hasHorizontalWrap) {
+                measuredWidth += mPaddingLeft + mPaddingRight;
+            }
             measuredHeight = mCachedWrapSize.getHeight();
+            if (hasVerticalWrap) {
+                measuredHeight += mPaddingTop + mPaddingBottom;
+            }
         } else {
             hasWrap = false;
         }
+
         if (isInHorizontalFill()) {
-            measuredWidth = insetMaxWidth;
+            measuredWidth = maxWidth;
         } else if (mWidthModifier.hasWeight()) {
             measuredWidth = Math.max(measuredWidth, computeModifierDefinedWidth());
         } else {
             measuredWidth = Math.max(measuredWidth, minWidth);
-            measuredWidth = Math.min(measuredWidth, insetMaxWidth);
+            measuredWidth = Math.min(measuredWidth, maxWidth);
         }
         if (isInVerticalFill()) { // todo: potential npe -- bbade@
-            measuredHeight = insetMaxHeight;
+            measuredHeight = maxHeight;
         } else if (mHeightModifier.hasWeight()) {
             measuredHeight = Math.max(measuredHeight, computeModifierDefinedHeight());
         } else {
             measuredHeight = Math.max(measuredHeight, minHeight);
-            measuredHeight = Math.min(measuredHeight, insetMaxHeight);
+            measuredHeight = Math.min(measuredHeight, maxHeight);
         }
         if (minWidth == maxWidth) {
             measuredWidth = maxWidth;
@@ -172,20 +199,27 @@
         if (minHeight == maxHeight) {
             measuredHeight = maxHeight;
         }
-        measuredWidth = Math.min(measuredWidth, insetMaxWidth);
-        measuredHeight = Math.min(measuredHeight, insetMaxHeight);
+
         if (!hasWrap) {
             if (hasHorizontalScroll()) {
                 mCachedWrapSize.setWidth(0f);
                 mCachedWrapSize.setHeight(0f);
-                computeWrapSize(context, Float.MAX_VALUE, maxHeight, measure, mCachedWrapSize);
+                computeWrapSize(
+                        context,
+                        Float.MAX_VALUE,
+                        maxHeight,
+                        false,
+                        false,
+                        measure,
+                        mCachedWrapSize);
                 float w = mCachedWrapSize.getWidth();
                 computeSize(context, 0f, w, 0, measuredHeight, measure);
                 mComponentModifiers.setHorizontalScrollDimension(measuredWidth, w);
             } else if (hasVerticalScroll()) {
                 mCachedWrapSize.setWidth(0f);
                 mCachedWrapSize.setHeight(0f);
-                computeWrapSize(context, maxWidth, Float.MAX_VALUE, measure, mCachedWrapSize);
+                computeWrapSize(
+                        context, maxWidth, Float.MAX_VALUE, false, false, measure, mCachedWrapSize);
                 float h = mCachedWrapSize.getHeight();
                 computeSize(context, 0f, measuredWidth, 0, h, measure);
                 mComponentModifiers.setVerticalScrollDimension(measuredHeight, h);
@@ -202,9 +236,6 @@
             cm.setH(measuredHeight);
         }
 
-        measuredWidth += mMarginLeft + mMarginRight;
-        measuredHeight += mMarginTop + mMarginBottom;
-
         ComponentMeasure m = measure.get(this);
         m.setW(measuredWidth);
         m.setH(measuredHeight);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
index 0ce634f..0ec820b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
@@ -123,21 +123,25 @@
             @NonNull PaintContext context,
             float maxWidth,
             float maxHeight,
+            boolean horizontalWrap,
+            boolean verticalWrap,
             @NonNull MeasurePass measure,
             @NonNull Size size) {
         DebugLog.s(() -> "COMPUTE WRAP SIZE in " + this + " (" + mComponentId + ")");
-        //        int visibleChildrens = 0;
+        int visibleChildrens = 0;
+        float currentMaxWidth = maxWidth;
         for (Component c : mChildrenComponents) {
-            c.measure(context, 0f, maxWidth, 0f, maxHeight, measure);
+            c.measure(context, 0f, currentMaxWidth, 0f, maxHeight, measure);
             ComponentMeasure m = measure.get(c);
             if (m.getVisibility() != Visibility.GONE) {
                 size.setWidth(size.getWidth() + m.getW());
                 size.setHeight(Math.max(size.getHeight(), m.getH()));
-                //                visibleChildrens++;
+                visibleChildrens++;
+                currentMaxWidth -= m.getW();
             }
         }
         if (!mChildrenComponents.isEmpty()) {
-            size.setWidth(size.getWidth() + (mSpacedBy * (mChildrenComponents.size() - 1)));
+            size.setWidth(size.getWidth() + (mSpacedBy * (visibleChildrens - 1)));
         }
         DebugLog.e();
     }
@@ -345,6 +349,11 @@
         return "RowLayout";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.LAYOUT_ROW;
     }
@@ -364,6 +373,12 @@
         buffer.writeFloat(spacedBy);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int componentId = buffer.readInt();
         int animationId = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java
index 73a104b..61a3ec9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java
@@ -159,10 +159,13 @@
             @NonNull PaintContext context,
             float maxWidth,
             float maxHeight,
+            boolean horizontalWrap,
+            boolean verticalWrap,
             @NonNull MeasurePass measure,
             @NonNull Size size) {
         LayoutManager layout = getLayout(currentLayoutIndex);
-        layout.computeWrapSize(context, maxWidth, maxHeight, measure, size);
+        layout.computeWrapSize(
+                context, maxWidth, maxHeight, horizontalWrap, verticalWrap, measure, size);
     }
 
     @Override
@@ -442,11 +445,7 @@
                     int id = c.getPaintId();
                     for (int i = 0; i < idIndex; i++) {
                         if (cacheListElementsId[i] == id) {
-                            context.translate(
-                                    previousLayout.getMarginLeft(), previousLayout.getMarginTop());
                             c.paint(context);
-                            context.translate(
-                                    -currentLayout.getMarginLeft(), -currentLayout.getMarginTop());
                             break;
                         }
                     }
@@ -472,16 +471,10 @@
                     // and fade in the new one
                     Component previousComponent = stateComponents[previousLayoutIndex];
                     if (previousComponent != null && component != previousComponent) {
-                        context.translate(
-                                currentLayout.getMarginLeft(), currentLayout.getMarginTop());
                         previousComponent.paint(context);
-                        context.translate(
-                                -currentLayout.getMarginLeft(), -currentLayout.getMarginTop());
                     }
                 }
-                context.translate(currentLayout.getMarginLeft(), currentLayout.getMarginTop());
                 component.paint(context);
-                context.translate(-currentLayout.getMarginLeft(), -currentLayout.getMarginTop());
             } else if (op instanceof PaintOperation) {
                 ((PaintOperation) op).paint(context);
             }
@@ -563,6 +556,12 @@
         buffer.writeInt(indexId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int componentId = buffer.readInt();
         int animationId = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
index a527e5a..8e7f538 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
@@ -52,8 +52,8 @@
     private int mType = -1;
     private float mTextX;
     private float mTextY;
-    private float mTextW;
-    private float mTextH;
+    private float mTextW = -1;
+    private float mTextH = -1;
 
     @Nullable private String mCachedString = "";
 
@@ -66,7 +66,11 @@
 
     @Override
     public void updateVariables(@NonNull RemoteContext context) {
-        mCachedString = context.getText(mTextId);
+        String cachedString = context.getText(mTextId);
+        if (cachedString != null && cachedString.equalsIgnoreCase(mCachedString)) {
+            return;
+        }
+        mCachedString = cachedString;
         if (mType == -1) {
             if (mFontFamilyId != -1) {
                 String fontFamily = context.getText(mFontFamilyId);
@@ -86,8 +90,9 @@
                 mType = 0;
             }
         }
-        mNeedsMeasure = true;
-        needsRepaint();
+        mTextW = -1;
+        mTextH = -1;
+        invalidateMeasure();
     }
 
     public TextLayout(
@@ -168,7 +173,14 @@
             return;
         }
         int length = mCachedString.length();
-        context.drawTextRun(mTextId, 0, length, 0, 0, mTextX, mTextY, false);
+        if (mTextW > mWidth) {
+            context.save();
+            context.translate(getScrollX(), getScrollY());
+            context.drawTextRun(mTextId, 0, length, 0, 0, mTextX, mTextY, false);
+            context.restore();
+        } else {
+            context.drawTextRun(mTextId, 0, length, 0, 0, mTextX, mTextY, false);
+        }
         if (DEBUG) {
             mPaint.setStyle(PaintBundle.STYLE_FILL_AND_STROKE);
             mPaint.setColor(1f, 1F, 1F, 1F);
@@ -246,6 +258,8 @@
             @NonNull PaintContext context,
             float maxWidth,
             float maxHeight,
+            boolean horizontalWrap,
+            boolean verticalWrap,
             @NonNull MeasurePass measure,
             @NonNull Size size) {
         context.savePaint();
@@ -262,9 +276,9 @@
         context.restorePaint();
         float w = bounds[2] - bounds[0];
         float h = bounds[3] - bounds[1];
-        size.setWidth(w);
+        size.setWidth(Math.min(maxWidth, w));
         mTextX = -bounds[0];
-        size.setHeight(h);
+        size.setHeight(Math.min(maxHeight, h));
         mTextY = -bounds[1];
         mTextW = w;
         mTextH = h;
@@ -285,6 +299,11 @@
         return "TextLayout";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.LAYOUT_TEXT;
     }
@@ -312,6 +331,12 @@
         buffer.writeInt(textAlign);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int componentId = buffer.readInt();
         int animationId = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
index 71d2ba6..5df16c5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
@@ -114,6 +114,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -142,6 +147,12 @@
         buffer.writeInt(shapeType);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         float x = buffer.readFloat();
         float y = buffer.readFloat();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
index 0707cd6..bfadd2f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
@@ -160,6 +160,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -192,6 +197,12 @@
         buffer.writeInt(shapeType);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         float x = buffer.readFloat();
         float y = buffer.readFloat();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
index e05b027..d0af872 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
@@ -60,6 +60,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -68,6 +73,12 @@
         buffer.start(OP_CODE);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         operations.add(new ClipRectModifierOperation());
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java
index 471db0b..1e6ccfc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java
@@ -34,7 +34,7 @@
 import java.util.List;
 
 /** Allows setting visibility on a component */
-public class ComponentVisibilityOperation
+public class ComponentVisibilityOperation extends Operation
         implements ModifierOperation, VariableSupport, DecoratorComponent {
     private static final int OP_CODE = Operations.MODIFIER_VISIBILITY;
 
@@ -79,6 +79,12 @@
         buffer.writeInt(valueId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int valueId = buffer.readInt();
         operations.add(new ComponentVisibilityOperation(valueId));
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
index b9324f0..b11deae 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
@@ -17,13 +17,15 @@
 
 import android.annotation.NonNull;
 
+import com.android.internal.widget.remotecompose.core.Operation;
 import com.android.internal.widget.remotecompose.core.RemoteContext;
 import com.android.internal.widget.remotecompose.core.VariableSupport;
 import com.android.internal.widget.remotecompose.core.operations.Utils;
 import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
 
 /** Base class for dimension modifiers */
-public abstract class DimensionModifierOperation implements ModifierOperation, VariableSupport {
+public abstract class DimensionModifierOperation extends Operation
+        implements ModifierOperation, VariableSupport {
 
     public enum Type {
         EXACT,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java
index 571e554..4252309 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java
@@ -206,6 +206,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
index 7bb4a75..692b526 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
@@ -37,6 +37,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -47,6 +52,12 @@
         buffer.writeFloat(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Type type = Type.fromInt(buffer.readInt());
         float value = buffer.readFloat();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java
index d239bc8..333e281 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java
@@ -32,7 +32,7 @@
 import java.util.List;
 
 /** Capture a host action information. This can be triggered on eg. a click. */
-public class HostActionOperation implements ActionOperation {
+public class HostActionOperation extends Operation implements ActionOperation {
     private static final int OP_CODE = Operations.HOST_ACTION;
 
     int mActionId = -1;
@@ -88,6 +88,12 @@
         buffer.writeInt(actionId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int actionId = buffer.readInt();
         operations.add(new HostActionOperation(actionId));
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java
index 3268e5e..f9a4270 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java
@@ -32,7 +32,7 @@
 import java.util.List;
 
 /** Capture a host action information. This can be triggered on eg. a click. */
-public class HostNamedActionOperation implements ActionOperation {
+public class HostNamedActionOperation extends Operation implements ActionOperation {
     private static final int OP_CODE = Operations.HOST_NAMED_ACTION;
 
     public static final int FLOAT_TYPE = 0;
@@ -112,6 +112,12 @@
         buffer.writeInt(valueId);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int textId = buffer.readInt();
         int type = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java
index 8f08f14..f8926fe 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java
@@ -17,10 +17,10 @@
 
 import android.annotation.NonNull;
 
-import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.OperationInterface;
 import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
 
 /** Represents a modifier */
-public interface ModifierOperation extends Operation {
+public interface ModifierOperation extends OperationInterface {
     void serializeToString(int indent, @NonNull StringSerializer serializer);
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java
index 8c07059..69c4e9a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java
@@ -94,6 +94,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
index 2b6621e..545df64 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
@@ -32,7 +32,7 @@
  * Represents a padding modifier. Padding modifiers can be chained and will impact following
  * modifiers.
  */
-public class PaddingModifierOperation implements ModifierOperation {
+public class PaddingModifierOperation extends Operation implements ModifierOperation {
     private static final int OP_CODE = Operations.MODIFIER_PADDING;
     public static final String CLASS_NAME = "PaddingModifierOperation";
     float mLeft;
@@ -118,6 +118,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.MODIFIER_PADDING;
     }
@@ -131,6 +136,12 @@
         buffer.writeFloat(bottom);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         float left = buffer.readFloat();
         float top = buffer.readFloat();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
index 3fefc58..681501d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
@@ -37,11 +37,22 @@
     public static final int OP_CODE = Operations.MODIFIER_ROUNDED_CLIP_RECT;
     public static final String CLASS_NAME = "RoundedClipRectModifierOperation";
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Maker m = RoundedClipRectModifierOperation::new;
         read(m, buffer, operations);
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java
index 8dcfed9..0b66320 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java
@@ -134,6 +134,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java
index a97fcff..b96d3cc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java
@@ -33,7 +33,7 @@
 import java.util.List;
 
 /** Apply a value change on an float variable. */
-public class ValueFloatChangeActionOperation implements ActionOperation {
+public class ValueFloatChangeActionOperation extends Operation implements ActionOperation {
     private static final int OP_CODE = Operations.VALUE_FLOAT_CHANGE_ACTION;
 
     int mTargetValueId = -1;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatExpressionChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatExpressionChangeActionOperation.java
index 41586b4..d81b7ff 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatExpressionChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatExpressionChangeActionOperation.java
@@ -32,7 +32,8 @@
 import java.util.List;
 
 /** Apply a value change on an integer variable. */
-public class ValueFloatExpressionChangeActionOperation implements ActionOperation {
+public class ValueFloatExpressionChangeActionOperation extends Operation
+        implements ActionOperation {
     private static final int OP_CODE = Operations.VALUE_FLOAT_EXPRESSION_CHANGE_ACTION;
 
     int mTargetValueId = -1;
@@ -88,6 +89,12 @@
         buffer.writeInt(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int valueId = buffer.readInt();
         int value = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java
index c2cd2ab..fb13b42 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java
@@ -32,7 +32,7 @@
 import java.util.List;
 
 /** Apply a value change on an integer variable. */
-public class ValueIntegerChangeActionOperation implements ActionOperation {
+public class ValueIntegerChangeActionOperation extends Operation implements ActionOperation {
     private static final int OP_CODE = Operations.VALUE_INTEGER_CHANGE_ACTION;
 
     int mTargetValueId = -1;
@@ -87,6 +87,12 @@
         buffer.writeInt(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int valueId = buffer.readInt();
         int value = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java
index 43fbb85..0fe88ad 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java
@@ -32,7 +32,8 @@
 import java.util.List;
 
 /** Apply a value change on an integer variable. */
-public class ValueIntegerExpressionChangeActionOperation implements ActionOperation {
+public class ValueIntegerExpressionChangeActionOperation extends Operation
+        implements ActionOperation {
     private static final int OP_CODE = Operations.VALUE_INTEGER_EXPRESSION_CHANGE_ACTION;
 
     long mTargetValueId = -1;
@@ -88,6 +89,12 @@
         buffer.writeLong(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         long valueId = buffer.readLong();
         long value = buffer.readLong();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java
index 1107889..a8d3b87 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java
@@ -32,7 +32,7 @@
 import java.util.List;
 
 /** Apply a value change on a string variable. */
-public class ValueStringChangeActionOperation implements ActionOperation {
+public class ValueStringChangeActionOperation extends Operation implements ActionOperation {
     private static final int OP_CODE = Operations.VALUE_STRING_CHANGE_ACTION;
 
     int mTargetValueId = -1;
@@ -91,6 +91,12 @@
         buffer.writeInt(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int valueId = buffer.readInt();
         int value = buffer.readInt();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
index 3c757a8..f6d743f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
@@ -37,6 +37,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
@@ -47,6 +52,12 @@
         buffer.writeFloat(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         Type type = Type.fromInt(buffer.readInt());
         float value = buffer.readFloat();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java
index 82c8f34..96ed2cd 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java
@@ -83,6 +83,11 @@
         return CLASS_NAME;
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return OP_CODE;
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java
index 07cf762..9543469 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java
@@ -498,6 +498,11 @@
         return ret;
     }
 
+    /**
+     * Write a bundle of paint changes to the buffer
+     *
+     * @param buffer bundle to write
+     */
     public void writeBundle(@NonNull WireBuffer buffer) {
         buffer.writeInt(mPos);
         for (int index = 0; index < mPos; index++) {
@@ -505,6 +510,11 @@
         }
     }
 
+    /**
+     * This will read the paint bundle off the wire buffer
+     *
+     * @param buffer the buffer to read
+     */
     public void readBundle(@NonNull WireBuffer buffer) {
         int len = buffer.readInt();
         if (len <= 0 || len > 1024) {
@@ -587,6 +597,9 @@
     public static final int RADIAL_GRADIENT = 1;
     public static final int SWEEP_GRADIENT = 2;
 
+    private int mLastShaderSet = -1;
+    private boolean mColorFilterSet = false;
+
     /**
      * sets a shader that draws a linear gradient along a line.
      *
@@ -722,12 +735,14 @@
         mArray[mPos] = COLOR_FILTER_ID | (mode << 16);
         mPos++;
         mArray[mPos++] = color;
+        mColorFilterSet = true;
     }
 
     /** This sets the color filter to null */
     public void clearColorFilter() {
         mArray[mPos] = CLEAR_COLOR_FILTER;
         mPos++;
+        mColorFilterSet = false;
     }
 
     /**
@@ -843,6 +858,7 @@
      * @param shaderId
      */
     public void setShader(int shaderId) {
+        mLastShaderSet = shaderId;
         mArray[mPos] = SHADER;
         mPos++;
         mArray[mPos] = shaderId;
@@ -909,11 +925,23 @@
         mPos++;
     }
 
+    /**
+     * clear a series of paint parameters. Currently not used
+     *
+     * @param mask bit pattern of the attributes to clear
+     */
     public void clear(long mask) { // unused for now
     }
 
+    /** Reset the content of the paint bundle so that it can be reused */
     public void reset() {
         mPos = 0;
+        if (mColorFilterSet) {
+            clearColorFilter();
+        }
+        if (mLastShaderSet != -1 && mLastShaderSet != 0) {
+            setShader(0);
+        }
     }
 
     public static @NonNull String blendModeString(int mode) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
index e5633c7..a568747 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
@@ -18,7 +18,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 
-import com.android.internal.widget.remotecompose.core.operations.Utils;
 import com.android.internal.widget.remotecompose.core.operations.utilities.easing.MonotonicSpline;
 
 /** high performance floating point expression evaluator used in animation */
@@ -141,7 +140,7 @@
         for (int i = 0; i < mStack.length; i++) {
             float v = mStack[i];
             if (Float.isNaN(v)) {
-                sp = mOps[fromNaN(v) - OFFSET].eval(sp);
+                sp = opEval(sp, fromNaN(v));
             } else {
                 mStack[++sp] = v;
             }
@@ -170,7 +169,7 @@
             if (Float.isNaN(v)) {
                 int id = fromNaN(v);
                 if ((id & NanMap.ID_REGION_MASK) != NanMap.ID_REGION_ARRAY) {
-                    sp = mOps[id - OFFSET].eval(sp);
+                    sp = opEval(sp, id);
                 } else {
                     mStack[++sp] = v;
                 }
@@ -199,7 +198,7 @@
             if (Float.isNaN(v)) {
                 int id = fromNaN(v);
                 if ((id & NanMap.ID_REGION_MASK) != NanMap.ID_REGION_ARRAY) {
-                    sp = mOps[id - OFFSET].eval(sp);
+                    sp = opEval(sp, id);
                 } else {
                     mStack[++sp] = v;
                 }
@@ -228,10 +227,11 @@
         mStack = mLocalStack;
         mVar = var;
         int sp = -1;
+
         for (int i = 0; i < len; i++) {
             float v = mStack[i];
             if (Float.isNaN(v)) {
-                sp = mOps[fromNaN(v) - OFFSET].eval(sp);
+                sp = opEval(sp, fromNaN(v));
             } else {
                 mStack[++sp] = v;
             }
@@ -250,9 +250,10 @@
         mStack = exp;
         mVar = var;
         int sp = -1;
+
         for (float v : exp) {
             if (Float.isNaN(v)) {
-                sp = mOps[fromNaN(v) - OFFSET].eval(sp);
+                sp = opEval(sp, fromNaN(v));
             } else {
                 System.out.print(" " + v);
                 mStack[++sp] = v;
@@ -261,294 +262,6 @@
         return mStack[sp];
     }
 
-    @NonNull Op[] mOps;
-
-    {
-        Op mADD =
-                (sp) -> { // ADD
-                    mStack[sp - 1] = mStack[sp - 1] + mStack[sp];
-                    return sp - 1;
-                };
-        Op mSUB =
-                (sp) -> { // SUB
-                    mStack[sp - 1] = mStack[sp - 1] - mStack[sp];
-                    return sp - 1;
-                };
-        Op mMUL =
-                (sp) -> { // MUL
-                    mStack[sp - 1] = mStack[sp - 1] * mStack[sp];
-                    return sp - 1;
-                };
-        Op mDIV =
-                (sp) -> { // DIV
-                    mStack[sp - 1] = mStack[sp - 1] / mStack[sp];
-                    return sp - 1;
-                };
-        Op mMOD =
-                (sp) -> { // MOD
-                    mStack[sp - 1] = mStack[sp - 1] % mStack[sp];
-                    return sp - 1;
-                };
-        Op mMIN =
-                (sp) -> { // MIN
-                    mStack[sp - 1] = (float) Math.min(mStack[sp - 1], mStack[sp]);
-                    return sp - 1;
-                };
-        Op mMAX =
-                (sp) -> { // MAX
-                    mStack[sp - 1] = (float) Math.max(mStack[sp - 1], mStack[sp]);
-                    return sp - 1;
-                };
-        Op mPOW =
-                (sp) -> { // POW
-                    mStack[sp - 1] = (float) Math.pow(mStack[sp - 1], mStack[sp]);
-                    return sp - 1;
-                };
-        Op mSQRT =
-                (sp) -> { // SQRT
-                    mStack[sp] = (float) Math.sqrt(mStack[sp]);
-                    return sp;
-                };
-        Op mABS =
-                (sp) -> { // ABS
-                    mStack[sp] = (float) Math.abs(mStack[sp]);
-                    return sp;
-                };
-        Op mSIGN =
-                (sp) -> { // SIGN
-                    mStack[sp] = (float) Math.signum(mStack[sp]);
-                    return sp;
-                };
-        Op mCOPY_SIGN =
-                (sp) -> { // copySign
-                    mStack[sp - 1] = (float) Math.copySign(mStack[sp - 1], mStack[sp]);
-                    return sp - 1;
-                };
-        Op mEXP =
-                (sp) -> { // EXP
-                    mStack[sp] = (float) Math.exp(mStack[sp]);
-                    return sp;
-                };
-        Op mFLOOR =
-                (sp) -> { // FLOOR
-                    mStack[sp] = (float) Math.floor(mStack[sp]);
-                    return sp;
-                };
-        Op mLOG =
-                (sp) -> { // LOG
-                    mStack[sp] = (float) Math.log10(mStack[sp]);
-                    return sp;
-                };
-        Op mLN =
-                (sp) -> { // LN
-                    mStack[sp] = (float) Math.log(mStack[sp]);
-                    return sp;
-                };
-        Op mROUND =
-                (sp) -> { // ROUND
-                    mStack[sp] = (float) Math.round(mStack[sp]);
-                    return sp;
-                };
-        Op mSIN =
-                (sp) -> { // SIN
-                    mStack[sp] = (float) Math.sin(mStack[sp]);
-                    return sp;
-                };
-        Op mCOS =
-                (sp) -> { // COS
-                    mStack[sp] = (float) Math.cos(mStack[sp]);
-                    return sp;
-                };
-        Op mTAN =
-                (sp) -> { // TAN
-                    mStack[sp] = (float) Math.tan(mStack[sp]);
-                    return sp;
-                };
-        Op mASIN =
-                (sp) -> { // ASIN
-                    mStack[sp] = (float) Math.asin(mStack[sp]);
-                    return sp;
-                };
-        Op mACOS =
-                (sp) -> { // ACOS
-                    mStack[sp] = (float) Math.acos(mStack[sp]);
-                    return sp;
-                };
-        Op mATAN =
-                (sp) -> { // ATAN
-                    mStack[sp] = (float) Math.atan(mStack[sp]);
-                    return sp;
-                };
-        Op mATAN2 =
-                (sp) -> { // ATAN2
-                    mStack[sp - 1] = (float) Math.atan2(mStack[sp - 1], mStack[sp]);
-                    return sp - 1;
-                };
-        Op mMAD =
-                (sp) -> { // MAD
-                    mStack[sp - 2] = mStack[sp] + mStack[sp - 1] * mStack[sp - 2];
-                    return sp - 2;
-                };
-        Op mTERNARY_CONDITIONAL =
-                (sp) -> { // TERNARY_CONDITIONAL
-                    mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2];
-                    return sp - 2;
-                };
-        Op mCLAMP =
-                (sp) -> { // CLAMP (min, max, value)
-                    mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
-                    return sp - 2;
-                };
-        Op mCBRT =
-                (sp) -> { // CBRT is cube root
-                    mStack[sp] = (float) Math.pow(mStack[sp], 1 / 3.);
-                    return sp;
-                };
-        Op mDEG =
-                (sp) -> { // DEG
-                    mStack[sp] = mStack[sp] * FP_TO_RAD;
-                    return sp;
-                };
-        Op mRAD =
-                (sp) -> { // RAD
-                    mStack[sp] = mStack[sp] * FP_TO_DEG;
-                    return sp;
-                };
-        Op mCEIL =
-                (sp) -> { // CEIL
-                    mStack[sp] = (float) Math.ceil(mStack[sp]);
-                    return sp;
-                };
-        Op mA_DEREF =
-                (sp) -> { // A_DEREF
-                    Utils.log(" \n >>> DREF " + Integer.toHexString(fromNaN(mStack[sp - 1])));
-                    Utils.log(" >>> DREF " + mStack[sp] + "  " + mStack[sp - 1]);
-                    int id = fromNaN(mStack[sp - 1]);
-                    mStack[sp - 1] = mCollectionsAccess.getFloatValue(id, (int) mStack[sp]);
-                    return sp - 1;
-                };
-        Op mA_MAX =
-                (sp) -> { // A_MAX
-                    int id = fromNaN(mStack[sp]);
-                    float[] array = mCollectionsAccess.getFloats(id);
-                    float max = array[0];
-                    for (int i = 1; i < array.length; i++) {
-                        max = Math.max(max, array[i]);
-                    }
-                    mStack[sp] = max;
-                    return sp;
-                };
-        Op mA_MIN =
-                (sp) -> { // A_MIN
-                    int id = fromNaN(mStack[sp]);
-                    float[] array = mCollectionsAccess.getFloats(id);
-                    if (array.length == 0) {
-                        return sp;
-                    }
-                    float min = array[0];
-                    for (int i = 1; i < array.length; i++) {
-                        min = Math.min(min, array[i]);
-                    }
-                    mStack[sp] = min;
-                    return sp;
-                };
-        Op mA_SUM =
-                (sp) -> { // A_SUM
-                    int id = fromNaN(mStack[sp]);
-                    float[] array = mCollectionsAccess.getFloats(id);
-                    float sum = 0;
-                    for (int i = 0; i < array.length; i++) {
-                        sum += array[i];
-                    }
-                    mStack[sp] = sum;
-                    return sp;
-                };
-        Op mA_AVG =
-                (sp) -> { // A_AVG
-                    int id = fromNaN(mStack[sp]);
-                    float[] array = mCollectionsAccess.getFloats(id);
-                    float sum = 0;
-                    for (int i = 0; i < array.length; i++) {
-                        sum += array[i];
-                    }
-                    mStack[sp] = sum / array.length;
-                    return sp;
-                };
-        Op mA_LEN =
-                (sp) -> { // A_LEN
-                    int id = fromNaN(mStack[sp]);
-                    mStack[sp] = mCollectionsAccess.getListLength(id);
-                    return sp;
-                };
-        Op mA_SPLINE =
-                (sp) -> { // A_SPLINE
-                    int id = fromNaN(mStack[sp - 1]);
-                    mStack[sp - 1] = getSplineValue(id, mStack[sp]);
-                    return sp - 1;
-                };
-        Op mFIRST_VAR =
-                (sp) -> { // FIRST_VAR
-                    mStack[sp] = mVar[0];
-                    return sp;
-                };
-        Op mSECOND_VAR =
-                (sp) -> { // SECOND_VAR
-                    mStack[sp] = mVar[1];
-                    return sp;
-                };
-        Op mTHIRD_VAR =
-                (sp) -> { // THIRD_VAR
-                    mStack[sp] = mVar[2];
-                    return sp;
-                };
-
-        Op[] ops = {
-            null,
-            mADD,
-            mSUB,
-            mMUL,
-            mDIV,
-            mMOD,
-            mMIN,
-            mMAX,
-            mPOW,
-            mSQRT,
-            mABS,
-            mSIGN,
-            mCOPY_SIGN,
-            mEXP,
-            mFLOOR,
-            mLOG,
-            mLN,
-            mROUND,
-            mSIN,
-            mCOS,
-            mTAN,
-            mASIN,
-            mACOS,
-            mATAN,
-            mATAN2,
-            mMAD,
-            mTERNARY_CONDITIONAL,
-            mCLAMP,
-            mCBRT,
-            mDEG,
-            mRAD,
-            mCEIL,
-            mA_DEREF,
-            mA_MAX,
-            mA_MIN,
-            mA_SUM,
-            mA_AVG,
-            mA_LEN,
-            mA_SPLINE,
-            mFIRST_VAR,
-            mSECOND_VAR,
-            mTHIRD_VAR,
-        };
-        mOps = ops;
-    }
-
     static {
         int k = 0;
         sNames.put(k++, "NOP");
@@ -765,4 +478,248 @@
         int b = Float.floatToRawIntBits(v);
         return b & 0x7FFFFF;
     }
+
+    // ================= New approach ========
+    private static final int OP_ADD = OFFSET + 1;
+    private static final int OP_SUB = OFFSET + 2;
+    private static final int OP_MUL = OFFSET + 3;
+    private static final int OP_DIV = OFFSET + 4;
+    private static final int OP_MOD = OFFSET + 5;
+    private static final int OP_MIN = OFFSET + 6;
+    private static final int OP_MAX = OFFSET + 7;
+    private static final int OP_POW = OFFSET + 8;
+    private static final int OP_SQRT = OFFSET + 9;
+    private static final int OP_ABS = OFFSET + 10;
+    private static final int OP_SIGN = OFFSET + 11;
+    private static final int OP_COPY_SIGN = OFFSET + 12;
+    private static final int OP_EXP = OFFSET + 13;
+    private static final int OP_FLOOR = OFFSET + 14;
+    private static final int OP_LOG = OFFSET + 15;
+    private static final int OP_LN = OFFSET + 16;
+    private static final int OP_ROUND = OFFSET + 17;
+    private static final int OP_SIN = OFFSET + 18;
+    private static final int OP_COS = OFFSET + 19;
+    private static final int OP_TAN = OFFSET + 20;
+    private static final int OP_ASIN = OFFSET + 21;
+    private static final int OP_ACOS = OFFSET + 22;
+    private static final int OP_ATAN = OFFSET + 23;
+    private static final int OP_ATAN2 = OFFSET + 24;
+    private static final int OP_MAD = OFFSET + 25;
+    private static final int OP_TERNARY_CONDITIONAL = OFFSET + 26;
+    private static final int OP_CLAMP = OFFSET + 27;
+    private static final int OP_CBRT = OFFSET + 28;
+    private static final int OP_DEG = OFFSET + 29;
+    private static final int OP_RAD = OFFSET + 30;
+    private static final int OP_CEIL = OFFSET + 31;
+    private static final int OP_A_DEREF = OFFSET + 32;
+    private static final int OP_A_MAX = OFFSET + 33;
+    private static final int OP_A_MIN = OFFSET + 34;
+    private static final int OP_A_SUM = OFFSET + 35;
+    private static final int OP_A_AVG = OFFSET + 36;
+    private static final int OP_A_LEN = OFFSET + 37;
+    private static final int OP_A_SPLINE = OFFSET + 38;
+    private static final int OP_FIRST_VAR = OFFSET + 39;
+    private static final int OP_SECOND_VAR = OFFSET + 40;
+    private static final int OP_THIRD_VAR = OFFSET + 41;
+
+    int opEval(int sp, int id) {
+        float[] array;
+
+        switch (id) {
+            case OP_ADD:
+                mStack[sp - 1] = mStack[sp - 1] + mStack[sp];
+                return sp - 1;
+
+            case OP_SUB:
+                mStack[sp - 1] = mStack[sp - 1] - mStack[sp];
+                return sp - 1;
+
+            case OP_MUL:
+                mStack[sp - 1] = mStack[sp - 1] * mStack[sp];
+                return sp - 1;
+
+            case OP_DIV:
+                mStack[sp - 1] = mStack[sp - 1] / mStack[sp];
+                return sp - 1;
+
+            case OP_MOD:
+                mStack[sp - 1] = mStack[sp - 1] % mStack[sp];
+                return sp - 1;
+
+            case OP_MIN:
+                mStack[sp - 1] = (float) Math.min(mStack[sp - 1], mStack[sp]);
+                return sp - 1;
+
+            case OP_MAX:
+                mStack[sp - 1] = (float) Math.max(mStack[sp - 1], mStack[sp]);
+                return sp - 1;
+
+            case OP_POW:
+                mStack[sp - 1] = (float) Math.pow(mStack[sp - 1], mStack[sp]);
+                return sp - 1;
+
+            case OP_SQRT:
+                mStack[sp] = (float) Math.sqrt(mStack[sp]);
+                return sp;
+
+            case OP_ABS:
+                mStack[sp] = (float) Math.abs(mStack[sp]);
+                return sp;
+
+            case OP_SIGN:
+                mStack[sp] = (float) Math.signum(mStack[sp]);
+                return sp;
+
+            case OP_COPY_SIGN:
+                mStack[sp - 1] = (float) Math.copySign(mStack[sp - 1], mStack[sp]);
+                return sp - 1;
+
+            case OP_EXP:
+                mStack[sp] = (float) Math.exp(mStack[sp]);
+                return sp;
+
+            case OP_FLOOR:
+                mStack[sp] = (float) Math.floor(mStack[sp]);
+                return sp;
+
+            case OP_LOG:
+                mStack[sp] = (float) Math.log10(mStack[sp]);
+                return sp;
+
+            case OP_LN:
+                mStack[sp] = (float) Math.log(mStack[sp]);
+                return sp;
+
+            case OP_ROUND:
+                mStack[sp] = (float) Math.round(mStack[sp]);
+                return sp;
+
+            case OP_SIN:
+                mStack[sp] = (float) Math.sin(mStack[sp]);
+                return sp;
+
+            case OP_COS:
+                mStack[sp] = (float) Math.cos(mStack[sp]);
+                return sp;
+
+            case OP_TAN:
+                mStack[sp] = (float) Math.tan(mStack[sp]);
+                return sp;
+
+            case OP_ASIN:
+                mStack[sp] = (float) Math.asin(mStack[sp]);
+                return sp;
+
+            case OP_ACOS:
+                mStack[sp] = (float) Math.acos(mStack[sp]);
+                return sp;
+
+            case OP_ATAN:
+                mStack[sp] = (float) Math.atan(mStack[sp]);
+                return sp;
+
+            case OP_ATAN2:
+                mStack[sp - 1] = (float) Math.atan2(mStack[sp - 1], mStack[sp]);
+                return sp - 1;
+
+            case OP_MAD:
+                mStack[sp - 2] = mStack[sp] + mStack[sp - 1] * mStack[sp - 2];
+                return sp - 2;
+
+            case OP_TERNARY_CONDITIONAL:
+                mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2];
+                return sp - 2;
+
+            case OP_CLAMP:
+                mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
+                return sp - 2;
+
+            case OP_CBRT:
+                mStack[sp] = (float) Math.pow(mStack[sp], 1 / 3.);
+                return sp;
+
+            case OP_DEG:
+                mStack[sp] = mStack[sp] * FP_TO_RAD;
+                return sp;
+
+            case OP_RAD:
+                mStack[sp] = mStack[sp] * FP_TO_DEG;
+                return sp;
+
+            case OP_CEIL:
+                mStack[sp] = (float) Math.ceil(mStack[sp]);
+                return sp;
+
+            case OP_A_DEREF:
+                id = fromNaN(mStack[sp - 1]);
+                mStack[sp - 1] = mCollectionsAccess.getFloatValue(id, (int) mStack[sp]);
+                return sp - 1;
+
+            case OP_A_MAX:
+                id = fromNaN(mStack[sp]);
+                array = mCollectionsAccess.getFloats(id);
+                float max = array[0];
+                for (int i = 1; i < array.length; i++) {
+                    max = Math.max(max, array[i]);
+                }
+                mStack[sp] = max;
+                return sp;
+
+            case OP_A_MIN:
+                id = fromNaN(mStack[sp]);
+                array = mCollectionsAccess.getFloats(id);
+                if (array.length == 0) {
+                    return sp;
+                }
+                float min = array[0];
+                for (int i = 1; i < array.length; i++) {
+                    min = Math.min(min, array[i]);
+                }
+                mStack[sp] = min;
+                return sp;
+
+            case OP_A_SUM:
+                id = fromNaN(mStack[sp]);
+                array = mCollectionsAccess.getFloats(id);
+                float sum = 0;
+                for (int i = 0; i < array.length; i++) {
+                    sum += array[i];
+                }
+                mStack[sp] = sum;
+                return sp;
+
+            case OP_A_AVG:
+                id = fromNaN(mStack[sp]);
+                array = mCollectionsAccess.getFloats(id);
+                sum = 0;
+                for (int i = 0; i < array.length; i++) {
+                    sum += array[i];
+                }
+                mStack[sp] = sum / array.length;
+                return sp;
+
+            case OP_A_LEN:
+                id = fromNaN(mStack[sp]);
+                mStack[sp] = mCollectionsAccess.getListLength(id);
+                return sp;
+
+            case OP_A_SPLINE:
+                id = fromNaN(mStack[sp - 1]);
+                mStack[sp - 1] = getSplineValue(id, mStack[sp]);
+                return sp - 1;
+
+            case OP_FIRST_VAR:
+                mStack[sp] = mVar[0];
+                return sp;
+
+            case OP_SECOND_VAR:
+                mStack[sp] = mVar[1];
+                return sp;
+
+            case OP_THIRD_VAR:
+                mStack[sp] = mVar[2];
+                return sp;
+        }
+        return sp;
+    }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java
index 4f12872..b92f96f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java
@@ -24,13 +24,39 @@
 public interface CollectionsAccess {
     float getFloatValue(int id, int index);
 
+    /**
+     * Get the array of float if it is a float array
+     *
+     * @param id the id of the float array
+     * @return
+     */
     @Nullable
     float[] getFloats(int id);
 
+    /**
+     * Get the number of entries in the list
+     *
+     * @param id the id of the list
+     * @return
+     */
     int getListLength(int id);
 
+    /**
+     * get the id of an entry if the list is a list of id's
+     *
+     * @param listId the list id
+     * @param index the index into the list
+     * @return
+     */
     int getId(int listId, int index);
 
+    /**
+     * Get the value as an integer
+     *
+     * @param listId the list id to access
+     * @param index the index into the list
+     * @return
+     */
     default int getIntValue(int listId, int index) {
         return (int) getFloatValue(listId, index);
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
index f73ab39..0a33511 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
@@ -82,7 +82,7 @@
         for (int i = 0; i < mStack.length; i++) {
             int v = mStack[i];
             if (((1 << i) & mask) != 0) {
-                sp = mOps[v - OFFSET].eval(sp);
+                sp = opEval(sp, v);
             } else {
                 mStack[++sp] = v;
             }
@@ -107,7 +107,7 @@
         for (int i = 0; i < len; i++) {
             int v = mStack[i];
             if (((1 << i) & mask) != 0) {
-                sp = mOps[v - OFFSET].eval(sp);
+                sp = opEval(sp, v);
             } else {
                 mStack[++sp] = v;
             }
@@ -130,7 +130,7 @@
         for (int i = 0; i < exp.length; i++) {
             int v = mStack[i];
             if (((1 << i) & opMask) != 0) {
-                sp = mOps[v - OFFSET].eval(sp);
+                sp = opEval(sp, v);
             } else {
                 mStack[++sp] = v;
             }
@@ -138,171 +138,140 @@
         return mStack[sp];
     }
 
-    @NonNull Op[] mOps;
+    private static final int OP_ADD = OFFSET + 1;
+    private static final int OP_SUB = OFFSET + 2;
+    private static final int OP_MUL = OFFSET + 3;
+    private static final int OP_DIV = OFFSET + 4;
+    private static final int OP_MOD = OFFSET + 5;
+    private static final int OP_SHL = OFFSET + 6;
+    private static final int OP_SHR = OFFSET + 7;
+    private static final int OP_USHR = OFFSET + 8;
+    private static final int OP_OR = OFFSET + 9;
+    private static final int OP_AND = OFFSET + 10;
+    private static final int OP_XOR = OFFSET + 11;
+    private static final int OP_COPY_SIGN = OFFSET + 12;
+    private static final int OP_MIN = OFFSET + 13;
+    private static final int OP_MAX = OFFSET + 14;
+    private static final int OP_NEG = OFFSET + 15;
+    private static final int OP_ABS = OFFSET + 16;
+    private static final int OP_INCR = OFFSET + 17;
+    private static final int OP_DECR = OFFSET + 18;
+    private static final int OP_NOT = OFFSET + 19;
+    private static final int OP_SIGN = OFFSET + 20;
+    private static final int OP_CLAMP = OFFSET + 21;
+    private static final int OP_TERNARY_CONDITIONAL = OFFSET + 22;
+    private static final int OP_MAD = OFFSET + 23;
+    private static final int OP_FIRST_VAR = OFFSET + 24;
+    private static final int OP_SECOND_VAR = OFFSET + 25;
+    private static final int OP_THIRD_VAR = OFFSET + 26;
 
-    {
-        Op mADD =
-                (sp) -> { // ADD
-                    mStack[sp - 1] = mStack[sp - 1] + mStack[sp];
-                    return sp - 1;
-                };
-        Op mSUB =
-                (sp) -> { // SUB
-                    mStack[sp - 1] = mStack[sp - 1] - mStack[sp];
-                    return sp - 1;
-                };
-        Op mMUL =
-                (sp) -> { // MUL
-                    mStack[sp - 1] = mStack[sp - 1] * mStack[sp];
-                    return sp - 1;
-                };
-        Op mDIV =
-                (sp) -> { // DIV
-                    mStack[sp - 1] = mStack[sp - 1] / mStack[sp];
-                    return sp - 1;
-                };
-        Op mMOD =
-                (sp) -> { // MOD
-                    mStack[sp - 1] = mStack[sp - 1] % mStack[sp];
-                    return sp - 1;
-                };
-        Op mSHL =
-                (sp) -> { // SHL
-                    mStack[sp - 1] = mStack[sp - 1] << mStack[sp];
-                    return sp - 1;
-                };
-        Op mSHR =
-                (sp) -> { // SHR
-                    mStack[sp - 1] = mStack[sp - 1] >> mStack[sp];
-                    return sp - 1;
-                };
-        Op mUSHR =
-                (sp) -> { // USHR
-                    mStack[sp - 1] = mStack[sp - 1] >>> mStack[sp];
-                    return sp - 1;
-                };
-        Op mOR =
-                (sp) -> { // OR
-                    mStack[sp - 1] = mStack[sp - 1] | mStack[sp];
-                    return sp - 1;
-                };
-        Op mAND =
-                (sp) -> { // AND
-                    mStack[sp - 1] = mStack[sp - 1] & mStack[sp];
-                    return sp - 1;
-                };
-        Op mXOR =
-                (sp) -> { // XOR
-                    mStack[sp - 1] = mStack[sp - 1] ^ mStack[sp];
-                    return sp - 1;
-                };
-        Op mCOPY_SIGN =
-                (sp) -> { // COPY_SIGN copy the sign via bit manipulation
-                    mStack[sp - 1] = (mStack[sp - 1] ^ (mStack[sp] >> 31)) - (mStack[sp] >> 31);
-                    return sp - 1;
-                };
-        Op mMIN =
-                (sp) -> { // MIN
-                    mStack[sp - 1] = Math.min(mStack[sp - 1], mStack[sp]);
-                    return sp - 1;
-                };
-        Op mMAX =
-                (sp) -> { // MAX
-                    mStack[sp - 1] = Math.max(mStack[sp - 1], mStack[sp]);
-                    return sp - 1;
-                };
-        Op mNEG =
-                (sp) -> { // NEG
-                    mStack[sp] = -mStack[sp];
-                    return sp;
-                };
-        Op mABS =
-                (sp) -> { // ABS
-                    mStack[sp] = Math.abs(mStack[sp]);
-                    return sp;
-                };
-        Op mINCR =
-                (sp) -> { // INCR
-                    mStack[sp] = mStack[sp] + 1;
-                    return sp;
-                };
-        Op mDECR =
-                (sp) -> { // DECR
-                    mStack[sp] = mStack[sp] - 1;
-                    return sp;
-                };
-        Op mNOT =
-                (sp) -> { // NOT
-                    mStack[sp] = ~mStack[sp];
-                    return sp;
-                };
-        Op mSIGN =
-                (sp) -> { // SIGN x<0 = -1,x==0 =  0 , x>0 = 1
-                    mStack[sp] = (mStack[sp] >> 31) | (-mStack[sp] >>> 31);
-                    return sp;
-                };
-        Op mCLAMP =
-                (sp) -> { // CLAMP(min,max, val)
-                    mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
-                    return sp - 2;
-                };
-        Op mTERNARY_CONDITIONAL =
-                (sp) -> { // TERNARY_CONDITIONAL
-                    mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2];
-                    return sp - 2;
-                };
-        Op mMAD =
-                (sp) -> { // MAD
-                    mStack[sp - 2] = mStack[sp] + mStack[sp - 1] * mStack[sp - 2];
-                    return sp - 2;
-                };
-        Op mFIRST_VAR =
-                (sp) -> { // FIRST_VAR
-                    mStack[sp] = mVar[0];
-                    return sp;
-                };
-        Op mSECOND_VAR =
-                (sp) -> { // SECOND_VAR
-                    mStack[sp] = mVar[1];
-                    return sp;
-                };
-        Op mTHIRD_VAR =
-                (sp) -> { // THIRD_VAR
-                    mStack[sp] = mVar[2];
-                    return sp;
-                };
+    int opEval(int sp, int id) {
+        switch (id) {
+            case OP_ADD: // ADD
+                mStack[sp - 1] = mStack[sp - 1] + mStack[sp];
+                return sp - 1;
 
-        Op[] ops = {
-            null,
-            mADD,
-            mSUB,
-            mMUL,
-            mDIV,
-            mMOD,
-            mSHL,
-            mSHR,
-            mUSHR,
-            mOR,
-            mAND,
-            mXOR,
-            mCOPY_SIGN,
-            mMIN,
-            mMAX,
-            mNEG,
-            mABS,
-            mINCR,
-            mDECR,
-            mNOT,
-            mSIGN,
-            mCLAMP,
-            mTERNARY_CONDITIONAL,
-            mMAD,
-            mFIRST_VAR,
-            mSECOND_VAR,
-            mTHIRD_VAR,
-        };
+            case OP_SUB: // SUB
+                mStack[sp - 1] = mStack[sp - 1] - mStack[sp];
+                return sp - 1;
 
-        mOps = ops;
+            case OP_MUL: // MUL
+                mStack[sp - 1] = mStack[sp - 1] * mStack[sp];
+                return sp - 1;
+
+            case OP_DIV: // DIV
+                mStack[sp - 1] = mStack[sp - 1] / mStack[sp];
+                return sp - 1;
+
+            case OP_MOD: // MOD
+                mStack[sp - 1] = mStack[sp - 1] % mStack[sp];
+                return sp - 1;
+
+            case OP_SHL: // SHL
+                mStack[sp - 1] = mStack[sp - 1] << mStack[sp];
+                return sp - 1;
+
+            case OP_SHR: // SHR
+                mStack[sp - 1] = mStack[sp - 1] >> mStack[sp];
+                return sp - 1;
+
+            case OP_USHR: // USHR
+                mStack[sp - 1] = mStack[sp - 1] >>> mStack[sp];
+                return sp - 1;
+
+            case OP_OR: // OR
+                mStack[sp - 1] = mStack[sp - 1] | mStack[sp];
+                return sp - 1;
+
+            case OP_AND: // AND
+                mStack[sp - 1] = mStack[sp - 1] & mStack[sp];
+                return sp - 1;
+
+            case OP_XOR: // XOR
+                mStack[sp - 1] = mStack[sp - 1] ^ mStack[sp];
+                return sp - 1;
+
+            case OP_COPY_SIGN: // COPY_SIGN copy the sign via bit manipulation
+                mStack[sp - 1] = (mStack[sp - 1] ^ (mStack[sp] >> 31)) - (mStack[sp] >> 31);
+                return sp - 1;
+
+            case OP_MIN: // MIN
+                mStack[sp - 1] = Math.min(mStack[sp - 1], mStack[sp]);
+                return sp - 1;
+
+            case OP_MAX: // MAX
+                mStack[sp - 1] = Math.max(mStack[sp - 1], mStack[sp]);
+                return sp - 1;
+
+            case OP_NEG: // NEG
+                mStack[sp] = -mStack[sp];
+                return sp;
+
+            case OP_ABS: // ABS
+                mStack[sp] = Math.abs(mStack[sp]);
+                return sp;
+
+            case OP_INCR: // INCR
+                mStack[sp] = mStack[sp] + 1;
+                return sp;
+
+            case OP_DECR: // DECR
+                mStack[sp] = mStack[sp] - 1;
+                return sp;
+
+            case OP_NOT: // NOT
+                mStack[sp] = ~mStack[sp];
+                return sp;
+
+            case OP_SIGN: // SIGN x<0 = -1,x==0 =  0 , x>0 = 1
+                mStack[sp] = (mStack[sp] >> 31) | (-mStack[sp] >>> 31);
+                return sp;
+
+            case OP_CLAMP: // CLAMP(min,max, val)
+                mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
+                return sp - 2;
+
+            case OP_TERNARY_CONDITIONAL: // TERNARY_CONDITIONAL
+                mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2];
+                return sp - 2;
+
+            case OP_MAD: // MAD
+                mStack[sp - 2] = mStack[sp] + mStack[sp - 1] * mStack[sp - 2];
+                return sp - 2;
+
+            case OP_FIRST_VAR: // FIRST_VAR
+                mStack[sp] = mVar[0];
+                return sp;
+
+            case OP_SECOND_VAR: // SECOND_VAR
+                mStack[sp] = mVar[1];
+                return sp;
+
+            case OP_THIRD_VAR: // THIRD_VAR
+                mStack[sp] = mVar[2];
+                return sp;
+        }
+        return 0;
     }
 
     static {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
index 7e02bc9..c7e2442 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
@@ -31,6 +31,11 @@
  * limitations under the License.
  */
 
+/**
+ * This computes an form of easing such that the values constrained to be consistent in velocity The
+ * easing function is also constrained by the configure To have: a maximum time to stop, a maximum
+ * velocity, a maximum acceleration
+ */
 public class VelocityEasing {
     private float mStartPos = 0;
     private float mStartV = 0;
@@ -46,6 +51,11 @@
     private boolean mOneDimension = true;
     private float mTotalEasingDuration = 0;
 
+    /**
+     * get the duration the easing will take
+     *
+     * @return the duration for the easing
+     */
     public float getDuration() {
         if (mEasing != null) {
             return mTotalEasingDuration;
@@ -53,6 +63,12 @@
         return mDuration;
     }
 
+    /**
+     * Get the velocity at time t
+     *
+     * @param t time in seconds
+     * @return the velocity units/second
+     */
     public float getV(float t) {
         if (mEasing == null) {
             for (int i = 0; i < mNumberOfStages; i++) {
@@ -71,6 +87,12 @@
         return (float) getEasingDiff((t - mStage[lastStages].mStartTime));
     }
 
+    /**
+     * Get the position t seconds after the configure
+     *
+     * @param t time in seconds
+     * @return the position at time t
+     */
     public float getPos(float t) {
         if (mEasing == null) {
             for (int i = 0; i < mNumberOfStages; i++) {
@@ -91,6 +113,7 @@
         return ret;
     }
 
+    @Override
     public String toString() {
         var s = " ";
         for (int i = 0; i < mNumberOfStages; i++) {
@@ -100,6 +123,17 @@
         return s;
     }
 
+    /**
+     * Configure the Velocity easing curve The system is in arbitrary units
+     *
+     * @param currentPos the current position
+     * @param destination the destination
+     * @param currentVelocity the current velocity units/seconds
+     * @param maxTime the max time to achieve position
+     * @param maxAcceleration the max acceleration units/s^2
+     * @param maxVelocity the maximum velocity
+     * @param easing End in using this easing curve
+     */
     public void config(
             float currentPos,
             float destination,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java
index 4af79f3..975213f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java
@@ -29,7 +29,7 @@
 import java.util.List;
 
 /** Used to represent a boolean */
-public class BooleanConstant implements Operation {
+public class BooleanConstant extends Operation {
     private static final int OP_CODE = Operations.DATA_BOOLEAN;
     private boolean mValue = false;
     private int mId;
@@ -73,6 +73,11 @@
         return "OrigamiBoolean";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.DATA_BOOLEAN;
     }
@@ -90,6 +95,12 @@
         buffer.writeBoolean(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
 
diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java
index 613e732..210a15a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java
@@ -29,7 +29,7 @@
 import java.util.List;
 
 /** Represents a single integer typically used for states or named for input into the system */
-public class IntegerConstant implements Operation {
+public class IntegerConstant extends Operation {
     private int mValue = 0;
     private int mId;
 
@@ -65,6 +65,11 @@
         return "IntegerConstant";
     }
 
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
     public static int id() {
         return Operations.DATA_INT;
     }
@@ -82,6 +87,12 @@
         buffer.writeInt(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
 
diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java
index 745caa3..9875c93 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java
@@ -29,7 +29,7 @@
 import java.util.List;
 
 /** Used to represent a long */
-public class LongConstant implements Operation {
+public class LongConstant extends Operation {
     private static final int OP_CODE = Operations.DATA_LONG;
     private long mValue;
     private int mId;
@@ -83,6 +83,12 @@
         buffer.writeLong(value);
     }
 
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
     public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
         int id = buffer.readInt();
 
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
index 648f7bf..19b4b36 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
@@ -659,4 +659,14 @@
         }
         mListener = null;
     }
+
+    /**
+     * This returns the amount of time in ms the player used to evalueate a pass it is averaged over
+     * a number of evaluations.
+     *
+     * @return time in ms
+     */
+    public float getEvalTime() {
+        return mInner.getEvalTime();
+    }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
index 3c91cff..bc7d5e1 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
@@ -529,6 +529,7 @@
                     @Override
                     public void setImageFilterQuality(int quality) {
                         Utils.log(" quality =" + quality);
+                        mPaint.setFilterBitmap(quality == 1);
                     }
 
                     @Override
@@ -711,20 +712,32 @@
     }
 
     @Override
+    public void tweenPath(int out, int path1, int path2, float tween) {
+        float[] p = getPathArray(path1, path2, tween);
+        AndroidRemoteContext androidContext = (AndroidRemoteContext) mContext;
+        androidContext.mRemoteComposeState.putPathData(out, p);
+    }
+
+    @Override
     public void reset() {
         mPaint.reset();
     }
 
     private Path getPath(int path1Id, int path2Id, float tween, float start, float end) {
+        return getPath(getPathArray(path1Id, path2Id, tween), start, end);
+    }
+
+    private float[] getPathArray(int path1Id, int path2Id, float tween) {
+        AndroidRemoteContext androidContext = (AndroidRemoteContext) mContext;
         if (tween == 0.0f) {
-            return getPath(path1Id, start, end);
+            return androidContext.mRemoteComposeState.getPathData(path1Id);
         }
         if (tween == 1.0f) {
-            return getPath(path2Id, start, end);
+            return androidContext.mRemoteComposeState.getPathData(path2Id);
         }
-        AndroidRemoteContext androidContext = (AndroidRemoteContext) mContext;
-        float[] data1 = (float[]) androidContext.mRemoteComposeState.getFromId(path1Id);
-        float[] data2 = (float[]) androidContext.mRemoteComposeState.getFromId(path2Id);
+
+        float[] data1 = androidContext.mRemoteComposeState.getPathData(path1Id);
+        float[] data2 = androidContext.mRemoteComposeState.getPathData(path2Id);
         float[] tmp = new float[data2.length];
         for (int i = 0; i < tmp.length; i++) {
             if (Float.isNaN(data1[i]) || Float.isNaN(data2[i])) {
@@ -733,6 +746,10 @@
                 tmp[i] = (data2[i] - data1[i]) * tween + data1[i];
             }
         }
+        return tmp;
+    }
+
+    private Path getPath(float[] tmp, float start, float end) {
         Path path = new Path();
         FloatsToPath.genPath(path, tmp, start, end);
         return path;
@@ -741,9 +758,9 @@
     private Path getPath(int id, float start, float end) {
         AndroidRemoteContext androidContext = (AndroidRemoteContext) mContext;
         Path path = new Path();
-        if (androidContext.mRemoteComposeState.containsId(id)) {
-            float[] data = (float[]) androidContext.mRemoteComposeState.getFromId(id);
-            FloatsToPath.genPath(path, data, start, end);
+        float[] pathData = androidContext.mRemoteComposeState.getPathData(id);
+        if (pathData != null) {
+            FloatsToPath.genPath(path, pathData, start, end);
         }
         return path;
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
index 77c2514..0fb0a28 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
@@ -60,9 +60,12 @@
 
     @Override
     public void loadPathData(int instanceId, @NonNull float[] floatPath) {
-        if (!mRemoteComposeState.containsId(instanceId)) {
-            mRemoteComposeState.cacheData(instanceId, floatPath);
-        }
+        mRemoteComposeState.putPathData(instanceId, floatPath);
+    }
+
+    @Override
+    public float[] getPathData(int instanceId) {
+        return mRemoteComposeState.getPathData(instanceId);
     }
 
     static class VarName {
@@ -162,7 +165,7 @@
      * @param type the type of the data 0 = RGBA 8888, 1 = 888, 2 = 8 gray
      * @param width with of image to be loaded largest dimension is 32767
      * @param height height of image to be loaded
-     * @param bitmap a byte array containing the image information
+     * @param data a byte array containing the image information
      * @oaram imageId the id of the image
      */
     @Override
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
index 8f55f8a..ecfd13a 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
@@ -349,6 +349,27 @@
 
     private int mCount;
     private long mTime = System.nanoTime();
+    private long mDuration;
+    private boolean mEvalTime = false;
+
+    /**
+     * This returns the amount of time in ms the player used to evalueate a pass it is averaged over
+     * a number of evaluations.
+     *
+     * @return time in ms
+     */
+    public float getEvalTime() {
+        if (!mEvalTime) {
+            mEvalTime = true;
+            return 0.0f;
+        }
+        double avg = mDuration / (double) mCount;
+        if (mCount > 100) {
+            mDuration /= 2;
+            mCount /= 2;
+        }
+        return (float) (avg * 1E-6); // ms
+    }
 
     @Override
     protected void onDraw(Canvas canvas) {
@@ -356,6 +377,7 @@
         if (mDocument == null) {
             return;
         }
+        long start = mEvalTime ? System.nanoTime() : 0;
         mARContext.setAnimationEnabled(true);
         mARContext.currentTime = System.currentTimeMillis();
         mARContext.setDebug(mDebug);
@@ -376,5 +398,9 @@
         if (mDocument.needsRepaint() > 0) {
             invalidate();
         }
+        if (mEvalTime) {
+            mDuration += System.nanoTime() - start;
+            mCount++;
+        }
     }
 }
diff --git a/core/java/com/android/server/pm/pkg/AndroidPackage.java b/core/java/com/android/server/pm/pkg/AndroidPackage.java
index d05f5e3..70dd10f 100644
--- a/core/java/com/android/server/pm/pkg/AndroidPackage.java
+++ b/core/java/com/android/server/pm/pkg/AndroidPackage.java
@@ -875,6 +875,14 @@
     int getMemtagMode();
 
     /**
+     * @see ApplicationInfo#getPageSizeAppCompatFlags()
+     * @see R.styleable#AndroidManifestApplication_pageSizeCompat
+     * @hide
+     */
+    @ApplicationInfo.PageSizeAppCompatFlags
+    int getPageSizeAppCompatFlags();
+
+    /**
      * TODO(b/135203078): Make all the Bundles immutable (and non-null by shared empty reference?)
      * @see R.styleable#AndroidManifestMetaData
      * @hide
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index a21bf9a..5c03c5c 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -161,6 +161,7 @@
                 "android_view_MotionPredictor.cpp",
                 "android_view_PointerIcon.cpp",
                 "android_view_SurfaceControl.cpp",
+                "android_view_SurfaceControlActivePictureListener.cpp",
                 "android_view_SurfaceControlHdrLayerInfoListener.cpp",
                 "android_view_WindowManagerGlobal.cpp",
                 "android_graphics_BLASTBufferQueue.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 821861e..00a6297 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -128,6 +128,7 @@
 extern int register_android_view_InputWindowHandle(JNIEnv* env);
 extern int register_android_view_Surface(JNIEnv* env);
 extern int register_android_view_SurfaceControl(JNIEnv* env);
+extern int register_android_view_SurfaceControlActivePictureListener(JNIEnv* env);
 extern int register_android_view_SurfaceControlHdrLayerInfoListener(JNIEnv* env);
 extern int register_android_view_SurfaceSession(JNIEnv* env);
 extern int register_android_view_CompositionSamplingListener(JNIEnv* env);
@@ -1563,6 +1564,7 @@
         REG_JNI(register_android_view_DisplayEventReceiver),
         REG_JNI(register_android_view_Surface),
         REG_JNI(register_android_view_SurfaceControl),
+        REG_JNI(register_android_view_SurfaceControlActivePictureListener),
         REG_JNI(register_android_view_SurfaceControlHdrLayerInfoListener),
         REG_JNI(register_android_view_SurfaceSession),
         REG_JNI(register_android_view_InputApplicationHandle),
diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp
index ded1a99..1e7bfe3 100644
--- a/core/jni/android_content_res_ApkAssets.cpp
+++ b/core/jni/android_content_res_ApkAssets.cpp
@@ -36,6 +36,8 @@
 
 namespace android {
 
+static constexpr bool kLogWeakReachableDeletedAssets = false;
+
 static struct overlayableinfo_offsets_t {
   jclass classObject;
   jmethodID constructor;
@@ -97,7 +99,7 @@
       if (useCount > 1) {
         ALOGW("ApkAssets: Deleting an object '%s' with %d > 1 strong and %d weak references",
               (*assets)->GetDebugName().c_str(), int(useCount), int(weakCount));
-      } else if (weakCount > 0) {
+      } else if constexpr (kLogWeakReachableDeletedAssets) if (weakCount > 0) {
         ALOGW("ApkAssets: Deleting an ApkAssets object '%s' with %d weak references",
               (*assets)->GetDebugName().c_str(), int(weakCount));
       }
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 593b982..0c243d1 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -55,6 +55,7 @@
 #include <ui/FrameStats.h>
 #include <ui/GraphicTypes.h>
 #include <ui/HdrCapabilities.h>
+#include <ui/PictureProfileHandle.h>
 #include <ui/Rect.h>
 #include <ui/Region.h>
 #include <ui/StaticDisplayInfo.h>
@@ -118,6 +119,7 @@
     jfieldID renderFrameRate;
     jfieldID hasArrSupport;
     jfieldID frameRateCategoryRate;
+    jfieldID supportedRefreshRates;
     jfieldID supportedColorModes;
     jfieldID activeColorMode;
     jfieldID hdrCapabilities;
@@ -820,6 +822,21 @@
     transaction->setLuts(ctrl, base::unique_fd(fd), offsets, dimensions, sizes, samplingKeys);
 }
 
+static void nativeSetPictureProfileId(JNIEnv* env, jclass clazz, jlong transactionObj,
+                                      jlong surfaceControlObj, jlong pictureProfileId) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(surfaceControlObj);
+    PictureProfileHandle handle(pictureProfileId);
+    transaction->setPictureProfileHandle(surfaceControl, handle);
+}
+
+static void nativeSetContentPriority(JNIEnv* env, jclass clazz, jlong transactionObj,
+                                     jlong surfaceControlObj, jint priority) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(surfaceControlObj);
+    transaction->setContentPriority(surfaceControl, priority);
+}
+
 static void nativeSetCachingHint(JNIEnv* env, jclass clazz, jlong transactionObj,
                                  jlong nativeObject, jint cachingHint) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -1492,6 +1509,21 @@
     env->SetBooleanField(object, gDynamicDisplayInfoClassInfo.hasArrSupport, info.hasArrSupport);
     env->SetObjectField(object, gDynamicDisplayInfoClassInfo.frameRateCategoryRate,
                         convertFrameRateCategoryRateToJavaObject(env, info.frameRateCategoryRate));
+
+    jfloatArray supportedRefreshRatesArray = env->NewFloatArray(info.supportedRefreshRates.size());
+    if (supportedRefreshRatesArray == NULL) {
+        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+        return NULL;
+    }
+    jfloat* supportedRefreshRatesArrayValues =
+            env->GetFloatArrayElements(supportedRefreshRatesArray, 0);
+    for (size_t i = 0; i < info.supportedRefreshRates.size(); i++) {
+        supportedRefreshRatesArrayValues[i] = static_cast<jfloat>(info.supportedRefreshRates[i]);
+    }
+    env->ReleaseFloatArrayElements(supportedRefreshRatesArray, supportedRefreshRatesArrayValues, 0);
+    env->SetObjectField(object, gDynamicDisplayInfoClassInfo.supportedRefreshRates,
+                        supportedRefreshRatesArray);
+
     jintArray colorModesArray = env->NewIntArray(info.supportedColorModes.size());
     if (colorModesArray == NULL) {
         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
@@ -2351,6 +2383,20 @@
     return error == OK ? JNI_TRUE : JNI_FALSE;
 }
 
+static jint nativeGetMaxPictureProfiles(JNIEnv* env, jclass clazz) {
+    const auto displayIds = SurfaceComposerClient::SurfaceComposerClient::getPhysicalDisplayIds();
+    int largestMaxProfiles = 0;
+    for (auto displayId : displayIds) {
+        sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(displayId);
+        int32_t maxProfiles = 0;
+        SurfaceComposerClient::getMaxLayerPictureProfiles(token, &maxProfiles);
+        if (maxProfiles > largestMaxProfiles) {
+            largestMaxProfiles = maxProfiles;
+        }
+    }
+    return largestMaxProfiles;
+}
+
 jlong nativeCreateTpc(JNIEnv* env, jclass clazz, jobject trustedPresentationCallback) {
     return reinterpret_cast<jlong>(
             new TrustedPresentationCallbackWrapper(env, trustedPresentationCallback));
@@ -2672,6 +2718,8 @@
                 (void*)nativeGetDefaultApplyToken },
     {"nativeBootFinished", "()Z",
             (void*)nativeBootFinished },
+    {"nativeGetMaxPictureProfiles", "()I",
+            (void*)nativeGetMaxPictureProfiles },
     {"nativeCreateTpc", "(Landroid/view/SurfaceControl$TrustedPresentationCallback;)J",
             (void*)nativeCreateTpc},
     {"getNativeTrustedPresentationCallbackFinalizer", "()J", (void*)getNativeTrustedPresentationCallbackFinalizer },
@@ -2683,6 +2731,8 @@
             (void*)nativeNotifyShutdown },
     {"nativeSetLuts", "(JJ[F[I[I[I[I)V", (void*)nativeSetLuts },
     {"nativeEnableDebugLogCallPoints", "(J)V", (void*)nativeEnableDebugLogCallPoints },
+    {"nativeSetPictureProfileId", "(JJJ)V", (void*)nativeSetPictureProfileId },
+    {"nativeSetContentPriority", "(JJI)V", (void*)nativeSetContentPriority },
         // clang-format on
 };
 
@@ -2732,6 +2782,8 @@
     gFrameRateCategoryRateClassInfo.ctor =
             GetMethodIDOrDie(env, frameRateCategoryRateClazz, "<init>", "(FF)V");
 
+    gDynamicDisplayInfoClassInfo.supportedRefreshRates =
+            GetFieldIDOrDie(env, dynamicInfoClazz, "supportedRefreshRates", "[F");
     gDynamicDisplayInfoClassInfo.supportedColorModes =
             GetFieldIDOrDie(env, dynamicInfoClazz, "supportedColorModes", "[I");
     gDynamicDisplayInfoClassInfo.activeColorMode =
diff --git a/core/jni/android_view_SurfaceControlActivePictureListener.cpp b/core/jni/android_view_SurfaceControlActivePictureListener.cpp
new file mode 100644
index 0000000..91849c1
--- /dev/null
+++ b/core/jni/android_view_SurfaceControlActivePictureListener.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SurfaceControlActivePictureListener"
+
+#include <android/gui/BnActivePictureListener.h>
+#include <android_runtime/Log.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <utils/RefBase.h>
+
+#include "android_util_Binder.h"
+#include "core_jni_helpers.h"
+
+namespace android {
+
+namespace {
+
+struct {
+    jclass clazz;
+    jmethodID onActivePicturesChanged;
+} gListenerClassInfo;
+
+static struct {
+    jclass clazz;
+    jmethodID constructor;
+} gActivePictureClassInfo;
+
+static struct {
+    jclass clazz;
+    jmethodID constructor;
+    jfieldID id;
+} gPictureProfileHandleClassInfo;
+
+struct SurfaceControlActivePictureListener : public gui::BnActivePictureListener {
+    SurfaceControlActivePictureListener(JNIEnv* env, jobject listener)
+          : mListener(env->NewGlobalRef(listener)) {
+        LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mVm) != JNI_OK, "Failed to GetJavaVm");
+    }
+
+    binder::Status onActivePicturesChanged(
+            const std::vector<gui::ActivePicture>& activePictures) override {
+        JNIEnv* env = requireEnv();
+
+        ScopedLocalRef<jobjectArray> activePictureArrayObj(env);
+        activePictureArrayObj.reset(
+                env->NewObjectArray(activePictures.size(), gActivePictureClassInfo.clazz, NULL));
+        if (env->ExceptionCheck() || !activePictureArrayObj.get()) {
+            LOGE_EX(env);
+            LOG_ALWAYS_FATAL("Failed to create an active picture array.");
+        }
+
+        {
+            std::vector<ScopedLocalRef<jobject>> pictureProfileHandleObjs;
+            std::vector<ScopedLocalRef<jobject>> activePictureObjs;
+
+            for (size_t i = 0; i < activePictures.size(); ++i) {
+                pictureProfileHandleObjs.push_back(ScopedLocalRef<jobject>(env));
+                pictureProfileHandleObjs[i].reset(
+                        env->NewObject(gPictureProfileHandleClassInfo.clazz,
+                                       gPictureProfileHandleClassInfo.constructor,
+                                       activePictures[i].pictureProfileId));
+                if (env->ExceptionCheck() || !pictureProfileHandleObjs[i].get()) {
+                    LOGE_EX(env);
+                    LOG_ALWAYS_FATAL("Failed to create a picture profile handle.");
+                }
+                activePictureObjs.push_back(ScopedLocalRef<jobject>(env));
+                activePictureObjs[i].reset(env->NewObject(gActivePictureClassInfo.clazz,
+                                                          gActivePictureClassInfo.constructor,
+                                                          activePictures[i].layerId,
+                                                          activePictures[i].ownerUid,
+                                                          pictureProfileHandleObjs[i].get()));
+                if (env->ExceptionCheck() || !activePictureObjs[i].get()) {
+                    LOGE_EX(env);
+                    LOG_ALWAYS_FATAL("Failed to create an active picture.");
+                }
+                env->SetObjectArrayElement(activePictureArrayObj.get(), i,
+                                           activePictureObjs[i].get());
+            }
+
+            env->CallVoidMethod(mListener, gListenerClassInfo.onActivePicturesChanged,
+                                activePictureArrayObj.get());
+        }
+
+        if (env->ExceptionCheck()) {
+            ALOGE("SurfaceControlActivePictureListener.onActivePicturesChanged failed");
+            LOGE_EX(env);
+            env->ExceptionClear();
+        }
+        return binder::Status::ok();
+    }
+
+    status_t startListening() {
+        // TODO(b/337330263): Make SF multiple-listener capable
+        return SurfaceComposerClient::setActivePictureListener(this);
+    }
+
+    status_t stopListening() {
+        return SurfaceComposerClient::setActivePictureListener(nullptr);
+    }
+
+protected:
+    virtual ~SurfaceControlActivePictureListener() {
+        JNIEnv* env = requireEnv();
+        env->DeleteGlobalRef(mListener);
+    }
+
+    JNIEnv* requireEnv() {
+        JNIEnv* env = nullptr;
+        if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+            if (mVm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) {
+                LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!");
+            }
+        }
+        return env;
+    }
+
+private:
+    jobject mListener;
+    JavaVM* mVm;
+};
+
+jlong nativeMakeAndStartListening(JNIEnv* env, jobject jthis) {
+    auto listener = sp<SurfaceControlActivePictureListener>::make(env, jthis);
+    status_t err = listener->startListening();
+    if (err != OK) {
+        auto errStr = statusToString(err);
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                             "Failed to start listening, err = %d (%s)", err, errStr.c_str());
+        return 0;
+    }
+    SurfaceControlActivePictureListener* listenerRawPtr = listener.get();
+    listenerRawPtr->incStrong(0);
+    return static_cast<jlong>(reinterpret_cast<intptr_t>(listenerRawPtr));
+}
+
+static void destroy(SurfaceControlActivePictureListener* listener) {
+    listener->stopListening();
+    listener->decStrong(0);
+}
+
+static jlong nativeGetDestructor(JNIEnv* env, jobject clazz) {
+    return static_cast<jlong>(reinterpret_cast<intptr_t>(&destroy));
+}
+
+const JNINativeMethod gMethods[] = {
+        /* name, signature, funcPtr */
+        {"nativeGetDestructor", "()J", (void*)nativeGetDestructor},
+        {"nativeMakeAndStartListening", "()J", (void*)nativeMakeAndStartListening}};
+} // namespace
+
+int register_android_view_SurfaceControlActivePictureListener(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "android/view/SurfaceControlActivePictureListener",
+                                       gMethods, NELEM(gMethods));
+    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    jclass listenerClazz = env->FindClass("android/view/SurfaceControlActivePictureListener");
+    gListenerClassInfo.clazz = MakeGlobalRefOrDie(env, listenerClazz);
+    gListenerClassInfo.onActivePicturesChanged =
+            env->GetMethodID(listenerClazz, "onActivePicturesChanged",
+                             "([Landroid/view/SurfaceControlActivePicture;)V");
+
+    gActivePictureClassInfo.clazz = static_cast<jclass>(
+            env->NewGlobalRef(env->FindClass("android/view/SurfaceControlActivePicture")));
+    gActivePictureClassInfo.constructor =
+            env->GetMethodID(gActivePictureClassInfo.clazz, "<init>",
+                             "(IILandroid/media/quality/PictureProfileHandle;)V");
+
+    gPictureProfileHandleClassInfo.clazz = static_cast<jclass>(
+            env->NewGlobalRef(env->FindClass("android/media/quality/PictureProfileHandle")));
+    gPictureProfileHandleClassInfo.constructor =
+            env->GetMethodID(gPictureProfileHandleClassInfo.clazz, "<init>", "(J)V");
+    return 0;
+}
+
+} // namespace android
diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto
index b7408a4..facadee 100644
--- a/core/proto/android/content/package_item_info.proto
+++ b/core/proto/android/content/package_item_info.proto
@@ -114,6 +114,7 @@
         optional int32 enable_memtag = 20;
         optional bool native_heap_zero_init = 21;
         optional bool allow_cross_uid_activity_switch_from_below = 22;
+        optional int32 enable_page_size_app_compat = 23;
     }
     optional Detail detail = 17;
     repeated string overlay_paths = 18;
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 6af742f..2e0fe9e 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -256,6 +256,12 @@
     }
     optional Display display = 100;
 
+    message DoubleTapPowerButton {
+        optional SettingProto gesture_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto gesture = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+    optional DoubleTapPowerButton double_tap_power_button = 103;
+
     message Doze {
         option (android.msg_privacy).dest = DEST_EXPLICIT;
 
@@ -737,5 +743,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 103;
+    // Next tag = 104;
 }
diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto
index 9779dc0e..16d2565 100644
--- a/core/proto/android/providers/settings/system.proto
+++ b/core/proto/android/providers/settings/system.proto
@@ -217,6 +217,7 @@
         optional SettingProto right_click_zone = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto tap_to_click = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto tap_dragging = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto three_finger_tap_customization = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional Touchpad touchpad = 36;
 
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 8042b30..aacd869 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -160,6 +160,7 @@
         "android.app.contextualsearch.flags-aconfig",
         "android.app.flags-aconfig",
         "android.appwidget.flags-aconfig",
+        "android.companion.virtualdevice.flags-aconfig",
         "android.content.pm.flags-aconfig",
         "android.media.audio-aconfig",
         "android.provider.flags-aconfig",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index dae182f..e2f3d2a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -848,10 +848,10 @@
     <protected-broadcast android:name="android.app.action.CONSOLIDATED_NOTIFICATION_POLICY_CHANGED" />
     <protected-broadcast android:name="android.intent.action.MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED" />
     <protected-broadcast android:name="com.android.uwb.uwbcountrycode.GEOCODE_RETRY" />
-    <protected-broadcast android:name="android.telephony.action.ACTION_SATELLITE_SUBSCRIBER_ID_LIST_CHANGED" />
+    <protected-broadcast android:name="android.telephony.satellite.action.SATELLITE_SUBSCRIBER_ID_LIST_CHANGED" />
     <protected-broadcast android:name="android.service.ondeviceintelligence.MODEL_LOADED" />
     <protected-broadcast android:name="android.service.ondeviceintelligence.MODEL_UNLOADED" />
-    <protected-broadcast android:name="android.telephony.action.ACTION_SATELLITE_START_NON_EMERGENCY_SESSION" />
+    <protected-broadcast android:name="android.telephony.satellite.action.SATELLITE_START_NON_EMERGENCY_SESSION" />
 
 
     <!-- ====================================================================== -->
@@ -4201,18 +4201,19 @@
                 android:protectionLevel="signature|installer" />
     <uses-permission android:name="android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES" />
 
-    <!-- Allows an application to toggle the device's advanced protection mode status.
-        @FlaggedApi("android.security.aapm_api")
+    <!-- Allows an application to modify the device's advanced protection mode status, and query
+         the list of enabled features
+        @FlaggedApi(android.security.Flags.FLAG_AAPM_API)
         @SystemApi
         @hide -->
-    <permission android:name="android.permission.SET_ADVANCED_PROTECTION_MODE"
+    <permission android:name="android.permission.MANAGE_ADVANCED_PROTECTION_MODE"
         android:protectionLevel="signature|privileged"
         android:featureFlag="android.security.aapm_api"/>
-    <uses-permission android:name="android.permission.SET_ADVANCED_PROTECTION_MODE"
+    <uses-permission android:name="android.permission.MANAGE_ADVANCED_PROTECTION_MODE"
         android:featureFlag="android.security.aapm_api"/>
 
     <!-- Allows an application to query the device's advanced protection mode status.
-        @FlaggedApi("android.security.aapm_api") -->
+        @FlaggedApi(android.security.Flags.FLAG_AAPM_API) -->
     <permission android:name="android.permission.QUERY_ADVANCED_PROTECTION_MODE"
         android:protectionLevel="normal"
         android:featureFlag="android.security.aapm_api"/>
@@ -6515,7 +6516,7 @@
      @hide -->
     <permission android:name="android.permission.BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION"
         android:featureFlag="android.media.audio.concurrent_audio_record_bypass_permission"
-        android:protectionLevel="signature|privileged|role" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to capture audio for hotword detection.
          <p>Not for use by third-party applications.</p>
@@ -8059,6 +8060,13 @@
     <permission android:name="android.permission.ADD_ALWAYS_UNLOCKED_DISPLAY"
                 android:protectionLevel="signature|role"/>
 
+    <!-- Allows an application to create displays that mirror other displays' content.
+         @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ENABLE_LIMITED_VDM_ROLE)
+         @hide @SystemApi -->
+    <permission android:name="android.permission.ADD_MIRROR_DISPLAY"
+        android:protectionLevel="internal|role"
+        android:featureFlag="android.companion.virtualdevice.flags.enable_limited_vdm_role" />
+
     <!-- @hide @SystemApi Allows an application to access locusId events in the usage stats. -->
     <permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"
                 android:protectionLevel="signature|role" />
@@ -8716,29 +8724,6 @@
     <permission android:name="android.permission.RESERVED_FOR_TESTING_SIGNATURE"
                 android:protectionLevel="signature"/>
 
-    <!-- @SystemApi
-        @FlaggedApi("android.content.pm.verification_service")
-        Allows app to be the verification agent to verify packages.
-        <p>Protection level: signature|privileged
-        @hide
-    -->
-    <permission android:name="android.permission.VERIFICATION_AGENT"
-        android:protectionLevel="signature|privileged"
-        android:featureFlag="android.content.pm.verification_service" />
-
-    <!-- @SystemApi
-        @FlaggedApi("android.content.pm.verification_service")
-        Must be required by a privileged {@link android.content.pm.verify.pkg.VerifierService}
-        to ensure that only the system can bind to it.
-        This permission should not be held by anything other than the system.
-        <p>Not for use by third-party applications. </p>
-        <p>Protection level: signature
-        @hide
-    -->
-    <permission android:name="android.permission.BIND_VERIFICATION_AGENT"
-        android:protectionLevel="internal"
-        android:featureFlag="android.content.pm.verification_service" />
-
     <!--
         This permission allows the system to receive PACKAGE_CHANGED broadcasts when the component
         state of a non-exported component has been changed.
@@ -9366,6 +9351,17 @@
             </intent-filter>
         </service>
 
+        <service android:name="com.android.ecm.EnhancedConfirmationCallTrackerService"
+            android:permission="android.permission.BIND_INCALL_SERVICE"
+            android:featureFlag="android.permission.flags.enhanced_confirmation_in_call_apis_enabled"
+            android:exported="true">
+            <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+                android:value="true" />
+            <intent-filter>
+                <action android:name="android.telecom.InCallService"/>
+            </intent-filter>
+        </service>
+
         <service android:name="com.android.server.companion.datatransfer.contextsync.CallMetadataSyncConnectionService"
                  android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
                  android:exported="true">
diff --git a/core/res/res/drawable-watch-v36/btn_background_material_filled.xml b/core/res/res/drawable-watch-v36/btn_background_material_filled.xml
index 0029de1..6e74f64 100644
--- a/core/res/res/drawable-watch-v36/btn_background_material_filled.xml
+++ b/core/res/res/drawable-watch-v36/btn_background_material_filled.xml
@@ -19,7 +19,7 @@
     <item>
         <shape android:shape="rectangle">
             <solid android:color="@color/btn_material_filled_background_color"/>
-            <corners android:radius="?android:attr/buttonCornerRadius"/>
+            <corners android:radius="@dimen/config_wearMaterial3_buttonCornerRadius"/>
             <size
                 android:width="@dimen/btn_material_width"
                 android:height="@dimen/btn_material_height" />
diff --git a/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml b/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml
index 105f077..fbd6973 100644
--- a/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml
+++ b/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml
@@ -19,7 +19,7 @@
     <item>
         <shape android:shape="rectangle">
             <solid android:color="@color/btn_material_filled_tonal_background_color"/>
-            <corners android:radius="?android:attr/buttonCornerRadius"/>
+            <corners android:radius="@dimen/config_wearMaterial3_buttonCornerRadius"/>
             <size
                 android:width="@dimen/btn_material_width"
                 android:height="@dimen/btn_material_height" />
diff --git a/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml b/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml
index b6b8eac3..0314bbe 100644
--- a/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml
+++ b/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml
@@ -18,7 +18,7 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
     <solid android:color="@color/btn_material_filled_tonal_background_color"/>
-    <corners android:radius="@dimen/config_bottomDialogCornerRadius" />
+    <corners android:radius="@dimen/config_wearMaterial3_bottomDialogCornerRadius" />
     <size
         android:width="@dimen/dialog_btn_negative_width"
         android:height="@dimen/dialog_btn_negative_height" />
diff --git a/core/res/res/layout-sw600dp/preference_list_content_single.xml b/core/res/res/layout-sw600dp/preference_list_content_single.xml
index 88b1aa8..ebe4eca 100644
--- a/core/res/res/layout-sw600dp/preference_list_content_single.xml
+++ b/core/res/res/layout-sw600dp/preference_list_content_single.xml
@@ -19,6 +19,7 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
+    android:fitsSystemWindows="true"
     android:layout_height="match_parent"
     android:layout_width="match_parent">
 
diff --git a/core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml b/core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml
new file mode 100644
index 0000000..407ec7a
--- /dev/null
+++ b/core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml
@@ -0,0 +1,123 @@
+<!--
+  ~ 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.
+  -->
+
+<!-- This layout is the AlertDialog template. It overrides the system layout with the same name.
+    Make sure to include all the existing id of the overridden alert_dialog_material.-->
+<com.android.internal.widget.WatchListDecorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/parentPanel"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ScrollView
+        android:id="@+id/scrollView"
+        android:fillViewport="true"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <!-- Top Panel -->
+            <FrameLayout
+                android:paddingLeft="?dialogPreferredPadding"
+                android:paddingRight="?dialogPreferredPadding"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/topPanel"
+                android:minHeight="@dimen/dialog_list_padding_top_no_title">
+                <include android:id="@+id/title_template"
+                         android:layout_width="match_parent"
+                         android:layout_height="wrap_content"
+                         layout="@layout/alert_dialog_title_material"/>
+            </FrameLayout>
+
+            <!-- Content Panel -->
+            <FrameLayout android:id="@+id/contentPanel"
+                         android:layout_width="match_parent"
+                         android:layout_height="wrap_content"
+                         android:clipToPadding="false">
+                <TextView android:id="@+id/message"
+                          android:layout_width="match_parent"
+                          android:layout_height="wrap_content"
+                          android:gravity="center_horizontal|top"
+                          android:textAppearance="@style/TextAppearance.DeviceDefault.Body1"
+                          android:paddingStart="?dialogPreferredPadding"
+                          android:paddingEnd="?dialogPreferredPadding"
+                          android:paddingTop="8dip"
+                          android:paddingBottom="8dip"/>
+            </FrameLayout>
+
+            <!-- Custom Panel, to replace content panel if needed -->
+            <FrameLayout android:id="@+id/customPanel"
+                         android:layout_width="match_parent"
+                         android:layout_height="match_parent"
+                         android:minHeight="64dp">
+                <FrameLayout android:id="@+android:id/custom"
+                             android:layout_width="match_parent"
+                             android:layout_height="wrap_content" />
+            </FrameLayout>
+
+            <!-- Button Panel -->
+            <FrameLayout
+                android:id="@+id/buttonPanel"
+                android:minHeight="@dimen/dialog_list_padding_bottom_no_buttons"
+                android:layout_weight="1"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center">
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="bottom"
+                    android:orientation="horizontal"
+                    android:paddingBottom="?dialogPreferredPadding"
+                    style="?android:attr/buttonBarStyle"
+                    android:measureWithLargestChild="true">
+                    <Button android:id="@+id/button2"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_gravity="center"
+                            android:gravity="center"
+                            android:layout_weight="1"
+                            style="@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Negative" />
+                    <Button android:id="@+id/button3"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_gravity="center"
+                            android:gravity="center"
+                            android:layout_weight="1"
+                            style="?android:attr/buttonBarButtonStyle"/>
+                    <FrameLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content">
+                        <Button android:id="@+id/button1"
+                                android:layout_width="match_parent"
+                                android:layout_height="match_parent"
+                                android:layout_gravity="center"
+                                android:gravity="center"
+                                android:layout_weight="1"
+                                style="@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Confirm" />
+                        <!-- This works as background. -->
+                        <ImageView
+                            android:layout_width="match_parent"
+                            android:layout_height="match_parent"
+                            android:src="@drawable/dialog_alert_button_positive"/>
+                    </FrameLayout>
+                </LinearLayout>
+            </FrameLayout>
+        </LinearLayout>
+    </ScrollView>
+</com.android.internal.widget.WatchListDecorLayout>
diff --git a/core/res/res/layout-watch-v36/alert_dialog_material.xml b/core/res/res/layout-watch-v36/alert_dialog_material.xml
index 900102f..8f75456 100644
--- a/core/res/res/layout-watch-v36/alert_dialog_material.xml
+++ b/core/res/res/layout-watch-v36/alert_dialog_material.xml
@@ -82,9 +82,8 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_gravity="bottom"
-                    android:orientation="horizontal"
+                    android:orientation="vertical"
                     android:paddingBottom="?dialogPreferredPadding"
-                    style="?android:attr/buttonBarStyle"
                     android:measureWithLargestChild="true">
                     <Button android:id="@+id/button2"
                             android:layout_width="wrap_content"
@@ -92,7 +91,7 @@
                             android:layout_gravity="center"
                             android:gravity="center"
                             android:layout_weight="1"
-                            style="@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog.Negative" />
+                            style="@*android:style/Widget.DeviceDefault.Button.WearMaterial3"/>
                     <Button android:id="@+id/button3"
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
@@ -100,22 +99,13 @@
                             android:gravity="center"
                             android:layout_weight="1"
                             style="?android:attr/buttonBarButtonStyle"/>
-                    <FrameLayout
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content">
-                        <Button android:id="@+id/button1"
-                                android:layout_width="match_parent"
-                                android:layout_height="match_parent"
-                                android:layout_gravity="center"
-                                android:gravity="center"
-                                android:layout_weight="1"
-                                style="@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog.Confirm"/>
-                        <!-- This works as background. -->
-                        <ImageView
+                    <Button android:id="@+id/button1"
                             android:layout_width="match_parent"
                             android:layout_height="match_parent"
-                            android:src="@drawable/dialog_alert_button_positive"/>
-                    </FrameLayout>
+                            android:layout_gravity="center"
+                            android:gravity="center"
+                            android:layout_weight="1"
+                            style="@*android:style/Widget.DeviceDefault.Button.Filled"/>
                 </LinearLayout>
             </FrameLayout>
         </LinearLayout>
diff --git a/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml b/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml
new file mode 100644
index 0000000..b25adaa
--- /dev/null
+++ b/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml
@@ -0,0 +1,54 @@
+<?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 underthe License
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/conversation_face_pile"
+    android:layout_width="@dimen/conversation_avatar_size"
+    android:layout_height="@dimen/conversation_avatar_size"
+    android:forceHasOverlappingRendering="false"
+    >
+    <ImageView
+        android:id="@+id/conversation_face_pile_top"
+        android:layout_width="@dimen/messaging_avatar_size"
+        android:layout_height="@dimen/messaging_avatar_size"
+        android:scaleType="centerCrop"
+        android:layout_gravity="end|top"
+        android:background="@drawable/notification_icon_circle"
+        android:clipToOutline="true"
+        />
+    <FrameLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="start|bottom">
+        <ImageView
+            android:id="@+id/conversation_face_pile_bottom_background"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/conversation_badge_background"
+            />
+        <ImageView
+            android:id="@+id/conversation_face_pile_bottom"
+            android:layout_width="@dimen/messaging_avatar_size"
+            android:layout_height="@dimen/messaging_avatar_size"
+            android:scaleType="centerCrop"
+            android:layout_gravity="center"
+            android:background="@drawable/notification_icon_circle"
+            android:clipToOutline="true"
+            />
+    </FrameLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_2025_conversation_icon_container.xml b/core/res/res/layout/notification_2025_conversation_icon_container.xml
new file mode 100644
index 0000000..90befd9
--- /dev/null
+++ b/core/res/res/layout/notification_2025_conversation_icon_container.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/conversation_icon_container"
+    android:layout_width="@dimen/conversation_content_start"
+    android:layout_height="wrap_content"
+    android:gravity="start|top"
+    android:clipChildren="false"
+    android:clipToPadding="false"
+    android:paddingTop="20dp"
+    android:paddingBottom="16dp"
+    android:importantForAccessibility="no"
+    >
+
+    <FrameLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:layout_gravity="top|center_horizontal"
+        >
+
+        <!-- Big icon: 48x48, 12dp padding top, 16dp padding sides -->
+        <com.android.internal.widget.CachingIconView
+            android:id="@+id/conversation_icon"
+            android:layout_width="@dimen/conversation_avatar_size"
+            android:layout_height="@dimen/conversation_avatar_size"
+            android:layout_marginLeft="@dimen/conversation_badge_protrusion"
+            android:layout_marginRight="@dimen/conversation_badge_protrusion"
+            android:layout_marginBottom="@dimen/conversation_badge_protrusion"
+            android:background="@drawable/notification_icon_circle"
+            android:clipToOutline="true"
+            android:scaleType="centerCrop"
+            android:importantForAccessibility="no"
+            />
+
+        <ViewStub
+            android:layout="@layout/notification_2025_conversation_face_pile_layout"
+            android:layout_width="@dimen/conversation_avatar_size"
+            android:layout_height="@dimen/conversation_avatar_size"
+            android:layout_marginLeft="@dimen/conversation_badge_protrusion"
+            android:layout_marginRight="@dimen/conversation_badge_protrusion"
+            android:layout_marginBottom="@dimen/conversation_badge_protrusion"
+            android:id="@+id/conversation_face_pile"
+            />
+
+        <FrameLayout
+            android:id="@+id/conversation_icon_badge"
+            android:layout_width="@dimen/conversation_icon_size_badged"
+            android:layout_height="@dimen/conversation_icon_size_badged"
+            android:layout_gravity="end|bottom"
+            android:clipChildren="false"
+            android:clipToPadding="false"
+            >
+
+            <com.android.internal.widget.CachingIconView
+                android:id="@+id/conversation_icon_badge_bg"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_gravity="center"
+                android:src="@drawable/conversation_badge_background"
+                android:forceHasOverlappingRendering="false"
+                android:scaleType="center"
+                />
+
+            <com.android.internal.widget.NotificationRowIconView
+                android:id="@+id/icon"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_margin="4dp"
+                android:layout_gravity="center"
+                android:forceHasOverlappingRendering="false"
+                />
+
+            <com.android.internal.widget.CachingIconView
+                android:id="@+id/conversation_icon_badge_ring"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:src="@drawable/conversation_badge_ring"
+                android:visibility="gone"
+                android:forceHasOverlappingRendering="false"
+                android:clipToPadding="false"
+                android:scaleType="center"
+                />
+        </FrameLayout>
+    </FrameLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_2025_messaging_group.xml b/core/res/res/layout/notification_2025_messaging_group.xml
new file mode 100644
index 0000000..c1b491f
--- /dev/null
+++ b/core/res/res/layout/notification_2025_messaging_group.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<!-- extends LinearLayout -->
+<com.android.internal.widget.MessagingGroup
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal" >
+    <FrameLayout
+        android:id="@+id/message_icon_container"
+        android:layout_width="@dimen/conversation_content_start"
+        android:layout_height="wrap_content">
+        <ImageView
+            android:layout_gravity="top|center_horizontal"
+            android:id="@+id/message_icon"
+            android:layout_width="@dimen/messaging_avatar_size"
+            android:layout_height="@dimen/messaging_avatar_size"
+            android:background="@drawable/notification_icon_circle"
+            android:clipToOutline="true"
+            android:scaleType="centerCrop"
+            android:importantForAccessibility="no" />
+    </FrameLayout>
+    <com.android.internal.widget.RemeasuringLinearLayout
+        android:id="@+id/messaging_group_content_container"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:baselineAligned="true"
+        android:orientation="vertical">
+        <com.android.internal.widget.ImageFloatingTextView
+            android:id="@+id/message_name"
+            style="@style/Widget.DeviceDefault.Notification.MessagingName"
+            android:layout_width="wrap_content"
+            android:textAlignment="viewStart"
+        />
+        <com.android.internal.widget.MessagingLinearLayout
+            android:id="@+id/group_message_container"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/notification_text_margin_top"
+            android:spacing="2dp" />
+    </com.android.internal.widget.RemeasuringLinearLayout>
+    <FrameLayout
+        android:id="@+id/messaging_group_icon_container"
+        android:layout_width="@dimen/messaging_avatar_size"
+        android:layout_height="@dimen/messaging_avatar_size"
+        android:layout_marginStart="12dp"
+        android:visibility="gone"/>
+    <FrameLayout
+        android:id="@+id/messaging_group_sending_progress_container"
+        android:layout_width="@dimen/messaging_group_sending_progress_size"
+        android:layout_height="@dimen/messaging_avatar_size"
+        android:layout_marginStart="12dp"
+        android:layout_gravity="top"
+        android:visibility="gone">
+        <ProgressBar
+            android:id="@+id/messaging_group_sending_progress"
+            android:layout_height="@dimen/messaging_group_sending_progress_size"
+            android:layout_width="@dimen/messaging_group_sending_progress_size"
+            android:layout_gravity="center"
+            android:indeterminate="true"
+            style="?android:attr/progressBarStyleSmall" />
+    </FrameLayout>
+</com.android.internal.widget.MessagingGroup>
diff --git a/core/res/res/layout/notification_2025_reply_container.xml b/core/res/res/layout/notification_2025_reply_container.xml
new file mode 100644
index 0000000..6923b59
--- /dev/null
+++ b/core/res/res/layout/notification_2025_reply_container.xml
@@ -0,0 +1,79 @@
+<?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
+  -->
+
+<!-- Note: this layout is included from a view stub; layout attributes will be overridden. -->
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/notification_material_reply_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:paddingStart="@dimen/notification_2025_content_margin_start">
+
+    <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:id="@+id/action_divider"
+            android:layout_marginTop="@dimen/notification_content_margin"
+            android:layout_marginBottom="@dimen/notification_content_margin"
+            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:background="@drawable/notification_template_divider" />
+
+    <TextView
+            android:id="@+id/notification_material_reply_text_3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:visibility="gone"
+            android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
+            android:singleLine="true" />
+
+    <TextView
+            android:id="@+id/notification_material_reply_text_2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:visibility="gone"
+            android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
+            android:singleLine="true" />
+
+    <LinearLayout
+            android:id="@+id/notification_material_reply_text_1_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:layout_marginEnd="@dimen/notification_content_margin_end">
+        <TextView
+                android:id="@+id/notification_material_reply_text_1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_marginEnd="@dimen/notification_content_margin_end"
+                android:layout_gravity="center"
+                android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
+                android:singleLine="true" />
+        <ProgressBar
+            android:id="@+id/notification_material_reply_progress"
+            android:layout_height="@dimen/messaging_group_sending_progress_size"
+            android:layout_width="@dimen/messaging_group_sending_progress_size"
+            android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+            android:layout_gravity="center"
+            android:indeterminate="true"
+            style="?android:attr/progressBarStyleSmall" />
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_base.xml b/core/res/res/layout/notification_2025_template_collapsed_base.xml
index c003820..a790e5d 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_base.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_base.xml
@@ -123,7 +123,7 @@
                     <!-- This is the simplest way to keep this text vertically centered without
                      gravity="center_vertical" which causes jumpiness in expansion animations. -->
                     <include
-                        layout="@layout/notification_template_text"
+                        layout="@layout/notification_2025_text"
                         android:layout_width="match_parent"
                         android:layout_height="@dimen/notification_text_height"
                         android:layout_gravity="center_vertical"
diff --git a/core/res/res/layout/notification_2025_template_collapsed_call.xml b/core/res/res/layout/notification_2025_template_collapsed_call.xml
new file mode 100644
index 0000000..06f5f06
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_collapsed_call.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<!-- Extends FrameLayout -->
+<com.android.internal.widget.CallLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:clipChildren="false"
+    android:tag="call"
+    android:theme="@style/Theme.DeviceDefault.Notification"
+    >
+
+    <!-- CallLayout shares visual appearance with ConversationLayout, so shares layouts -->
+    <include layout="@layout/notification_2025_conversation_icon_container" />
+
+    <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="88dp"
+        android:orientation="horizontal"
+        >
+
+        <LinearLayout
+            android:id="@+id/notification_main_column"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_marginStart="@dimen/conversation_content_start"
+            android:orientation="vertical"
+            android:minHeight="68dp"
+            android:paddingBottom="@dimen/notification_headerless_margin_twoline"
+            >
+
+            <include
+                layout="@layout/notification_template_conversation_header"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                />
+
+            <include layout="@layout/notification_template_text"
+                android:layout_height="wrap_content"
+                android:minHeight="@dimen/notification_text_height"
+                />
+
+        </LinearLayout>
+
+        <FrameLayout
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:minWidth="@dimen/notification_content_margin_end"
+            >
+
+            <include
+                layout="@layout/notification_expand_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                />
+
+        </FrameLayout>
+
+    </LinearLayout>
+
+</com.android.internal.widget.CallLayout>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_media.xml b/core/res/res/layout/notification_2025_template_collapsed_media.xml
new file mode 100644
index 0000000..427c4e4
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_collapsed_media.xml
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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
+  -->
+
+<!-- Note: This is the old media style notification (different from UMO). -->
+
+<!-- extends FrameLayout -->
+<com.android.internal.widget.MediaNotificationView
+    android:id="@+id/status_bar_latest_event_content"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="@dimen/notification_min_height"
+    android:tag="media"
+    >
+
+
+    <ImageView
+        android:id="@+id/left_icon"
+        android:layout_width="@dimen/notification_2025_left_icon_size"
+        android:layout_height="@dimen/notification_2025_left_icon_size"
+        android:layout_gravity="center_vertical|start"
+        android:layout_marginStart="@dimen/notification_left_icon_start"
+        android:background="@drawable/notification_large_icon_outline"
+        android:clipToOutline="true"
+        android:importantForAccessibility="no"
+        android:scaleType="centerCrop"
+        android:visibility="gone"
+        />
+
+    <com.android.internal.widget.NotificationRowIconView
+        android:id="@+id/icon"
+        android:layout_width="@dimen/notification_2025_icon_circle_size"
+        android:layout_height="@dimen/notification_2025_icon_circle_size"
+        android:layout_gravity="center_vertical|start"
+        android:layout_marginStart="@dimen/notification_icon_circle_start"
+        android:background="@drawable/notification_icon_circle"
+        android:padding="@dimen/notification_2025_icon_circle_padding"
+        />
+
+    <FrameLayout
+        android:id="@+id/alternate_expand_target"
+        android:layout_width="@dimen/notification_2025_content_margin_start"
+        android:layout_height="match_parent"
+        android:layout_gravity="start"
+        android:importantForAccessibility="no"
+        android:focusable="false"
+        />
+
+    <LinearLayout
+        android:id="@+id/notification_headerless_view_row"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+        android:orientation="horizontal"
+        >
+
+        <LinearLayout
+            android:id="@+id/notification_headerless_view_column"
+            android:layout_width="0px"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_weight="1"
+            android:layout_marginBottom="@dimen/notification_headerless_margin_twoline"
+            android:layout_marginTop="@dimen/notification_headerless_margin_twoline"
+            android:orientation="vertical"
+            >
+
+            <NotificationTopLineView
+                android:id="@+id/notification_top_line"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:minHeight="@dimen/notification_headerless_line_height"
+                android:clipChildren="false"
+                android:theme="@style/Theme.DeviceDefault.Notification"
+                >
+
+                <!--
+                NOTE: The notification_top_line_views layout contains the app_name_text.
+                In order to include the title view at the beginning, the Notification.Builder
+                has logic to hide that view whenever this title view is to be visible.
+                -->
+
+                <TextView
+                    android:id="@+id/title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginEnd="@dimen/notification_header_separating_margin"
+                    android:ellipsize="end"
+                    android:fadingEdge="horizontal"
+                    android:singleLine="true"
+                    android:textAlignment="viewStart"
+                    android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
+                    />
+
+                <include layout="@layout/notification_top_line_views" />
+
+            </NotificationTopLineView>
+
+            <LinearLayout
+                android:id="@+id/notification_main_column"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                >
+
+                <com.android.internal.widget.NotificationVanishingFrameLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/notification_headerless_line_height"
+                    >
+                    <!-- This is the simplest way to keep this text vertically centered without
+                     gravity="center_vertical" which causes jumpiness in expansion animations. -->
+                    <include
+                        layout="@layout/notification_template_text"
+                        android:layout_width="match_parent"
+                        android:layout_height="@dimen/notification_text_height"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginTop="0dp"
+                        />
+                </com.android.internal.widget.NotificationVanishingFrameLayout>
+
+                <include
+                    layout="@layout/notification_template_progress"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/notification_headerless_line_height"
+                    />
+
+            </LinearLayout>
+
+        </LinearLayout>
+
+        <ImageView
+            android:id="@+id/right_icon"
+            android:layout_width="@dimen/notification_right_icon_size"
+            android:layout_height="@dimen/notification_right_icon_size"
+            android:layout_gravity="center_vertical|end"
+            android:layout_marginTop="@dimen/notification_right_icon_headerless_margin"
+            android:layout_marginBottom="@dimen/notification_right_icon_headerless_margin"
+            android:layout_marginStart="@dimen/notification_right_icon_content_margin"
+            android:background="@drawable/notification_large_icon_outline"
+            android:clipToOutline="true"
+            android:importantForAccessibility="no"
+            android:scaleType="centerCrop"
+            />
+
+        <LinearLayout
+            android:id="@+id/media_actions"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layoutDirection="ltr"
+            android:orientation="horizontal"
+            >
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action0"
+                />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action1"
+                />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action2"
+                />
+        </LinearLayout>
+
+        <FrameLayout
+            android:id="@+id/expand_button_touch_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:minWidth="@dimen/notification_content_margin_end"
+            >
+
+            <include layout="@layout/notification_expand_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical|end"
+                />
+
+        </FrameLayout>
+
+    </LinearLayout>
+</com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
new file mode 100644
index 0000000..f0e4c0f
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<!-- Note: This is the old "Messaging Style" notification (not a conversation). -->
+
+<!-- extends FrameLayout -->
+<com.android.internal.widget.MessagingLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:clipChildren="false"
+    android:tag="messaging"
+    >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:clipChildren="false"
+        android:orientation="vertical"
+        >
+
+
+        <com.android.internal.widget.NotificationMaxHeightFrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:minHeight="@dimen/notification_min_height"
+            android:clipChildren="false"
+            >
+
+            <ImageView
+                android:id="@+id/left_icon"
+                android:layout_width="@dimen/notification_2025_left_icon_size"
+                android:layout_height="@dimen/notification_2025_left_icon_size"
+                android:layout_gravity="center_vertical|start"
+                android:layout_marginStart="@dimen/notification_left_icon_start"
+                android:background="@drawable/notification_large_icon_outline"
+                android:clipToOutline="true"
+                android:importantForAccessibility="no"
+                android:scaleType="centerCrop"
+                android:visibility="gone"
+                />
+
+            <com.android.internal.widget.NotificationRowIconView
+                android:id="@+id/icon"
+                android:layout_width="@dimen/notification_2025_icon_circle_size"
+                android:layout_height="@dimen/notification_2025_icon_circle_size"
+                android:layout_gravity="center_vertical|start"
+                android:layout_marginStart="@dimen/notification_icon_circle_start"
+                android:background="@drawable/notification_icon_circle"
+                android:padding="@dimen/notification_2025_icon_circle_padding"
+                />
+
+            <FrameLayout
+                android:id="@+id/alternate_expand_target"
+                android:layout_width="@dimen/notification_2025_content_margin_start"
+                android:layout_height="match_parent"
+                android:layout_gravity="start"
+                android:importantForAccessibility="no"
+                android:focusable="false"
+                />
+
+            <!--
+              NOTE: to make the expansion animation of id/notification_messaging happen vertically,
+              its X positioning must be the left edge of the notification, so instead of putting the
+              layout_marginStart on the id/notification_headerless_view_row, we put it on
+              id/notification_top_line, making the layout here just a bit different from the base.
+              -->
+            <LinearLayout
+                android:id="@+id/notification_headerless_view_row"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:orientation="horizontal"
+                android:clipChildren="false"
+                >
+
+                <!--
+                  NOTE: because messaging will always have 2 lines, this LinearLayout should NOT
+                  have the id/notification_headerless_view_column, as that is used for modifying
+                   vertical margins to accommodate the single-line state that base supports
+                  -->
+                <LinearLayout
+                    android:layout_width="0px"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    android:layout_weight="1"
+                    android:layout_marginBottom="@dimen/notification_headerless_margin_twoline"
+                    android:layout_marginTop="@dimen/notification_headerless_margin_twoline"
+                    android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+                    android:clipChildren="false"
+                    android:orientation="vertical"
+                    >
+
+                    <NotificationTopLineView
+                        android:id="@+id/notification_top_line"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:minHeight="@dimen/notification_headerless_line_height"
+                        android:clipChildren="false"
+                        android:theme="@style/Theme.DeviceDefault.Notification"
+                        >
+
+                        <!--
+                        NOTE: The notification_top_line_views layout contains the app_name_text.
+                        In order to include the title view at the beginning, the Notification.Builder
+                        has logic to hide that view whenever this title view is to be visible.
+                        -->
+
+                        <TextView
+                            android:id="@+id/title"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginEnd="@dimen/notification_header_separating_margin"
+                            android:ellipsize="end"
+                            android:fadingEdge="horizontal"
+                            android:singleLine="true"
+                            android:textAlignment="viewStart"
+                            android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
+                            />
+
+                        <include layout="@layout/notification_top_line_views" />
+
+                    </NotificationTopLineView>
+
+                    <LinearLayout
+                        android:id="@+id/notification_main_column"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="vertical"
+                        android:clipChildren="false"
+                        >
+                        <com.android.internal.widget.MessagingLinearLayout
+                            android:id="@+id/notification_messaging"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:clipChildren="false"
+                            android:spacing="@dimen/notification_messaging_spacing" />
+                    </LinearLayout>
+
+                </LinearLayout>
+
+                <!-- Images -->
+                <com.android.internal.widget.MessagingLinearLayout
+                    android:id="@+id/conversation_image_message_container"
+                    android:layout_width="@dimen/notification_right_icon_size"
+                    android:layout_height="@dimen/notification_right_icon_size"
+                    android:layout_gravity="center_vertical|end"
+                    android:layout_marginTop="@dimen/notification_right_icon_headerless_margin"
+                    android:layout_marginBottom="@dimen/notification_right_icon_headerless_margin"
+                    android:layout_marginStart="@dimen/notification_right_icon_content_margin"
+                    android:forceHasOverlappingRendering="false"
+                    android:spacing="0dp"
+                    android:clipChildren="false"
+                    android:visibility="gone"
+                    />
+
+                <ImageView
+                    android:id="@+id/right_icon"
+                    android:layout_width="@dimen/notification_right_icon_size"
+                    android:layout_height="@dimen/notification_right_icon_size"
+                    android:layout_gravity="center_vertical|end"
+                    android:layout_marginTop="@dimen/notification_right_icon_headerless_margin"
+                    android:layout_marginBottom="@dimen/notification_right_icon_headerless_margin"
+                    android:layout_marginStart="@dimen/notification_right_icon_content_margin"
+                    android:background="@drawable/notification_large_icon_outline"
+                    android:clipToOutline="true"
+                    android:importantForAccessibility="no"
+                    android:scaleType="centerCrop"
+                    />
+
+                <FrameLayout
+                    android:id="@+id/expand_button_touch_container"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:minWidth="@dimen/notification_content_margin_end"
+                    >
+
+                    <include layout="@layout/notification_expand_button"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center_vertical|end"
+                        />
+
+                </FrameLayout>
+
+            </LinearLayout>
+
+        </com.android.internal.widget.NotificationMaxHeightFrameLayout>
+
+    <LinearLayout
+            android:id="@+id/notification_action_list_margin_target"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="-20dp"
+            android:clipChildren="false"
+            android:orientation="vertical">
+        <include layout="@layout/notification_template_smart_reply_container"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/notification_content_margin"
+                android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+                android:layout_marginEnd="@dimen/notification_content_margin_end" />
+        <include layout="@layout/notification_material_action_list" />
+    </LinearLayout>
+</LinearLayout>
+</com.android.internal.widget.MessagingLayout>
diff --git a/core/res/res/layout/notification_2025_template_conversation.xml b/core/res/res/layout/notification_2025_template_conversation.xml
new file mode 100644
index 0000000..0c4c7fb
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_conversation.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<!-- extends FrameLayout -->
+<com.android.internal.widget.ConversationLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:clipChildren="false"
+    android:tag="conversation"
+    android:theme="@style/Theme.DeviceDefault.Notification"
+    >
+
+    <include layout="@layout/notification_2025_conversation_icon_container" />
+
+    <!-- Wraps entire "expandable" notification -->
+    <com.android.internal.widget.RemeasuringLinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top"
+        android:clipToPadding="false"
+        android:clipChildren="false"
+        android:orientation="vertical"
+        >
+        <!-- LinearLayout for Expand Button-->
+        <com.android.internal.widget.RemeasuringLinearLayout
+            android:id="@+id/expand_button_and_content_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="start|top"
+            android:orientation="horizontal"
+            android:clipChildren="false"
+            android:clipToPadding="false">
+            <!--TODO: move this into a separate layout and share logic with the header to bring back app opps etc-->
+            <com.android.internal.widget.RemeasuringLinearLayout
+                android:id="@+id/notification_action_list_margin_target"
+                android:layout_width="0dp"
+                android:orientation="vertical"
+                android:layout_height="wrap_content"
+                android:layout_weight="1">
+
+                <!-- Header -->
+
+                <!-- Use layout_marginStart instead of paddingStart to work around strange
+                     measurement behavior on lower display densities. -->
+                <include
+                    layout="@layout/notification_template_conversation_header"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="2dp"
+                    android:layout_marginStart="@dimen/conversation_content_start"
+                    />
+
+                <!-- Messages -->
+                <com.android.internal.widget.MessagingLinearLayout
+                    android:id="@+id/notification_messaging"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:minHeight="@dimen/notification_text_size"
+                    android:spacing="@dimen/notification_messaging_spacing"
+                    android:clipToPadding="false"
+                    android:clipChildren="false"
+                    />
+            </com.android.internal.widget.RemeasuringLinearLayout>
+
+            <!-- This is where the expand button container will be placed when collapsed-->
+        </com.android.internal.widget.RemeasuringLinearLayout>
+
+        <include layout="@layout/notification_template_smart_reply_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/notification_content_margin"
+            android:layout_marginStart="@dimen/conversation_content_start"
+            android:layout_marginEnd="@dimen/notification_content_margin_end" />
+        <include layout="@layout/notification_material_action_list" />
+    </com.android.internal.widget.RemeasuringLinearLayout>
+
+    <!--expand_button_a11y_container ensures talkback focus order is correct when view is expanded.
+    The -1px of marginTop and 1px of paddingTop make sure expand_button_a11y_container is prior to
+    its sibling view in accessibility focus order.
+    {see android.view.ViewGroup.addChildrenForAccessibility()}
+    expand_button_container will be moved under expand_button_and_content_container when collapsed,
+    this dynamic movement ensures message can flow under expand button when expanded-->
+    <FrameLayout
+        android:id="@+id/expand_button_a11y_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="end|top"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:layout_marginTop="-1px"
+        android:paddingTop="1px"
+        >
+        <!--expand_button_container is dynamically placed between here and at the end of the
+        layout. It starts here since only FrameLayout layout params have gravity-->
+        <LinearLayout
+            android:id="@+id/expand_button_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_gravity="end|top"
+            android:clipChildren="false"
+            android:clipToPadding="false"
+            android:orientation="vertical">
+            <include layout="@layout/notification_close_button"
+                android:layout_width="@dimen/notification_close_button_size"
+                android:layout_height="@dimen/notification_close_button_size"
+                android:layout_gravity="end"
+                android:layout_marginEnd="20dp"
+                />
+            <!--expand_button_touch_container makes sure that we can nicely center the expand
+            content in the collapsed layout while the parent makes sure that we're never laid out
+            bigger than the messaging content.-->
+            <LinearLayout
+                android:id="@+id/expand_button_touch_container"
+                android:layout_width="wrap_content"
+                android:layout_height="@dimen/conversation_expand_button_height"
+                android:orientation="horizontal"
+                android:layout_gravity="end|top"
+                android:paddingEnd="0dp"
+                android:clipToPadding="false"
+                android:clipChildren="false"
+                >
+                <!-- Images -->
+                <com.android.internal.widget.MessagingLinearLayout
+                    android:id="@+id/conversation_image_message_container"
+                    android:forceHasOverlappingRendering="false"
+                    android:layout_width="40dp"
+                    android:layout_height="40dp"
+                    android:layout_marginStart="@dimen/conversation_image_start_margin"
+                    android:spacing="0dp"
+                    android:layout_gravity="center"
+                    android:clipToPadding="false"
+                    android:clipChildren="false"
+                    />
+                <include layout="@layout/notification_expand_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    />
+            </LinearLayout>
+        </LinearLayout>
+    </FrameLayout>
+</com.android.internal.widget.ConversationLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_base.xml b/core/res/res/layout/notification_2025_template_expanded_base.xml
new file mode 100644
index 0000000..e480fe5
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_base.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:clipChildren="false"
+    android:tag="big"
+    >
+
+    <LinearLayout
+        android:id="@+id/notification_action_list_margin_target"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/notification_content_margin"
+        android:orientation="vertical"
+        >
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_gravity="top"
+            >
+
+            <include layout="@layout/notification_2025_template_header" />
+
+            <LinearLayout
+                android:id="@+id/notification_main_column"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+                android:layout_marginEnd="@dimen/notification_content_margin_end"
+                android:layout_marginTop="@dimen/notification_content_margin_top"
+                android:orientation="vertical"
+                >
+
+                <include layout="@layout/notification_template_part_line1" />
+
+                <include layout="@layout/notification_template_text_multiline" />
+
+                <include
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/notification_progress_bar_height"
+                    android:layout_marginTop="@dimen/notification_progress_margin_top"
+                    layout="@layout/notification_template_progress"
+                    />
+            </LinearLayout>
+
+            <include layout="@layout/notification_template_right_icon" />
+        </FrameLayout>
+
+        <ViewStub
+            android:layout="@layout/notification_2025_reply_container"
+            android:id="@+id/notification_material_reply_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            />
+
+        <include
+            layout="@layout/notification_template_smart_reply_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginTop="@dimen/notification_content_margin"
+            />
+
+        <include layout="@layout/notification_material_action_list" />
+    </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_call.xml b/core/res/res/layout/notification_2025_template_expanded_call.xml
new file mode 100644
index 0000000..3ff71b7
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_call.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<!-- Extends FrameLayout -->
+<com.android.internal.widget.CallLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:clipChildren="false"
+    android:tag="call"
+    android:theme="@style/Theme.DeviceDefault.Notification"
+    >
+
+    <!-- CallLayout shares visual appearance with ConversationLayout, so shares layouts -->
+    <include layout="@layout/notification_2025_conversation_icon_container" />
+
+    <LinearLayout
+        android:id="@+id/notification_action_list_margin_target"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/notification_content_margin"
+        android:orientation="vertical"
+        >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:orientation="horizontal"
+            >
+
+            <LinearLayout
+                android:id="@+id/notification_main_column"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_marginStart="@dimen/conversation_content_start"
+                android:orientation="vertical"
+                android:minHeight="68dp"
+                >
+
+                <include
+                    layout="@layout/notification_template_conversation_header"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    />
+
+                <include layout="@layout/notification_template_text_multiline" />
+
+                <include
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/notification_progress_bar_height"
+                    android:layout_marginTop="@dimen/notification_progress_margin_top"
+                    layout="@layout/notification_template_progress"
+                    />
+            </LinearLayout>
+
+            <FrameLayout
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:minWidth="@dimen/notification_content_margin_end"
+                >
+
+                <include
+                    layout="@layout/notification_expand_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    />
+
+            </FrameLayout>
+
+        </LinearLayout>
+
+        <ViewStub
+            android:layout="@layout/notification_material_reply_text"
+            android:id="@+id/notification_material_reply_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            />
+
+        <include
+            layout="@layout/notification_template_smart_reply_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/notification_content_margin_start"
+            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginTop="@dimen/notification_content_margin"
+            />
+
+        <include layout="@layout/notification_material_action_list" />
+
+    </LinearLayout>
+
+</com.android.internal.widget.CallLayout>
diff --git a/core/res/res/layout/notification_2025_text.xml b/core/res/res/layout/notification_2025_text.xml
new file mode 100644
index 0000000..48b1083
--- /dev/null
+++ b/core/res/res/layout/notification_2025_text.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<com.android.internal.widget.ImageFloatingTextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/Widget.DeviceDefault.Notification.Text"
+    android:id="@+id/text"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/notification_text_height"
+    android:layout_gravity="top"
+    android:layout_marginTop="@dimen/notification_text_margin_top"
+    android:fadingEdge="horizontal"
+    android:gravity="top"
+    android:maxLines="1"
+    android:textAlignment="viewStart"
+    />
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 565d584..5795936 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -13,7 +13,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<!-- extends FrameLayout -->
+<!-- extends RelativeLayout -->
 <NotificationHeaderView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/notification_header"
@@ -62,7 +62,7 @@
         android:layout_height="match_parent"
         android:layout_alignParentStart="true"
         android:layout_centerVertical="true"
-        android:layout_toStartOf="@id/notification_buttons_column"
+        android:layout_toStartOf="@id/expand_button"
         android:layout_alignWithParentIfMissing="true"
         android:clipChildren="false"
         android:gravity="center_vertical"
@@ -83,28 +83,17 @@
         android:focusable="false"
         />
 
-    <LinearLayout
-        android:id="@+id/notification_buttons_column"
+    <include layout="@layout/notification_expand_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:orientation="vertical"
-        >
+        android:layout_centerVertical="true"
+        android:layout_alignParentEnd="true" />
 
-        <include layout="@layout/notification_close_button"
-            android:layout_width="@dimen/notification_close_button_size"
-            android:layout_height="@dimen/notification_close_button_size"
-            android:layout_gravity="end"
-            android:layout_marginEnd="20dp"
-            />
-
-        <include layout="@layout/notification_expand_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_centerVertical="true"
-            />
-
-    </LinearLayout>
+    <include layout="@layout/notification_close_button"
+        android:id="@+id/close_button"
+        android:layout_width="@dimen/notification_close_button_size"
+        android:layout_height="@dimen/notification_close_button_size"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentEnd="true" />
 
 </NotificationHeaderView>
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index 29f14a4..227f84b 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -157,39 +157,27 @@
             android:maxDrawableHeight="@dimen/notification_right_icon_size"
             />
 
-        <LinearLayout
-            android:id="@+id/notification_buttons_column"
+        <FrameLayout
+            android:id="@+id/expand_button_touch_container"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:layout_alignParentEnd="true"
-            android:orientation="vertical"
+            android:minWidth="@dimen/notification_content_margin_end"
             >
 
-            <include layout="@layout/notification_close_button"
-                android:layout_width="@dimen/notification_close_button_size"
-                android:layout_height="@dimen/notification_close_button_size"
-                android:layout_gravity="end"
-                android:layout_marginEnd="20dp"
+            <include layout="@layout/notification_expand_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical|end"
                 />
 
-            <FrameLayout
-                android:id="@+id/expand_button_touch_container"
-                android:layout_width="wrap_content"
-                android:layout_height="0dp"
-                android:layout_weight="1"
-                android:minWidth="@dimen/notification_content_margin_end"
-                >
-
-                <include layout="@layout/notification_expand_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center_vertical|end"
-                    />
-
-            </FrameLayout>
-
-        </LinearLayout>
+        </FrameLayout>
 
     </LinearLayout>
 
+    <include layout="@layout/notification_close_button"
+        android:id="@+id/close_button"
+        android:layout_width="@dimen/notification_close_button_size"
+        android:layout_height="@dimen/notification_close_button_size"
+        android:layout_gravity="top|end" />
+
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 6e9d17f..5459fa8 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -15,6 +15,7 @@
   ~ limitations under the License
   -->
 
+<!-- extends FrameLayout -->
 <com.android.internal.widget.MediaNotificationView
     android:id="@+id/status_bar_latest_event_content"
     xmlns:android="http://schemas.android.com/apk/res/android"
@@ -191,4 +192,11 @@
         </FrameLayout>
 
     </LinearLayout>
+
+    <include layout="@layout/notification_close_button"
+        android:id="@+id/close_button"
+        android:layout_width="@dimen/notification_close_button_size"
+        android:layout_height="@dimen/notification_close_button_size"
+        android:layout_gravity="top|end" />
+
 </com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/notification_template_material_messaging.xml b/core/res/res/layout/notification_template_material_messaging.xml
index 1eae41d..2b3b7d8 100644
--- a/core/res/res/layout/notification_template_material_messaging.xml
+++ b/core/res/res/layout/notification_template_material_messaging.xml
@@ -195,6 +195,12 @@
 
             </LinearLayout>
 
+            <include layout="@layout/notification_close_button"
+                android:id="@+id/close_button"
+                android:layout_width="@dimen/notification_close_button_size"
+                android:layout_height="@dimen/notification_close_button_size"
+                android:layout_gravity="top|end" />
+
         </com.android.internal.widget.NotificationMaxHeightFrameLayout>
 
     <LinearLayout
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index bed80ed..7a2fb0b 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -20,6 +20,7 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
+    android:fitsSystemWindows="true"
     android:layout_height="match_parent"
     android:layout_width="match_parent">
 
diff --git a/core/res/res/layout/preference_list_content_material.xml b/core/res/res/layout/preference_list_content_material.xml
index 37b4119..23c8250 100644
--- a/core/res/res/layout/preference_list_content_material.xml
+++ b/core/res/res/layout/preference_list_content_material.xml
@@ -20,6 +20,7 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
+    android:fitsSystemWindows="true"
     android:layout_height="match_parent"
     android:layout_width="match_parent">
 
diff --git a/core/res/res/layout/preference_list_content_single.xml b/core/res/res/layout/preference_list_content_single.xml
index 726ce78..4f072da 100644
--- a/core/res/res/layout/preference_list_content_single.xml
+++ b/core/res/res/layout/preference_list_content_single.xml
@@ -19,6 +19,7 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
+    android:fitsSystemWindows="true"
     android:layout_height="match_parent"
     android:layout_width="match_parent">
 
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index c43975e..44a5df9 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -19,6 +19,7 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
+    android:fitsSystemWindows="true"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
     android:background="@android:color/transparent"
diff --git a/core/res/res/layout/preference_list_fragment_material.xml b/core/res/res/layout/preference_list_fragment_material.xml
index db2fe7d..4df7602 100644
--- a/core/res/res/layout/preference_list_fragment_material.xml
+++ b/core/res/res/layout/preference_list_fragment_material.xml
@@ -19,6 +19,7 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
+    android:fitsSystemWindows="true"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
     android:background="@android:color/transparent"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 9cfaca7..a4499ef 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Laat die program toe om relatiewe posisie tussen ultrabreëbandtoestelle in die omtrek te bepaal"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"om interaksie met wi‑fi-toestelle in die omtrek te hê"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Laat die program toe om op toestelle in die omtrek te adverteer, aan hulle te koppel en hul relatiewe posisie te bepaal"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"bepaal relatiewe posisie tussen toestelle in die omtrek"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Laat die app toe om relatiewe posisie tussen toestelle in die omtrek te bepaal"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Voorkeur-NFC-betalingdiensinligting"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Laat die program toe om voorkeur-NFC-betalingdiensinligting soos geregistreerde hulpmiddels en roetebestemming te kry."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"beheer kortveldkommunikasie"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Skakel aan"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Gaan terug"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Hangend …"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satelliet-SOS is nou beskikbaar"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Jy kan vir nooddienste ’n boodskap stuur as daar geen selfoon- of wi-fi-netwerk is nie. Google Boodskappe moet jou verstekboodskapapp wees."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satelliet-SOS word nie gesteun nie"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satelliet-SOS word nie op hierdie toestel gesteun nie"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satelliet-SOS is nie opgestel nie"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Maak seker jy is aan die internet gekoppel en probeer weer om op te stel"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satelliet-SOS is nie beskikbaar nie"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satelliet-SOS is nie in hierdie land of streek beskikbaar nie"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satelliet-SOS is nie opgestel nie"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Stel Google Boodskappe as jou verstekboodskapapp op om boodskappe per satelliet te stuur"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satelliet-SOS is nie beskikbaar nie"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Skakel ligginginstellings aan om te kyk of satelliet-SOS in hierdie land of streek beskikbaar is"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satellietboodskappe is beskikbaar"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Jy kan per satelliet ’n boodskap stuur as daar geen selfoon- of wi-fi-netwerk is nie. Google Boodskappe moet jou verstekboodskapapp wees."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satellietboodskappe word nie gesteun nie"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satellietboodskappe word nie op hierdie toestel gesteun nie"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satellietboodskappe is nie opgestel nie"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Maak seker jy is aan die internet gekoppel en probeer weer om op te stel"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satellietboodskappe is nie beskikbaar nie"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satellietboodskappe is nie in hierdie land of streek beskikbaar nie"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satellietboodskappe is nie opgestel nie"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Stel Google Boodskappe as jou verstekboodskapapp op om boodskappe per satelliet te stuur"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satellietboodskappe is nie beskikbaar nie"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Skakel ligginginstellings aan om te kyk of satellietboodskappe in hierdie land of streek beskikbaar is"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Stel Vingerafdrukslot weer op"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan nie meer herken word nie."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan nie meer herken word nie."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index c30a5c8..225f04d 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"በአቅራቢያ ባሉ ልዕለ-ሰፊ ባንድ መሣሪያዎች መካከል ያለውን አንጻራዊ አቀማመጣቸውን ለማወቅ ንዲችል ለመተግበሪያው ይፍቀዱ"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"በአቅራቢያ ካሉ የWi‑Fi መሣሪያዎች ጋር መስተጋብር መፍጠር"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"መተግበሪያው በአቅራቢያ ያሉ የWi-Fi መሣሪያዎች አንጻራዊ ቦታን እንዲያሳውቅ፣ እንዲያገናኝ እና እንዲያውቅ ያስችለዋል"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"በአቅራቢያ ባሉ መሣሪያዎች መካከል ያለውን አንጻራዊ አካባቢ ይወቁ"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"መተግበሪያው በአቅራቢያ ባሉ መሣሪያዎች መካከል ያለውን አንጻራዊ አካባቢ ለማወቅ እንዲችል ይፍቀዱለት"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ተመራጭ NFC የክፍያ አገልግሎት መረጃ"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"እንደ የተመዘገቡ እርዳታዎች እና የጉዞ መሥመር መዳረሻ የመሳሰለ ተመራጭ nfc የክፍያ አገልግሎት መረጃን ለማግኘት ለመተግበሪያው ያፈቅድለታል።"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ቅርብ የግኑኙነትመስክ (NFC) ተቆጣጠር"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"አብራ"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ወደኋላ ተመለስ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"በመጠባበቅ ላይ..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"ሳተላይት ኤስኦኤስ አሁን ይገኛል"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"ምንም የሞባይል ወይም Wi-Fi አውታረ መረብ ባይኖርም እንኳን ለድንገተኛ አደጋ አገልግሎቶች መልዕክት መላክ ይችላሉ። Google መልዕክቶች የእርስዎ ነባሪ የመልዕክት መላኪያ መተግበሪያ መሆን አለበት።"</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"ሳተላይት ኤስኦኤስ አይደገፍም"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"ሳተላይት ኤስኦኤስ በዚህ መሣሪያ ላይ አይደገፍም"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"ሳተላይት ኤስኦኤስ አልተዋቀረም"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"ከበይነመረቡ ጋር መገናኘትዎን ያረጋግጡ እና ውቅረትን እንደገና ይሞክሩ"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"ሳተላይት ኤስኦኤስ አይገኝም"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"ሳተላይት ኤስኦኤስ በዚህ አገር ወይም ክልል ውስጥ አይገኝም"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"ሳተላይት ኤስኦኤስ አልተዋቀረም"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"በሳተላይት መልዕክት ለመላክ Google መልዕክቶችን እንደ የእርስዎ ነባሪ የመልዕክት መላኪያ መተግበሪያ ያቀናብሩ"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"ሳተላይት ኤስኦኤስ አይገኝም"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"በዚህ አገር ወይም ክልል ውስጥ ሳተላይት ኤስኦኤስ እንደሚገኝ ለመፈተሽ የአካባቢ ቅንብሮችን ያብሩ"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"የሳተላይት መልዕክት ይገኛል"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"የሞባይል ወይም የWi-Fi አውታረ መረብ ከሌለ በሳተላይት መልዕክት መላክ ይችላሉ። Google መልዕክቶች የእርስዎ ነባሪ የመልዕክት መላኪያ መተግበሪያ መሆን አለበት።"</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"የሳተላይት መልዕክት አይደገፍም"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"የሳተላይት መልዕክት በዚህ መሣሪያ ላይ አይደገፍም"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"የሳተላይት መልዕክት አልተዋቀረም"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"ከበይነመረቡ ጋር መገናኘትዎን ያረጋግጡ እና ውቅረትን እንደገና ይሞክሩ"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"የሳተላይት መልዕክት አይገኝም"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"የሳተላይት መልዕክት በዚህ አገር ወይም ክልል ውስጥ አይገኝም"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"የሳተላይት መልዕክት አልተዋቀረም"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"በሳተላይት መልዕክት ለመላክ Google መልዕክቶችን እንደ የእርስዎ ነባሪ የመልዕክት መላኪያ መተግበሪያ ያቀናብሩ"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"የሳተላይት መልዕክት አይገኝም"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"በዚህ አገር ወይም ክልል ውስጥ የሳተላይት መልዕክት እንደሚገኝ ለመፈተሽ የአካባቢ ቅንብሮችን ያብሩ"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ከእንግዲህ መለየት አይችልም።"</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ከእንግዲህ መለየት አይችሉም።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index f2080cb..484d220 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -616,10 +616,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"يسمح هذا الإذن للتطبيق بتحديد الموضع النسبي بين الأجهزة المجاورة التي تستخدم النطاق الواسع جدًا."</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"‏التفاعل مع أجهزة Wi‑Fi المجاورة"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏للسماح للتطبيق بعرض الإعلانات والاتصال بالأجهزة الأخرى وتحديد الموقع النسبي لأجهزة Wi-Fi المجاورة."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"تحديد الموضع النسبي بين الأجهزة المجاورة"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"يسمح هذا الإذن للتطبيق بتحديد الموضع النسبي بين الأجهزة المجاورة"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏يسمح هذا الإذن للتطبيق بالحصول على معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل، مثلاً المساعدات المسجّلة ووجهة المسار."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"التحكم في اتصال الحقل القريب"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 1f207d5..fdddc70 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"এপ্‌টোক নিকটৱৰ্তী আল্ট্ৰা-ৱাইডবেণ্ড ডিভাইচসমূহৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ক"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"নিকটৱৰ্তী ৱাই-ফাই ডিভাইচসমূহৰ সৈতে ভাব বিনিময় কৰক"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এপ্‌টোক বিজ্ঞাপন প্ৰচাৰাভিযান কৰিবলৈ, সংযোগ কৰিবলৈ আৰু নিকটৱৰ্তী ৱাই-ফাই ডিভাইচৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"নিকটৱৰ্তী ডিভাইচৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰক"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"এপ্‌টোক নিকটৱৰ্তী ডিভাইচসমূহৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ক"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"অগ্ৰাধিকাৰ দিয়া NFC পৰিশোধ সেৱাৰ তথ্য"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"এপ্‌টোক অগ্ৰাধিকাৰ দিয়া nfc পৰিশোধ সেৱাৰ পঞ্জীকৃত সহায়কসমূহ আৰু পৰিশোধ কৰিব লগা লক্ষ্যস্থান দৰে তথ্য পাবলৈ অনুমতি দিয়ে।"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"নিয়েৰ ফিল্ড কমিউনিকেশ্বন নিয়ন্ত্ৰণ কৰক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 07216f5..003c0db 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tətbiqə yaxınlıqdakı Ultra Genişzolaqlı cihazları arasında nisbi mövqeyi təyin etməyə icazə verin"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"yaxınlıqdakı Wi-Fi cihazları ilə əlaqə qurmaq"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Tətbiqə yaxınlıqdakı Wi-Fi cihazlarında reklam etmək, onlara qoşulmaq və nisbi mövqeyini təyin etmək icazəsi verir"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"yaxınlıqdakı cihazlar arasında nisbi mövqeyin təyini"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Tətbiqin yaxınlıqdakı cihazlar arasında nisbi mövqeyi təyin etməsinə icazə verin"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tərcih edilən NFC ödəniş xidməti məlumatı"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tətbiqə qeydiyyatdan keçmiş yardım və marşrut təyinatı kimi tərcih edilən nfc ödəniş xidməti məlumatını əldə etmək icazəsi verir."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication\'ı kontrol et"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktiv edin"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Geri qayıdın"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Gözləmədə..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Təcili peyk bağlantısı artıq əlçatandır"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Mobil və ya Wi-Fi şəbəkəsi yoxdursa, təcili xidmətlərə mesaj göndərə bilərsiniz. Google Mesajlar defolt mesajlaşma tətbiqiniz olmalıdır."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Təcili peyk bağlantısı dəstəklənmir"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Təcili peyk bağlantısı bu cihazda dəstəklənmir"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Təcili peyk bağlantısı ayarlanmayıb"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"İnternetə qoşulduğunuzdan əmin olun və yenidən ayarlamağa cəhd edin"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Təcili peyk bağlantısı əlçatan deyil"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Təcili peyk bağlantısı bu ölkə və ya regionda əlçatan deyil"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Təcili peyk bağlantısı ayarlanmayıb"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Peyk vasitəsilə mesaj göndərmək üçün Google Mesajları defolt mesajlaşma tətbiqi olaraq təyin edin"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Təcili peyk bağlantısı əlçatan deyil"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Bu ölkədə və ya regionda təcili peyk bağlantısının əlçatan olub-olmadığını yoxlamaq üçün məkan ayarlarını aktiv edin"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Peyk mesajlaşması əlçatandır"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Mobil və ya Wi-Fi şəbəkəsi yoxdursa, peyk vasitəsilə mesaj göndərə bilərsiniz. Google Mesajlar defolt mesajlaşma tətbiqiniz olmalıdır."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Peyk mesajlaşması dəstəklənmir"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Peyk mesajlaşması bu cihazda dəstəklənmir"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Peyk mesajlaşması quraşdırılmayıb"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"İnternetə qoşulduğunuzdan əmin olun və yenidən ayarlamağa cəhd edin"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Peyk mesajlaşması əlçatan deyil"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Peyk mesajlaşması bu ölkə və ya regionda əlçatan deyil"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Peyk mesajlaşması quraşdırılmayıb"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Peyk vasitəsilə mesaj göndərmək üçün Google Mesajları defolt mesajlaşma tətbiqi olaraq təyin edin"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Peyk mesajlaşması əlçatan deyil"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Bu ölkədə və ya regionda peyk mesajlaşmasının əlçatan olub-olmadığını yoxlamaq üçün məkan ayarlarını aktiv edin"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmaqla Kilidaçmanı yenidən ayarlayın"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artıq tanınmır."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artıq tanınmır."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index ac6a47f..5a848ba 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dozvoljava aplikaciji da određuje relativnu razdaljinu između uređaja ultra-širokog pojasa u blizini"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcija sa WiFi uređajima u blizini"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Dozvoljava aplikaciji da se oglašava, povezuje i utvrđuje relativnu poziciju WiFi uređaja u blizini"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"određivanje razdaljine između uređaja u blizini"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Dozvolite aplikaciji da određuje relativnu razdaljinu između uređaja u blizini"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o željenoj NFC usluzi za plaćanje"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da preuzima informacije o željenoj NFC usluzi za plaćanje, poput registrovanih identifikatora aplikacija i odredišta preusmeravanja."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrola komunikacije u užem polju (Near Field Communication)"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index f492bfa..ce98a5f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -614,10 +614,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дазволіць праграме вызначаць адлегласць паміж прыладамі паблізу, якія выкарыстоўваюць звышшырокапалосную сувязь"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"узаемадзейнічаць з прыладамі з Wi‑Fi паблізу"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Праграма зможа адпраўляць даныя на прылады Wi-Fi паблізу, падключацца да іх і вызначаць іх месцазнаходжанне"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"вызначаць адноснае месцазнаходжанне прылад паблізу"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Дазвольце праграме вызначаць адноснае месцазнаходжанне прылад паблізу"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Інфармацыя пра прыярытэтны сэрвіс аплаты NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дазваляе праграме атрымаць доступ да інфармацыі пра прыярытэтны сэрвіс аплаты NFC, напрыклад зарэгістраваныя ідэнтыфікатары праграм і маршруты адпраўкі даных."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"кантроль Near Field Communication"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index c8b171a..aad5d48 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Разрешаване на приложението да определя относителната позиция между устройствата с ултрашироколентови сигнали в близост"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"взаимодействие с устройствата с Wi-Fi в близост"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Разрешава на приложението да рекламира, да се свързва и да определя относителната позиция на устройствата с Wi-Fi в близост"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"опр. на относителната позиция м/у у-вата в близост"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Разрешаване на приложението да определя относителната позиция между устройствата в близост"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информация за предпочитаната услуга за плащане чрез NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дава възможност на приложението да получава информация за предпочитаната услуга за плащане чрез NFC, като например регистрирани помощни средства и местоназначение."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"контролиране на комуникацията в близкото поле"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Включване"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Назад"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Изчаква..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Функцията „SOS чрез сателит“ вече е налице"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Можете да изпращате съобщения до службите за спешни случаи, ако нямате връзка с мобилна или Wi-Fi мрежа. Google Messages трябва да е основното ви приложение за съобщения."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Функцията „SOS чрез сателит“ не се поддържа"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Функцията „SOS чрез сателит“ не се поддържа на това устройство"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Функцията „SOS чрез сателит“ не е настроена"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Проверете дали имате връзка с интернет, и опитайте да настроите отново"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Функцията „SOS чрез сателит“ не е налице"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Функцията „SOS чрез сателит“ не е налице в тази държава или регион"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Функцията „SOS чрез сателит“ не е настроена"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"За да изпращате съобщения чрез сателит, задайте Google Messages като основното си приложение за съобщения"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Функцията „SOS чрез сателит“ не е налице"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"За да проверите дали функцията „SOS чрез сателит“ е налице в тази държава или регион, включете настройките за местоположението"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Функцията за сателитни съобщения е налице"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Можете да изпращате съобщения чрез сателит, ако нямате връзка с мобилна или Wi-Fi мрежа. Google Messages трябва да е основното ви приложение за съобщения."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Функцията за сателитни съобщения не се поддържа"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Функцията за сателитни съобщения не се поддържа на това устройство"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Функцията за сателитни съобщения не е настроена"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Проверете дали имате връзка с интернет, и опитайте да настроите отново"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Функцията за сателитни съобщения не е налице"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Функцията за сателитни съобщения не е налице в тази държава или регион"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Функцията за сателитни съобщения не е настроена"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"За да изпращате съобщения чрез сателит, задайте Google Messages като основното си приложение за съобщения"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Функцията за сателитни съобщения не е налице"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"За да проверите дали функцията за сателитни съобщения е налице в тази държава или регион, включете настройките за местоположението"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Повторно настройване на „Отключване с отпечатък“"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> вече не може да се разпознае."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> вече не могат да бъдат разпознати."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 0e103cc..d52f6e9 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"অ্যাপকে আশেপাশের Ultra-Wideband ডিভাইসগুলির আপেক্ষিক অবস্থান নির্ণয় করার অনুমতি দিন"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"আশপাশের ওয়াই-ফাই ডিভাইসের সাথে ইন্টার‍্যাক্ট করুন"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এটির ফলে অ্যাপ আশপাশের ওয়াই-ফাই ডিভাইসের তথ্য দেখতে, তাদের সাথে কানেক্ট করতে এবং তা কত দূরত্বে আছে সেটি জানতে পারবে"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"আশেপাশের ডিভাইসের আপেক্ষিক অবস্থান নির্ণয় করুন"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"অ্যাপকে আশেপাশের ডিভাইসের আপেক্ষিক অবস্থান নির্ণয় করার অনুমতি দিন"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"পছন্দের NFC পেমেন্ট পরিষেবার তথ্য"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"অ্যাপের মাধ্যমে পছন্দসই এনএফসি পেমেন্ট পরিষেবার তথ্য, যেমন রেজিস্ট্রার করার সহায়তা এবং রুট ডেস্টিনেশন সম্পর্কিত তথ্য অ্যাক্সেস করার অনুমতি দেয়।"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"নিয়ার ফিল্ড কমিউনিকেশন নিয়ন্ত্রণ করে"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 202afde..b74b139 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dozvolite aplikaciji da odredi relativni položaj između uređaja ultra širokog opsega u blizini"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"stupanje u interakciju s WiFi uređajima u blizini"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Dozvoljava aplikaciji da se oglašava, povezuje i određuje relativni položaj WiFi uređaja u blizini"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"određivanje relativnog položaja uređaja u blizini"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Dozvolite aplikaciji da odredi relativni položaj između uređaja u blizini"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja putem NFC-a"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da dobije informacije o preferiranoj usluzi plaćanja putem NFC-a kao što su registrirana pomagala i odredište rute."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"upravljanje NFC-om"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 8b28cd7..7500122 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permet que l\'aplicació determini la posició relativa entre els dispositius de banda ultraampla propers"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interaccionar amb els dispositius Wi‑Fi propers"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet que l\'aplicació s\'anunciï i es connecti als dispositius Wi‑Fi propers, i en determini la posició relativa"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"determin. posició relativa entre dispositius propers"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Permet que l\'aplicació determini la posició relativa entre els dispositius propers"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informació preferent sobre el servei de pagament per NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet que l\'aplicació obtingui informació preferent sobre el servei de pagament per NFC, com ara complements registrats i destinacions de rutes."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicació de camp proper (NFC)"</string>
@@ -2436,54 +2434,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activa"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Torna"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendent..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS per satèl·lit ja està disponible"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Pots enviar missatges als serveis d\'emergències si no tens cap xarxa mòbil ni Wi‑Fi. Missatges de Google ha de ser l\'aplicació de missatgeria predeterminada."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS per satèl·lit no s\'admet"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS per satèl·lit no s\'admet en aquest dispositiu"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS per satèl·lit no està configurat"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Comprova que tinguis connexió a Internet i torna a provar de configurar-lo"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS per satèl·lit no està disponible"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS per satèl·lit no està disponible en aquest país o regió"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS per satèl·lit no està configurat"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Per enviar missatges per satèl·lit, defineix Missatges de Google com a aplicació de missatgeria predeterminada"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS per satèl·lit no està disponible"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Per comprovar si SOS per satèl·lit està disponible en aquest país o regió, activa la configuració d\'ubicació"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Missatges per satèl·lit disponibles"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Pots enviar missatges per satèl·lit si no tens cap xarxa mòbil ni Wi‑Fi. Missatges de Google ha de ser l\'aplicació de missatgeria predeterminada."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Els missatges per satèl·lit no s\'admeten"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Els missatges per satèl·lit no s\'admeten en aquest dispositiu"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Els missatges per satèl·lit no estan configurats"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Comprova que tinguis connexió a Internet i torna a provar de configurar-los"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Els missatges per satèl·lit no estan disponibles"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Els missatges per satèl·lit no estan disponibles en aquest país o regió"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Els missatges per satèl·lit no estan configurats"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Per enviar missatges per satèl·lit, defineix Missatges de Google com a aplicació de missatgeria predeterminada"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Els missatges per satèl·lit no estan disponibles"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Per comprovar si els missatges per satèl·lit estan disponibles en aquest país o regió, activa la configuració d\'ubicació"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Torna a configurar Desbloqueig amb empremta digital"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ja no es pot reconèixer."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ja no es poden reconèixer."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index f3a020b..277d359 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -614,10 +614,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikace bude moci zjišťovat vzájemnou pozici mezi ultra-širokopásmovými zařízeními v okolí"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakce se zařízeními Wi-Fi v okolí"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Umožňuje aplikaci inzerovat, připojovat se a odhadovat relativní polohu zařízení Wi-Fi v okolí"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"zjišťování vzájemné pozice mezi zařízeními v okolí"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Aplikace bude moci zjišťovat vzájemnou pozici mezi zařízeními v okolí"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informace o preferované platební službě NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikaci získat informace o preferované platební službě NFC, například o registrovaných pomůckách a cíli směrování."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ovládání technologie NFC"</string>
@@ -2437,54 +2435,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Zapnout"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Zpět"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Čeká na vyřízení…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"K dispozici je funkce SOS přes satelit"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Pokud není k dispozici mobilní síť ani Wi-Fi, můžete na tísňovou linku poslat zprávu. Jako výchozí aplikace na odesílání zpráv musí být nastavené Google zprávy."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Funkce SOS přes satelit není podporována"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Funkce SOS přes satelit není na tomto zařízení podporována"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Funkce SOS přes satelit není nastavena"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Zkontrolujte připojení k internetu a zkuste nastavení provést znovu"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Funkce SOS přes satelit není k dispozici"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS před satelit není v této zemi nebo oblasti k dispozici"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Funkce SOS přes satelit není nastavena"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Pokud chcete odesílat zprávy přes satelit, nastavte Google zprávy jako výchozí aplikaci na odesílání zpráv"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Funkce SOS přes satelit není k dispozici"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Pokud chcete zjistit, zda je v této zemi nebo oblasti dostupná funkce SOS přes satelit, zapněte nastavení polohy"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Jsou k dispozici satelitní zprávy"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Pokud není k dispozici mobilní síť ani Wi-Fi, můžete odesílat zprávy přes satelit. Jako výchozí aplikace na odesílání zpráv musí být nastavené Google zprávy."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelitní zprávy nejsou podporovány"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satelitní zprávy nejsou na tomto zařízení podporovány"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelitní zprávy nejsou nastaveny"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Zkontrolujte připojení k internetu a zkuste nastavení provést znovu"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelitní zprávy nejsou k dispozici"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satelitní zprávy nejsou v této zemi nebo oblasti dostupné"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelitní zprávy nejsou nastaveny"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Pokud chcete odesílat zprávy přes satelit, nastavte Google zprávy jako výchozí aplikaci na odesílání zpráv"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelitní zprávy nejsou k dispozici"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Pokud chcete zjistit, zda jsou v této zemi nebo oblasti dostupné satelitní zprávy, zapněte nastavení polohy"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Opětovné nastavení odemknutí otiskem prstu"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> se nedaří rozpoznat."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se nedaří rozpoznat."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index b481682..9db6076 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tillad, at appen fastlægger den relative position mellem UWB-enheder (Ultra-Wideband) i nærheden"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagere med Wi‑Fi-enheder i nærheden"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Giver appen tilladelse til at informere om, oprette forbindelse til og fastslå den relative placering af Wi‑Fi-enheder i nærheden"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"fastlægge relativ position mellem enheder i nærheden"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Tillad, at appen fastlægger den relative position mellem enheder i nærheden"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Foretrukne oplysninger vedrørende NFC-betalingstjeneste"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillader, at appen får foretrukne oplysninger vedrørende NFC-betalingstjeneste, f.eks. registrerede hjælpemidler og rutedestinationer."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"administrere Near Field Communication"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivér"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Gå tilbage"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Afventer…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS-meldinger via satellit er nu tilgængelig"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Du kan sende beskeder til nødtjenester, hvis du ikke har forbindelse til et mobil- eller Wi-Fi-netværk. Google Beskeder skal være din standardapp til beskeder."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS-meldinger via satellit understøttes ikke"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS-meldinger via satellit understøttes ikke på denne enhed"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS-meldinger via satellit er ikke konfigureret"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Sørg for, at du har forbindelse til internettet, og prøv at konfigurere igen"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS-meldinger via satellit er ikke tilgængelig"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS-meldinger via satellit er ikke tilgængelig i dette land eller denne region"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS-meldinger via satellit er ikke konfigureret"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Hvis du vil sende beskeder via satellit, skal du angive Google Beskeder som din standardapp til beskeder"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS-meldinger via satellit er ikke tilgængelig"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Hvis du vil tjekke, om SOS-meldinger via satellit er tilgængelig i dette land eller denne region, skal du aktivere lokationsindstillinger"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satellitbeskeder er tilgængelige"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Du kan sende beskeder via satellit, hvis du ikke har forbindelse til et mobil- eller Wi-Fi-netværk. Google Beskeder skal være din standardapp til beskeder."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satellitbeskeder understøttes ikke"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satellitbeskeder understøttes ikke på denne enhed"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satellitbeskeder er ikke konfigureret"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Sørg for, at du har forbindelse til internettet, og prøv at konfigurere igen"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satellitbeskeder er ikke tilgængelige"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satellitbeskeder er ikke tilgængelige i dette land eller denne region"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satellitbeskeder er ikke konfigureret"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Hvis du vil sende beskeder via satellit, skal du angive Google Beskeder som din standardapp til beskeder"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satellitbeskeder er ikke tilgængelige"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Hvis du vil tjekke, om satellitbeskeder er tilgængelige i dette land eller denne region, skal du aktivere lokationsindstillinger"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer fingeroplåsning igen"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan ikke længere genkendes."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan ikke længere genkendes."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 64afb5a..9561b3f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ermöglicht der App, die relative Distanz zwischen Ultrabreitband-Geräten in der Nähe zu bestimmen"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Mit WLAN-Geräten in der Nähe interagieren"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Erlaubt der App, Inhalte an WLAN-Geräte in der Nähe zu senden, sich mit ihnen zu verbinden und ihre relative Position zu ermitteln"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"Relative Position zu Geräten in der Nähe bestimmen"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Ermöglicht es der App, die relative Position zu Geräten in der Nähe zu bestimmen"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informationen zum bevorzugten NFC-Zahlungsdienst"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ermöglicht der App, Informationen zum bevorzugten NFC-Zahlungsdienst abzurufen, etwa registrierte Hilfsmittel oder das Routenziel."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Nahfeldkommunikation steuern"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivieren"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Zurück"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Ausstehend…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"„Notruf über Satellit“ jetzt verfügbar"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Du kannst dem Rettungsdienst eine Nachricht senden, wenn kein Mobilfunknetz oder WLAN verfügbar ist. Dazu muss Google Messages als Standard-Messaging-App festgelegt sein."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"„Notruf über Satellit“ nicht unterstützt"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"„Notruf über Satellit“ wird auf diesem Gerät nicht unterstützt"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"„Notruf über Satellit“ nicht eingerichtet"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Vergewissere dich, dass du mit dem Internet verbunden bist, und versuche noch einmal, die Einrichtung durchzuführen"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"„Notruf über Satellit“ nicht verfügbar"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"„Notruf über Satellit“ ist in diesem Land oder in dieser Region nicht verfügbar"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"„Notruf über Satellit“ nicht eingerichtet"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Wenn du Nachrichten per Satellit senden möchtest, musst du Google Messages als Standard-Messaging-App festlegen"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"„Notruf über Satellit“ nicht verfügbar"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Wenn du wissen möchtest, ob „Notruf über Satellit“ in diesem Land oder dieser Region verfügbar ist, aktiviere die Standorteinstellungen"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"„Nachrichten per Satellit“ verfügbar"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Du kannst Nachrichten per Satellit senden, wenn kein Mobilfunknetz oder WLAN verfügbar ist. Dazu muss Google Messages als Standard-Messaging-App festgelegt sein."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"„Nachrichten per Satellit“ nicht unterstützt"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"„Nachrichten per Satellit“ wird auf diesem Gerät nicht unterstützt"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"„Nachrichten per Satellit“ nicht eingerichtet"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Vergewissere dich, dass du mit dem Internet verbunden bist, und versuche noch einmal, die Einrichtung durchzuführen"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"„Nachrichten per Satellit“ nicht verfügbar"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"„Nachrichten per Satellit“ ist in diesem Land oder dieser Region nicht verfügbar"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"„Nachrichten per Satellit“ nicht eingerichtet"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Wenn du Nachrichten per Satellit senden möchtest, musst du Google Messages als Standard-Messaging-App festlegen"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"„Nachrichten per Satellit“ nicht verfügbar"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Wenn du wissen möchtest, ob „Nachrichten per Satellit“ in diesem Land oder dieser Region verfügbar ist, aktiviere die Standorteinstellungen"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Entsperrung per Fingerabdruck neu einrichten"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> wird nicht mehr erkannt."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werden nicht mehr erkannt."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4ad85d9..551fe70 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Επιτρέψτε στην εφαρμογή να προσδιορίζει τη σχετική θέση μεταξύ κοντινών συσκευών Ultra-Wideband"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"αλληλεπίδραση με κοντινές συσκευές Wi‑Fi"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Επιτρέπει στην εφαρμογή: προβολή διαφημίσεων, σύνδεση και καθορισμό της σχετικής τοποθεσίας των κοντινών συσκευών Wi‑Fi"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"προσδιορ. σχετ. θέσης μεταξύ συσκ. σε κοντ. απόστ."</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Επιτρέψτε στην εφαρμογή να προσδιορίζει τη σχετική θέση μεταξύ συσκευών σε κοντινή απόσταση"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Πληροφορίες προτιμώμενης υπηρεσίας πληρωμών NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Επιτρέπει στην εφαρμογή να λαμβάνει πληροφορίες προτιμώμενης υπηρεσίας πληρωμής NFC, όπως καταχωρημένα βοηθήματα και προορισμό διαδρομής."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ελέγχει την Επικοινωνία κοντινού πεδίου (FNC)"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ενεργοποίηση"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Επιστροφή"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Σε εκκρεμότητα…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Το δορυφορικό SOS είναι πλέον διαθέσιμο"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Μπορείτε να στέλνετε μηνύματα σε υπηρεσίες έκτακτης ανάγκης, εάν δεν υπάρχει δίκτυο κινητής τηλεφωνίας ή Wi-Fi. Το Google Messages πρέπει να είναι η προεπιλεγμένη εφαρμογή ανταλλαγής μηνυμάτων."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Το δορυφορικό SOS δεν υποστηρίζεται"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Το δορυφορικό SOS δεν υποστηρίζεται σε αυτή τη συσκευή"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Το δορυφορικό SOS δεν έχει ρυθμιστεί"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Βεβαιωθείτε ότι είστε συνδεδεμένοι στο διαδίκτυο και δοκιμάστε ξανά τη ρύθμιση"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Το δορυφορικό SOS δεν είναι διαθέσιμο"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Το δορυφορικό SOS δεν είναι διαθέσιμο σε αυτή τη χώρα ή την περιοχή"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Το δορυφορικό SOS δεν έχει ρυθμιστεί"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Για να ανταλλάζετε μηνύματα μέσω δορυφόρου, ορίστε το Google Messages ως την προεπιλεγμένη εφαρμογή ανταλλαγής μηνυμάτων"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Το δορυφορικό SOS δεν είναι διαθέσιμο"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Για να ελέγξετε αν το δορυφορικό SOS είναι διαθέσιμο σε αυτή τη χώρα ή την περιοχή, ενεργοποιήστε τις ρυθμίσεις τοποθεσίας"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου είναι διαθέσιμη"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Μπορείτε να ανταλλάζετε μηνύματα μέσω δορυφόρου, εάν δεν υπάρχει δίκτυο κινητής τηλεφωνίας ή Wi-Fi. Το Google Messages πρέπει να είναι η προεπιλεγμένη εφαρμογή ανταλλαγής μηνυμάτων."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν υποστηρίζεται"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν υποστηρίζεται σε αυτή τη συσκευή"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν έχει ρυθμιστεί"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Βεβαιωθείτε ότι είστε συνδεδεμένοι στο διαδίκτυο και δοκιμάστε ξανά τη ρύθμιση"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν είναι διαθέσιμη"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν είναι διαθέσιμη σε αυτή τη χώρα ή την περιοχή"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν έχει ρυθμιστεί"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Για να ανταλλάζετε μηνύματα μέσω δορυφόρου, ορίστε το Google Messages ως την προεπιλεγμένη εφαρμογή ανταλλαγής μηνυμάτων"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν είναι διαθέσιμη"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Για να ελέγξετε αν η ανταλλαγή μηνυμάτων μέσω δορυφόρου είναι διαθέσιμη σε αυτή τη χώρα ή την περιοχή, ενεργοποιήστε τις ρυθμίσεις τοποθεσίας"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με δακτυλικό αποτύπωμα"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και του <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index a82b567..5cedb1f 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"determine relative position between nearby devices"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Allow the app to determine relative position between nearby devices"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index bf3b985..4e728ff0 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"determine relative position between nearby devices"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Allow the app to determine relative position between nearby devices"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 5c9c521..578e479 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"determine relative position between nearby devices"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Allow the app to determine relative position between nearby devices"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index ab6f6ce..da3c4c4 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la app determine la posición relativa con dispositivos Ultra Wideband cercanos"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactuar con dispositivos Wi-Fi cercanos"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que la app muestre anuncios, se conecte y determine la posición relativa de los dispositivos Wi-Fi cercanos"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"determinar posición relativa entre disp. cercanos"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Permite que la app determine la posición relativa con dispositivos cercanos"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre servicio de pago NFC preferido"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la app reciba información del servicio de pago NFC preferido, como el servicio de asistencia registrado y el destino de la ruta."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlar la Transmisión de datos en proximidad"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 23e1ae6..37bf70e 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la aplicación determine la posición relativa de los dispositivos de banda ultraancha cercanos"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactuar con dispositivos Wi-Fi cercanos"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite a la aplicación emitir y conectarse a dispositivos Wi-Fi cercanos y determinar su posición relativa"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"determinar posición relativa de dispositivos cercanos"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Permite que la aplicación determine la posición relativa de los dispositivos cercanos"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre el servicio de pago por NFC preferido"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la aplicación obtenga información sobre el servicio de pago por NFC preferido, como identificadores de aplicación registrados y destinos de rutas."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicación de campo cercano (NFC)"</string>
@@ -1411,7 +1409,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Se ha detectado un accesorio de audio analógico"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"El dispositivo adjunto no es compatible con este teléfono. Toca para obtener más información."</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"Depuración por USB activa"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca para desactivar depuración USB"</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca para desactivar la depuración por USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Seleccionar para inhabilitar la depuración por USB"</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Depuración inalámbrica conectada"</string>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toca para desactivar la depuración inalámbrica"</string>
@@ -2436,54 +2434,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activar"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Volver"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS por satélite ya está disponible"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Puedes enviar mensajes a los servicios de emergencias si no hay una red móvil o Wi-Fi disponible. Mensajes de Google debe ser tu aplicación de mensajería predeterminada."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"No se admite SOS por satélite"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Este dispositivo no admite SOS por satélite"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS por satélite no está configurado"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Comprueba que tienes conexión a Internet e inténtalo de nuevo"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS por satélite no está disponible"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS por satélite no está disponible en este país o territorio"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS por satélite no configurado"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Para enviar mensajes por satélite, configura Mensajes de Google como tu aplicación de mensajería predeterminada"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS por satélite no está disponible"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Para comprobar si SOS por satélite está disponible en este país o territorio, activa los ajustes de ubicación"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Mensajes por satélite disponibles"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Puedes enviar mensajes por satélite si no hay una red móvil o Wi-Fi disponible. Mensajes de Google debe ser tu aplicación de mensajería predeterminada."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Mensajes por satélite no admitidos"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Este dispositivo no admite los mensajes por satélite"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Mensajes por satélite no configurados"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Comprueba que tienes conexión a Internet e inténtalo de nuevo"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Mensajes por satélite no disponibles"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Los mensajes por satélite no están disponibles en este país o territorio"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Mensajes por satélite no configurados"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Para enviar mensajes por satélite, configura Mensajes de Google como tu aplicación de mensajería predeterminada"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Mensajes por satélite no disponibles"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Para comprobar si los mensajes por satélite están disponibles en este país o territorio, activa los ajustes de ubicación"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura Desbloqueo con huella digital de nuevo"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ya no puede reconocerse."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ya no pueden reconocerse."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index d22c93b..0d79e8a 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Võimaldab rakendusel määrata lähedalasuvate ülilairibaühendust kasutavate seadmete suhtelise kauguse üksteisest"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Läheduses olevate WiFi-seadmetega suhtlemine"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lubab rakendusel läheduses olevatele WiFi-seadmetele reklaamida, nendega ühenduse luua ja määrata nende suhteline asend"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"Määrata läheduses olevate seadmete suhtelise kauguse üksteisest."</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Võimaldab rakendusel määrata läheduses olevate seadmete suhtelise kauguse üksteisest"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Eelistatud NFC-makseteenuse teave"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Võimaldab rakendusel hankida eelistatud NFC-makseteenuse teavet (nt registreeritud abi ja marsruudi sihtkoht)."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"lähiväljaside juhtimine"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Lülita sisse"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Mine tagasi"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Ootel …"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satelliit-SOS on nüüd saadaval"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Saate hädaabiteenustele sõnumi saata, kui mobiilside- või WiFi-võrku pole. Google Messages peab olema teie vaikesõnumsiderakendus."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satelliit-SOSi ei toetata"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"See seade ei toeta satelliit-SOSi"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satelliit-SOS pole seadistatud"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Veenduge, et teil oleks internetiühendus, ja proovige uuesti seadistada"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satelliit-SOS pole saadaval"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satelliit-SOS ei ole selles riigis või piirkonnas saadaval"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satelliit-SOSi pole seadistatud"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Satelliidi teel sõnumite saatmiseks määrake Google Messages oma sõnumside vaikerakenduseks"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satelliit-SOS pole saadaval"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Et kontrollida, kas satelliit-SOS on selles riigis või piirkonnas saadaval, lülitage sisse asukohaseaded"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Saadaval on satelliidipõhine sõnumside"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Kui mobiilside- või WiFi-võrku pole, saate sõnumeid saata satelliidi teel. Google Messages peab olema teie vaikesõnumsiderakendus."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelliidipõhist sõnumsidet ei toetata"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"See seade ei toeta satelliidipõhist sõnumsidet"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelliidipõhine sõnumside pole seadistatud"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Veenduge, et teil oleks internetiühendus, ja proovige uuesti seadistada"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelliidipõhine sõnumside pole saadaval"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satelliidipõhine sõnumside ei ole selles riigis või piirkonnas saadaval"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelliidipõhine sõnumside pole seadistatud"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Satelliidi teel sõnumite saatmiseks määrake Google Messages oma sõnumside vaikerakenduseks"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelliidipõhine sõnumside pole saadaval"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Et kontrollida, kas satelliidipõhine sõnumside on selles riigis või piirkonnas saadaval, lülitage sisse asukohaseaded"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Seadistage sõrmejäljega avamine uuesti"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Sõrmejälge <xliff:g id="FINGERPRINT">%s</xliff:g> ei saa enam tuvastada."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Sõrmejälgi <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei saa enam tuvastada."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 914dfb7..b96f9eb 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Banda ultrazabala darabilten inguruko gailuen arteko distantzia erlatiboa zehazteko baimena ematen dio aplikazioari"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"inguruko wifi-gailuekin interakzioan jardun"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Inguruko wifi-gailuetan iragartzeko, haiekin konektatzeko eta haien kokapena zehazteko baimena ematen dio aplikazioari"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"zehaztu inguruko gailuen arteko distantzia erlatiboa"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Inguruko gailuen arteko distantzia erlatiboa zehazteko baimena ematen dio aplikazioari"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa jasotzeko baimena ematen dio aplikazioari, hala nola erregistratutako laguntzaileak eta ibilbidearen helmuga."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrolatu Near Field Communication komunikazioa"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktibatu"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Egin atzera"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Zain…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satelite bidezko SOS komunikazioa erabilgarri dago orain"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Larrialdi-zerbitzuekin mezuak trukatu ahal izango dituzu sare mugikorrik edo wifi-sarerik ez badago. Google-ren Mezuak aplikazioak izan behar du mezularitza-aplikazio lehenetsia."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satelite bidezko SOS komunikazioa ez da bateragarria"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satelite bidezko SOS komunikazioa ez da bateragarria gailu honekin"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satelite bidezko SOS komunikazioa ez dago konfiguratuta"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Ziurtatu Internetera konektatuta zaudela eta saiatu konfiguratzen berriro"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satelite bidezko SOS komunikazioa ez dago erabilgarri"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satelite bidezko SOS komunikazioa ez dago erabilgarri herrialde edo lurralde honetan"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satelite bidezko SOS komunikazioa ez dago konfiguratuta"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Satelite bidez mezuak trukatzeko, ezarri Google-ren Mezuak mezularitza-aplikazio lehenetsi gisa"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satelite bidezko SOS komunikazioa ez dago erabilgarri"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Herrialde edo lurralde honetan satelite bidezko SOS komunikazioa erabilgarri dagoen egiaztatzeko, aktibatu kokapen-ezarpenak"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satelite bidezko mezularitza erabilgarri dago"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Satelite bidez trukatu ahal izango dituzu mezuak sare mugikorrik edo wifi-sarerik ez badago. Google-ren Mezuak aplikazioak izan behar du mezularitza-aplikazio lehenetsia."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelite bidezko mezularitza ez da bateragarria"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satelite bidezko mezularitza ez da bateragarria gailu honekin"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelite bidezko mezularitza ez dago konfiguratuta"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Ziurtatu Internetera konektatuta zaudela eta saiatu konfiguratzen berriro"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelite bidezko mezularitza ez dago erabilgarri"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satelite bidezko mezularitza ez dago erabilgarri herrialde edo lurralde honetan"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelite bidezko mezularitza ez dago konfiguratuta"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Satelite bidez mezuak trukatzeko, ezarri Google-ren Mezuak mezularitza-aplikazio lehenetsi gisa"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelite bidezko mezularitza ez dago erabilgarri"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Herrialde edo lurralde honetan satelite bidezko mezularitza erabilgarri dagoen egiaztatzeko, aktibatu kokapen-ezarpenak"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ez da ezagutzen jada."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ez dira ezagutzen jada."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index c3e4b46..7627ff3 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"به برنامه اجازه داده می‌شود موقعیت نسبی بین دستگاه‌های «فراپهن‌باند» اطراف را مشخص کند"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"‏برقراری تعامل با دستگاه‌های Wi-Fi اطراف"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏به برنامه اجازه می‌دهد در دستگاه‌های Wi-Fi اطراف تبلیغ کند، به آن‌ها متصل شود، و موقعیت نسبی آن‌ها را تشخیص دهد"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"تعیین موقعیت نسبی بین دستگاه‌های اطراف"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"به برنامه اجازه داده می‌شود موقعیت نسبی بین دستگاه‌های اطراف را تعیین کند"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏اطلاعات ترجیحی سرویس پرداخت NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏به برنامه اجازه می‌دهد اطلاعات ترجیحی سرویس پرداخت NFC، مانند کمک‌های ثبت‌شده و مقصد مسیر را دریافت کند."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"کنترل ارتباط راه نزدیک"</string>
@@ -918,7 +916,7 @@
     <string name="phoneTypeCustom" msgid="5120365721260686814">"سفارشی"</string>
     <string name="phoneTypeHome" msgid="3880132427643623588">"خانه"</string>
     <string name="phoneTypeMobile" msgid="1178852541462086735">"تلفن همراه"</string>
-    <string name="phoneTypeWork" msgid="6604967163358864607">"کاری"</string>
+    <string name="phoneTypeWork" msgid="6604967163358864607">"محل کار"</string>
     <string name="phoneTypeFaxWork" msgid="6757519896109439123">"نمابر محل کار"</string>
     <string name="phoneTypeFaxHome" msgid="6678559953115904345">"نمابر خانه"</string>
     <string name="phoneTypePager" msgid="576402072263522767">"پی‌جو"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"روشن کردن"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"برگشتن"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"درحال تعلیق…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"«درخواست کمک ماهواره‌ای» اکنون دردسترس است"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"‏اگر شبکه Wi-Fi یا تلفن همراه وجود ندارد، می‌توانید به خدمات اضطراری پیام ارسال کنید. «پیام‌نگار Google» باید برنامه پیام‌رسانی پیش‌فرض شما باشد."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"«درخواست کمک ماهواره‌ای» پشتیبانی نمی‌شود"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"«درخواست کمک ماهواره‌ای» در این دستگاه پشتیبانی نمی‌شود"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"«درخواست کمک ماهواره‌ای» راه‌اندازی نشده است"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"مطمئن شوید به اینترنت متصل هستید و دوباره راه‌اندازی را امتحان کنید"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"«درخواست کمک ماهواره‌ای» دردسترس نیست"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"«درخواست کمک ماهواره‌ای» در این کشور یا منطقه دردسترس نیست"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"درخواست کمک ماهواره‌ای راه‌اندازی نمی‌شود"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"‏برای ارسال پیام ازطریق ماهواره، «پیام‌نگار Google» را به‌عنوان برنامه پیام‌رسانی پیش‌فرض تنظیم کنید"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"«درخواست کمک ماهواره‌ای» دردسترس نیست"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"برای بررسی دردسترس بودن «درخواست کمک ماهواره‌ای» در این کشور یا منطقه، تنظیمات مکان را روشن کنید"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"پیام‌رسانی ماهواره‌ای دردسترس است"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"‏اگر شبکه تلفن همراه یا Wi-Fi وجود ندارد، می‌توانید ازطریق ماهواره پیام ارسال کنید. «پیام‌نگار Google» باید برنامه پیام‌رسانی پیش‌فرض شما باشد."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"پیام‌رسانی ماهواره‌ای پشتیبانی نمی‌شود"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"پیام‌رسانی ماهواره‌ای در این دستگاه پشتیبانی نمی‌شود"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"پیام‌رسانی ماهواره‌ای راه‌اندازی نمی‌شود"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"مطمئن شوید به اینترنت متصل هستید و دوباره راه‌اندازی را امتحان کنید"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"پیام‌رسانی ماهواره‌ای دردسترس نیست"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"پیام‌رسانی ماهواره‌ای در این کشور یا منطقه دردسترس نیست"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"پیام‌رسانی ماهواره‌ای راه‌اندازی نمی‌شود"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"‏برای ارسال پیام ازطریق ماهواره، «پیام‌نگار Google» را به‌عنوان برنامه پیام‌رسانی پیش‌فرض تنظیم کنید"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"پیام‌رسانی ماهواره‌ای دردسترس نیست"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"برای بررسی دردسترس بودن پیام‌رسانی ماهواره‌ای در این کشور یا منطقه، تنظیمات مکان را فعال کنید"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"راه‌اندازی مجدد «قفل‌گشایی با اثر انگشت»"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> دیگر قابل‌شناسایی نیست."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> دیگر قابل‌شناسایی نیستند."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index fb7c4fe..78fb2a0 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Sallii sovelluksen määrittää UVB-taajuutta käyttävien laitteiden sijainnin suhteessa toisiinsa"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"käyttää lähellä olevia Wi-Fi-laitteita"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Sallii sovelluksen ilmoittaa ja määrittää lähellä olevien Wi-Fi-laitteiden suhteellisen sijainnin sekä yhdistää niihin"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"määrittää laitteiden suhteellisen sijainnin"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Sallii sovelluksen määrittää lähellä olevien laitteiden sijainnin suhteessa toisiinsa"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ensisijaiset NFC-maksupalvelutiedot"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Sallii sovelluksen noutaa tietoja rekisteröidyistä sovellustunnuksista, maksureitin kohteesta ja muita ensisijaisia NFC-maksupalvelutietoja."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"hallitse Near Field Communication -tunnistusta"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Laita päälle"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Takaisin"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Odottaa…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satellite SOS on nyt käytettävissä"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Voit lähettää viestin hätäkeskukseen, jos sinulla ei ole mobiili‑ tai Wi-Fi-verkkoyhteyttä. Google Messages täytyy valita oletusviestisovellukseksi."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satellite SOS ei tueta"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satellite SOS ei tueta tällä laitteella"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satellite SOS ei ole otettu käyttöön"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Varmista, että internetyhteys on muodostettu, ja yritä käyttöönottoa uudelleen"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satellite SOS ei ole saatavilla"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satellite SOS ei ole saatavilla tällä alueella"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS ei ole otettu käyttöön"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Jos haluat lähettää viestejä satelliitin kautta, aseta Google Messages oletusviestisovellukseksi"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS ei ole saatavilla"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Voit tarkistaa, onko Satellite SOS saatavilla tällä alueella, laittamalla sijaintiasetukset päälle"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satelliittiviestintä saatavilla"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Voit lähettää viestin satelliitin kautta, jos sinulla ei ole mobiili‑ tai Wi-Fi-verkkoyhteyttä. Google Messages täytyy valita oletusviestisovellukseksi."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelliittiviestintää ei tueta"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satelliittiviestejä ei tueta tällä laitteella"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelliittiviestintää ei ole otettu käyttöön"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Varmista, että internetyhteys on muodostettu, ja yritä käyttöönottoa uudelleen"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelliittiviestintä ei ole käytettävissä"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satelliittiviestintä ei ole saatavilla tällä alueella"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelliittiviestintää ei ole otettu käyttöön"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Jos haluat lähettää viestejä satelliitin kautta, aseta Google Messages oletusviestisovellukseksi"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelliittiviestintä ei ole käytettävissä"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Voit tarkistaa, onko satelliittiviestit saatavilla tällä alueella, laittamalla sijaintiasetukset päälle"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ota sormenjälkiavaus uudelleen käyttöön"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei enää ole tunnistettavissa."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät enää ole tunnistettavissa."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 18ef109..163d70d 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autorisez l\'appli à déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'appli de diffuser des annonces, de se connecter et de déterminer la position relative des appareils Wi-Fi à proximité"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"Dét. position relative entre appareils à proximité"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Autorisez l\'appli à déterminer la position relative entre des appareils à proximité"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information sur le service préféré de paiement CCP"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'appli d\'obtenir de l\'information sur le service préféré de paiement CCP comme les aides enregistrées et la route de destination."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"gérer la communication en champ proche"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index bd064d1..75b8e31 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autoriser l\'appli à déterminer la position relative entre des appareils ultra-wideband à proximité"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'appli de déterminer la position approximative des appareils Wi‑Fi à proximité, de les afficher et de s\'y connecter"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"déterminer l\'emplacement relatif entre des appareils à proximité"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Autorisez l\'appli à déterminer l\'emplacement relatif entre des appareils à proximité"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informations sur le service de paiement NFC préféré"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir des informations sur le service de paiement NFC préféré, y compris les ID d\'applications et les destinations de routage enregistrés."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"contrôler la communication en champ proche"</string>
@@ -2436,54 +2434,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activer"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Retour"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS par satellite est maintenant disponible"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Vous pouvez envoyer des messages aux services d\'urgence s\'il n\'y a pas de réseau mobile ou Wi-Fi. Google Messages doit être votre application de chat par défaut."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS par satellite n\'est pas disponible"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS par satellite n\'est pas disponible sur cet appareil"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS par satellite n\'est pas configuré"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Vérifiez votre connexion à Internet, puis essayez à nouveau de lancer la configuration."</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS par satellite n\'est pas disponible"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS par satellite n\'est pas disponible dans ce pays ou cette région"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS par satellite non configuré"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Pour envoyer des messages par satellite, définissez Google Messages comme application de chat par défaut"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS par satellite n\'est pas disponible"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Pour savoir si SOS par satellite est disponible dans ce pays ou cette région, activez les paramètres de localisation"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Messagerie par satellite disponible"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Vous pouvez envoyer des messages par satellite s\'il n\'y a pas de réseau mobile ou Wi-Fi. Google Messages doit être votre application de chat par défaut."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Messagerie par satellite non disponible"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"La messagerie par satellite n\'est pas disponible sur cet appareil"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Messagerie par satellite non configurée"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Vérifiez votre connexion à Internet, puis essayez à nouveau de lancer la configuration."</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Messagerie par satellite non disponible"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"La messagerie par satellite n\'est pas disponible dans ce pays ou cette région"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Messagerie par satellite non configurée"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Pour envoyer des messages par satellite, définissez Google Messages comme application de chat par défaut"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Messagerie par satellite non disponible"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Pour savoir si la messagerie par satellite est disponible dans ce pays ou cette région, activez les paramètres de localisation"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Reconfigurer le déverrouillage par empreinte digitale"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 292a952..70a7ec9 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que a aplicación determine a posición relativa entre os dispositivos próximos que usen banda ultralarga"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactuar con dispositivos wifi próximos"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permítelle á aplicación enviar anuncios e conectarse a dispositivos wifi próximos, e determinar a súa posición relativa"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"fixar a posición relativa entre disp. próximos"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Permite que a aplicación determine a posición relativa entre os dispositivos próximos"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información do servizo de pagos de NFC preferido"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a aplicación obteña información do servizo de pagos de NFC preferido, como as axudas rexistradas e o destino da ruta."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlar Near Field Communication"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activar"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Volver"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS por satélite xa está dispoñible"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Podes enviar mensaxes aos servizos de emerxencia se non tes conexión con ningunha rede wifi nin de telefonía móbil. Debes ter definida Mensaxes de Google como aplicación predeterminada de mensaxaría."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Non se admite SOS por satélite"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Non se admite SOS por satélite neste dispositivo"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS por satélite non se configurou"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Asegúrate de ter conexión a Internet e tenta volver facer a configuración"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS por satélite non está dispoñible"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS por satélite non está dispoñible neste país ou rexión"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS por satélite non se configurou"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Para intercambiar mensaxes por satélite, cómpre establecer Mensaxes de Google como aplicación de mensaxaría predeterminada"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS por satélite non está dispoñible"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Para comprobar se está dispoñible SOS por satélite neste país ou rexión, activa a configuración de localización"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Mensaxaría por satélite dispoñible"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Podes intercambiar mensaxes por satélite se non tes conexión con ningunha rede wifi nin de telefonía móbil. Debes ter definida Mensaxes de Google como aplicación predeterminada de mensaxaría."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Mensaxaría por satélite non admitida"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Non se admite a mensaxaría por satélite neste dispositivo"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Mensaxaría por satélite non configurada"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Asegúrate de ter conexión a Internet e tenta volver facer a configuración"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Mensaxaría por satélite non dispoñible"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"A mensaxaría por satélite non está dispoñible neste país ou rexión"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Mensaxaría por satélite non configurada"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Para intercambiar mensaxes por satélite, cómpre establecer Mensaxes de Google como aplicación de mensaxaría predeterminada"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Mensaxaría por satélite non dispoñible"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Para ver se está dispoñible a mensaxaría por satélite neste país ou rexión, activa a configuración de localización"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura de novo o desbloqueo dactilar"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> xa non se recoñece."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> xa non se recoñecen."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 70454a3..1535e4f 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ઍપને નજીકના અલ્ટ્રા-વાઇડબૅન્ડ ડિવાઇસની વચ્ચેનું સંબંધિત અંતર નક્કી કરવાની મંજૂરી આપો"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"નજીકના વાઇ-ફાઇ ડિવાઇસ સાથે ક્રિયાપ્રતિક્રિયા કરો"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ઍપને નજીકના વાઇ-ફાઇ ડિવાઇસની માહિતી બતાવવાની, તેની સાથે કનેક્ટ કરવાની અને તેની સંબંધિત સ્થિતિ નક્કી કરવાની મંજૂરી આપો"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"ડિવાઇસની વચ્ચેનું સાપેક્ષ અંતર નક્કી કરો"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"ઍપને નજીકના ડિવાઇસની વચ્ચેનું સાપેક્ષ અંતર નક્કી કરવાની મંજૂરી આપો"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"આ મંજૂરીને આપવાથી, ઍપ તમારી પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી મેળવી શકે છે, જેમ કે રજિસ્ટર થયેલી સહાય અને નિર્ધારિત સ્થાન."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"નિઅર ફીલ્ડ કમ્યુનિકેશન નિયંત્રિત કરો"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ચાલુ કરો"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"પાછા જાઓ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"બાકી..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"ઇમર્જન્સી સૅટલાઇટ સહાય હવે ઉપલબ્ધ છે"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"જો મોબાઇલ કે વાઇ-ફાઇ નેટવર્ક ન હોય, તો તમે ઇમર્જન્સી સર્વિસને મેસેજ કરી શકો છો. Google Messages તમારી ડિફૉલ્ટ મેસેજિંગ ઍપ હોવી આવશ્યક છે."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"ઇમર્જન્સી સૅટલાઇટ સહાયને સપોર્ટ કરવામાં આવતો નથી"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"આ ડિવાઇસ પર ઇમર્જન્સી સૅટલાઇટ સહાયને સપોર્ટ કરવામાં આવતો નથી"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"ઇમર્જન્સી સૅટલાઇટ સહાયનું સેટઅપ કર્યું નથી"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"તમે ઇન્ટરનેટથી કનેક્ટેડ હોવાની ખાતરી કરો અને ફરી સેટઅપ કરવાનો પ્રયાસ કરો"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"ઇમર્જન્સી સૅટલાઇટ સહાય ઉપલબ્ધ નથી"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"આ દેશ કે પ્રદેશમાં ઇમર્જન્સી સૅટલાઇટ સહાય ઉપલબ્ધ નથી"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"ઇમર્જન્સી સૅટલાઇટ સહાયનું સેટઅપ કરેલું નથી"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"સૅટલાઇટ દ્વારા મેસેજ મોકલવા માટે, Google Messagesને તમારી ડિફૉલ્ટ મેસેજિંગ ઍપ તરીકે સેટ કરો"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"ઇમર્જન્સી સૅટલાઇટ સહાય ઉપલબ્ધ નથી"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"આ દેશ કે પ્રદેશમાં ઇમર્જન્સી સૅટલાઇટ સહાય ઉપલબ્ધ છે કે કેમ તે ચેક કરવા માટે, લોકેશન સેટિંગ ચાલુ કરો"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ છે"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"જો કોઈ મોબાઇલ કે વાઇ-ફાઇ નેટવર્ક ઉપલબ્ધ ન હોય, તો તમે સૅટલાઇટ દ્વારા મેસેજ મોકલી શકો છો. Google Messages તમારી ડિફૉલ્ટ મેસેજિંગ ઍપ હોવી આવશ્યક છે."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"સૅટલાઇટ મેસેજિંગને સપોર્ટ કરવામાં આવતો નથી"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"આ ડિવાઇસ પર સૅટલાઇટ મેસેજિંગને સપોર્ટ કરવામાં આવતો નથી"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"સૅટલાઇટ મેસેજિંગનું સેટઅપ કર્યું નથી"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"તમે ઇન્ટરનેટથી કનેક્ટેડ હોવાની ખાતરી કરો અને ફરી સેટઅપ કરવાનો પ્રયાસ કરો"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ નથી"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"આ દેશ કે પ્રદેશમાં સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ નથી"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"સૅટલાઇટ મેસેજિંગનું સેટઅપ કર્યું નથી"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"સૅટલાઇટ દ્વારા મેસેજ મોકલવા માટે, Google Messagesને તમારી ડિફૉલ્ટ મેસેજિંગ ઍપ તરીકે સેટ કરો"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ નથી"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"આ દેશ કે પ્રદેશમાં સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ છે કે કેમ તે ચેક કરવા માટે, લોકેશન સેટિંગ ચાલુ કરો"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"હવે <xliff:g id="FINGERPRINT">%s</xliff:g> ઓળખી શકાતી નથી."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"હવે <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ઓળખી શકાતી નથી."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 5422f1b..c5825fe 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -322,7 +322,7 @@
     <string name="permgrouplab_location" msgid="1858277002233964394">"जगह की जानकारी"</string>
     <string name="permgroupdesc_location" msgid="1995955142118450685">"इस डिवाइस की जगह तक पहुंचने दें"</string>
     <string name="permgrouplab_calendar" msgid="6426860926123033230">"कैलेंडर"</string>
-    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करें"</string>
+    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"आपके कैलेंडर को ऐक्सेस करने की अनुमति"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"मैसेज (एसएमएस)"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
     <string name="permgrouplab_storage" msgid="17339216290379241">"फ़ाइल"</string>
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ऐप्लिकेशन को आस-पास मौजूद Ultra-Wideband डिवाइसों के बीच की दूरी का पता लगाने की अनुमति दें"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"आस-पास मौजूद वाई-फ़ाई डिवाइसों से इंटरैक्ट करें"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"इससे, ऐप्लिकेशन आस-पास मौजूद वाई-फ़ाई डिवाइसों की जानकारी दिखा पाएगा, उनसे कनेक्ट कर पाएगा, और उनकी दूरी पता लगा पाएगा"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"आस-पास मौजूद डिवाइसों के बीच की दूरी का पता लगाएं"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"ऐप्लिकेशन को, आस-पास मौजूद डिवाइसों के बीच की दूरी का पता लगाने की अनुमति दें"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC का इस्तेमाल करने वाली पैसे चुकाने की पसंदीदा सेवा की जानकारी"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"अगर ऐप्लिकेशन को अनुमति दी जाती है, तो वह पैसे चुकाने की आपकी उस पसंदीदा सेवा के बारे में जानकारी पा सकता है जो NFC का इस्तेमाल करती है. इसमें रजिस्टर किए गए डिवाइस और उनके आउटपुट के रूट जैसी जानकारी शामिल होती है."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"नियर फ़ील्‍ड कम्‍यूनिकेशन नियंत्रित करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0594788..954f4cb 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dopušta aplikaciji da odredi približni položaj između uređaja u blizini koji upotrebljavaju ultraširokopojasno povezivanje"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcija s Wi-Fi uređajima u blizini"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Aplikaciji omogućuje oglašavanje, povezivanje i određivanje približnog položaja Wi-Fi uređaja u blizini"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"određivanje rel. položaja između uređaja u blizini"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Dopustite aplikaciji da odredi relativni položaj između uređaja u blizini"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Omogućuje aplikaciji primanje informacija o preferiranoj usluzi plaćanja NFC kao što su registrirana pomagala i odredište."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 8adb234..58a5cbd 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Az alkalmazás meghatározhatja a közeli, ultraszélessávú eszközök közötti relatív pozíciót"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"műveletek végrehajtása a közeli Wi‑Fi-eszközökkel"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Engedélyezi az alkalmazás számára, hogy közzétegye és meghatározza a közeli Wi-Fi-eszközök viszonylagos helyzetét, és csatlakozzon hozzájuk."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"közeli eszközök közötti relatív pozíció meghatározása"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Az alkalmazás meghatározhatja a közeli eszközök közötti relatív pozíciót"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferált NFC fizetési szolgáltatási információk"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lehetővé teszi az alkalmazás számára preferált NFC fizetési szolgáltatási információk (pl. regisztrált alkalmazásazonosítók és útvonali cél) lekérését."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"NFC technológia vezérlése"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Bekapcsolás"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Vissza"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Függőben…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Mostantól rendelkezésre áll a műholdas SOS"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Mobil- vagy Wi-Fi-hálózat nélkül is küldhet üzenetet a segélyhívó szolgálatnak. Ehhez a Google Messagest kell beállítani alapértelmezett üzenetküldő almazásként."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Nem támogatott a műholdas SOS"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Ezen az eszközön nem támogatott a műholdas SOS."</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Nincs beállítva a műholdas SOS"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Ellenőrizze, hogy csatlakozik-e az internethez, majd próbálja újra a beállítást."</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Nem áll rendelkezésre a műholdas SOS"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Ebben az országban vagy régióban nem áll rendelkezésre a műholdas SOS."</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Nincs beállítva a műholdas SOS"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Műholdas üzenetváltáshoz állítsa be a Google Messagest alapértelmezett üzenetküldő alkalmazásként."</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Nem áll rendelkezésre a műholdas SOS"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Ha szeretné ellenőrizni, hogy rendelkezésre áll-e a műholdas SOS ebben az országban vagy régióban, kapcsolja be a helybeállításokat."</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Rendelkezésre áll a műholdas üzenetváltás"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Műholdon keresztül is küldhet üzenetet, ha nincs mobil- vagy Wi-Fi-hálózat. Ehhez a Google Messagest kell beállítani alapértelmezett üzenetküldő almazásként."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Nem támogatott a műholdas üzenetváltás"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Ezen az eszközön nem támogatott a műholdas üzenetváltás."</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Nincs beállítva a műholdas üzenetváltás"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Ellenőrizze, hogy csatlakozik-e az internethez, majd próbálja újra a beállítást."</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Nem áll rendelkezésre a műholdas üzenetváltás"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Ebben az országban vagy régióban nem áll rendelkezésre a műholdas üzenetváltás."</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Nincs beállítva a műholdas üzenetváltás"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Műholdas üzenetváltáshoz állítsa be a Google Messagest alapértelmezett üzenetküldő alkalmazásként."</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Nem áll rendelkezésre a műholdas üzenetváltás"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Ha szeretné ellenőrizni, hogy rendelkezésre áll-e a műholdas üzenetváltás ebben az országban vagy régióban, kapcsolja be a helybeállításokat."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"A Feloldás ujjlenyomattal funkció újbóli beállítása"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A következő már nem felismerhető: <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"A következők már nem felismerhetők: <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 4a16d2f..f457c42d 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Թույլատրել հավելվածին որոշել գերլայնաշերտ կապի տեխնոլոգիան աջակցող մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"փոխներգործել մոտակա Wi‑Fi սարքերի հետ"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Թույլ է տալիս հավելվածին տվյալներ փոխանցել մոտակա Wi‑Fi սարքերին, միանալ դրանց և որոշել դրանց մոտավոր դիրքը։"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"որոշել մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Թույլատրել հավելվածին որոշել մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Տեղեկություններ NFC վճարային ծառայության մասին"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Թույլ է տալիս հավելվածին ստանալ նախընտրելի NFC վճարային ծառայության մասին տեղեկություններ (օր․՝ գրանցված լրացուցիչ սարքերի և երթուղու նպատակակետի մասին տվյալներ)։"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"վերահսկել Մոտ Տարածությամբ Հաղորդակցումը"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Միացնել"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Հետ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Առկախ է…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satellite SOS-ը այժմ հասանելի է"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Դուք կարող եք հաղորդագրություն գրել արտակարգ իրավիճակների ծառայություններին բջջային կամ Wi-Fi ցանցի բացակայության դեպքում։ Google Messages-ը պետք է լինի հաղորդագրման ձեր կանխադրված հավելվածը։"</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satellite SOS-ը չի աջակցվում"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satellite SOS-ը այս սարքում չի աջակցվում"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satellite SOS-ը կարգավորված չէ"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Համոզվեք, որ միացած եք ինտերնետին, և նորից փորձեք կարգավորել"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satellite SOS-ը հասանելի չէ"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satellite SOS-ը հասանելի չէ այս երկրում կամ տարածաշրջանում"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS-ը կարգավորված չէ"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Արբանյակային կապով հաղորդագրություններ ուղարկելու համար Google Messages-ը դարձրեք հաղորդագրման ձեր կանխադրված հավելվածը"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS-ը հասանելի չէ"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Միացրեք տեղադրության կարգավորումները, որպեսզի ստուգեք՝ արդյոք Satellite SOS գործառույթը հասանելի է այս երկրում կամ տարածաշրջանում"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Արբանյակային հաղորդագրումը հասանելի է"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Բջջային կամ Wi-Fi ցանցի բացակայության դեպքում դուք կարող եք հաղորդագրություններ ուղարկել արբանյակային կապով։ Google Messages-ը պետք է լինի հաղորդագրման ձեր կանխադրված հավելվածը։"</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Արբանյակային հաղորդագրումը չի աջակցվում"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Արբանյակային հաղորդագրումն այս սարքում չի աջակցվում"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Արբանյակային հաղորդագրումը կարգավորված չէ"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Համոզվեք, որ միացած եք ինտերնետին, և նորից փորձեք կարգավորել"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Արբանյակային հաղորդագրումը հասանելի չէ"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Արբանյակային հաղորդագրումը հասանելի չէ այս երկրում կամ տարածաշրջանում"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Արբանյակային հաղորդագրումը կարգավորված չէ"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Արբանյակային կապով հաղորդագրություններ ուղարկելու համար Google Messages-ը դարձրեք հաղորդագրման ձեր կանխադրված հավելվածը"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Արբանյակային հաղորդագրումը հասանելի չէ"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Միացրեք տեղադրության կարգավորումները, որպեսզի ստուգեք՝ արդյոք արբանյակային հաղորդագրումը հասանելի է այս երկրում կամ տարածաշրջանում"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Նորից կարգավորեք մատնահետքով ապակողպումը"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> մատնահետքն այլևս չի կարող ճանաչվել։"</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> և <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> մատնահետքերն այլևս չեն կարող ճանաչվել։"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index e90137f..88764c4 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Mengizinkan aplikasi menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"berinteraksi dengan perangkat Wi-Fi di sekitar"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Mengizinkan aplikasi menampilkan, menghubungkan, dan menentukan posisi relatif perangkat Wi-Fi di sekitar"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"menentukan posisi relatif antar-perangkat di sekitar"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Izinkan aplikasi menentukan posisi relatif antar-perangkat di sekitar"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasi Layanan Pembayaran NFC Pilihan"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Mengizinkan aplikasi untuk mendapatkan informasi layanan pembayaran NFC pilihan seperti bantuan terdaftar dan tujuan rute."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrol NFC"</string>
@@ -1397,7 +1395,7 @@
     <string name="no_permissions" msgid="5729199278862516390">"Tidak perlu izin"</string>
     <string name="perm_costs_money" msgid="749054595022779685">"ini mungkin tidak gratis"</string>
     <string name="dlg_ok" msgid="5103447663504839312">"Oke"</string>
-    <string name="usb_charging_notification_title" msgid="1674124518282666955">"Daya perangkat sedang diisi via USB"</string>
+    <string name="usb_charging_notification_title" msgid="1674124518282666955">"Mengisi daya perangkat ini via USB"</string>
     <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Mengisi daya perangkat yang terhubung via USB"</string>
     <string name="usb_mtp_notification_title" msgid="1065989144124499810">"Transfer file USB diaktifkan"</string>
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB diaktifkan"</string>
@@ -1763,7 +1761,7 @@
     <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Alat bantu dengar"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
-    <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan tombol volume. Untuk mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tekan dan tahan kedua tombol volume lagi selama 3 detik."</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan tombol volume. Untuk mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tekan kedua tombol volume lagi selama 3 detik."</string>
     <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Pilih fitur"</string>
     <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Pilih fitur"</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Pilih fitur"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktifkan"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Kembali"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Tertunda..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS via Satelit kini tersedia"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Anda dapat mengirim pesan ke layanan darurat jika tidak ada jaringan seluler atau Wi-Fi. Google Message harus menjadi aplikasi pesan default Anda."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS via Satelit tidak didukung"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS via Satelit tidak didukung di perangkat ini"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS via Satelit tidak disiapkan"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Pastikan perangkat Anda terhubung ke internet, lalu coba siapkan lagi"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS via Satelit tidak tersedia"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS via Satelit tidak tersedia di negara atau wilayah ini"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS via Satelit tidak disiapkan"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Untuk mengirim pesan melalui satelit, setel Google Message sebagai aplikasi pesan default"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS via Satelit tidak tersedia"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Untuk memeriksa apakah SOS via Satelit tersedia di negara atau wilayah ini, aktifkan setelan lokasi"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Fitur pesan satelit tersedia"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Anda dapat mengirim pesan melalui satelit jika tidak ada jaringan seluler atau Wi-Fi. Google Message harus menjadi aplikasi pesan default Anda."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Fitur pesan satelit tidak didukung"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Fitur pesan satelit tidak didukung di perangkat ini"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Fitur pesan satelit tidak disiapkan"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Pastikan perangkat Anda terhubung ke internet, lalu coba siapkan lagi"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Fitur pesan satelit tidak tersedia"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Fitur pesan satelit tidak tersedia di negara atau wilayah ini"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Fitur pesan satelit tidak disiapkan"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Untuk mengirim pesan melalui satelit, setel Google Message sebagai aplikasi pesan default"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Fitur pesan satelit tidak tersedia"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Untuk memeriksa apakah fitur pesan satelit tersedia di negara atau wilayah ini, aktifkan setelan lokasi"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Siapkan Buka dengan Sidik Jari lagi"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dikenali lagi."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dikenali lagi."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 9ca5731..8e92ed1 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Leyfa forritinu að ákvarða fjarlægð milli nálægra tækja með ofurbreiðband"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"eiga í samskiptum við nálæg WiFi-tæki"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Leyfir forritinu að auglýsa, tengja og áætla staðsetningu nálægra WiFi-tækja"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"greina áætlaða fjarlægð á milli nálægra tækja"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Leyfðu forritinu að greina áætlaða fjarlægð á milli nálægra tækja"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Upplýsingar um valda NFC-greiðsluþjónustu"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gerir forritinu kleift að fá valda NFC-greiðsluþjónustu, svo sem skráða aðstoð og áfangastað leiðar."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"stjórna nándarsamskiptum (NFC)"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ac0e458..49f1f21 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Consenti all\'app di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Interazione con dispositivi Wi-Fi vicini"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Consente all\'app di trasmettere annunci e connettersi a dispositivi Wi‑Fi vicini e di stabilirne la posizione relativa."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"stabilire la posizione relativa tra dispositivi nelle vicinanze"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Consenti all\'app di stabilire la posizione relativa tra dispositivi nelle vicinanze"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informazioni del servizio di pagamento NFC preferito"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Consente all\'app di recuperare informazioni del servizio di pagamento NFC preferito, quali destinazione della route e identificatori applicazione registrati."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controllo Near Field Communication"</string>
@@ -2436,54 +2434,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Attiva"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Indietro"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"In attesa…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS satellitare è disponibile"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Puoi inviare messaggi ai servizi di emergenza se non disponi di una rete mobile o Wi-Fi. Google Messaggi deve essere l\'app di messaggistica predefinita."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS satellitare non supportato"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS satellitare non è supportato su questo dispositivo"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS satellitare non configurato"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Assicurati di avere una connessione a internet attiva e prova a ripetere la configurazione"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS satellitare non disponibile"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS satellitare non è disponibile in questo paese o in questa regione"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS satellitare non configurato"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Per inviare messaggi via satellite, imposta Google Messaggi come app di messaggistica predefinita"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS satellitare non disponibile"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Per verificare se SOS satellitare è disponibile in questo paese o in questa regione, attiva le impostazioni di localizzazione"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Messaggi via satellite disponibili"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Puoi inviare messaggi via satellite se non disponi di una rete mobile o Wi-Fi. Google Messaggi deve essere l\'app di messaggistica predefinita."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Messaggi via satellite non supportati"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"I messaggi via satellite non sono supportati su questo dispositivo"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Messaggi via satellite non configurati"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Assicurati di avere una connessione a internet attiva e prova a ripetere la configurazione"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Messaggi via satellite non disponibili"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"I messaggi via satellite non sono disponibili in questo paese o in questa regione"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Messaggi via satellite non configurati"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Per inviare messaggi via satellite, imposta Google Messaggi come app di messaggistica predefinita"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Messaggi via satellite non disponibili"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Per verificare se i messaggi via satellite sono disponibili in questo paese o in questa regione, attiva le impostazioni di localizzazione"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Riconfigura lo Sblocco con l\'Impronta"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> non può più essere riconosciuto."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non possono più essere riconosciuti."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 386f531..0e8f472 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"‏האפליקציה תזהה את המיקום היחסי בין מכשירים קרובים שמשדרים בטכנולוגיית Ultra Wideband ‏(UWB)"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"‏אינטראקציה עם מכשירי Wi-Fi בקרבת מקום"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏האפליקציה תוכל לפרסם במכשירי Wi-Fi בקרבת מקום, להתחבר אליהם ולהעריך את המיקום היחסי שלהם"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"זיהוי המיקום היחסי בין מכשירים קרובים"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"האפליקציה תזהה את המיקום היחסי בין מכשירים קרובים"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏פרטים על שירות תשלום מועדף ב-NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏מאפשרת לאפליקציה לקבל פרטים על שירות תשלום מועדף ב-NFC, כמו עזרים רשומים ויעד של נתיב."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"שליטה בתקשורת מטווח קצר"</string>
@@ -1411,7 +1409,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"המכשיר זיהה התקן אודיו אנלוגי"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ההתקן שחיברת לא תואם לטלפון הזה. יש להקיש לקבלת מידע נוסף."</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"‏ניפוי באגים ב-USB מחובר"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"‏יש להקיש כדי לכבות את ניפוי הבאגים ב-USB"</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"‏צריך להקיש כדי להשבית את ניפוי הבאגים ב-USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"‏יש ללחוץ על ההתראה כדי להשבית ניפוי באגים ב-USB."</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ניפוי הבאגים האלחוטי מחובר"</string>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"יש להקיש כדי להשבית ניפוי באגים אלחוטי"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 3391446..6eabd4a 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"付近の Ultra Wideband デバイス間の相対位置の特定をアプリに許可します"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"付近の Wi-Fi デバイスとの通信"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"付近の Wi-Fi デバイスについて、情報の表示、接続、相対位置の確認をアプリに許可します"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"付近のデバイス間の相対位置の特定"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"付近のデバイス間の相対位置の特定をアプリに許可します"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"優先される NFC お支払いサービスの情報"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"登録されている支援やルートの目的地など、優先される NFC お支払いサービスの情報を取得することをアプリに許可します。"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"NFCの管理"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 58f7890..4ffa312 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ნებას რთავს აპს, დაადგინოს შედარებითი პოზიცია ახლომახლო ულტრაფართო სიხშირის მოწყობილობების შესახებ"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ინტერაქცია ახლომახლო Wi-Fi მოწყობილობებთან"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"საშუალებას აძლევს აპს, განაცხადოს ახლომახლო Wi-Fi მოწყობილობების შესახებ, დაუკავშირდეს მათ და განსაზღვროს მათი შედარებითი პოზიცია"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"ახლომახლო მოწყობილობებთან მიმართ. პოზიციის დადგენა"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"აპისთვის ახლომახლო მოწყობილობებთან მიმართებაში პოზიციის დადგენის ნების დართვა"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"უპირატესი NFC გადახდის სერვისის ინფორმაცია"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"საშუალებას აძლევს აპს, მიიღოს უპირატესი NFC გადახდის სერვისის ინფორმაცია, მაგალითად, რეგისტრირებული დახმარება და დანიშნულება."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ახლო მოქმედების რადიოკავშირი (NFC) მართვა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 737f950..6355d86 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Қолданбаға маңайдағы кең жолақты құрылғылардың бір-біріне қатысты орнын анықтауға мүмкіндік береді."</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"маңайдағы Wi-Fi құрылғыларымен байланысу"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Қолданба маңайдағы Wi‑Fi құрылғыларына жарнама беріп, оларға қосылып, шамамен орналасқан жерін анықтай алады."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"маңайдағы құрылғылардың салыстырмалы орнын анықтау"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Қолданбаның маңайдағы құрылғылардың салыстырмалы орнын анықтауына рұқсат береді."</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Таңдаулы NFC төлеу қызметі туралы ақпарат"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Қолданба тіркелген көмектер және баратын жер маршруты сияқты таңдаулы NFC төлеу қызметі туралы ақпаратты ала алатын болады."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"NFC функциясын басқару"</string>
@@ -1398,7 +1396,7 @@
     <string name="perm_costs_money" msgid="749054595022779685">"бұған төлем қажет болуы мүмкін"</string>
     <string name="dlg_ok" msgid="5103447663504839312">"Жарайды"</string>
     <string name="usb_charging_notification_title" msgid="1674124518282666955">"Құрылғы USB арқылы зарядталып тұр"</string>
-    <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Жалғанған құрылғы USB арқылы зарядталуда"</string>
+    <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Жалғанған құрылғы USB арқылы зарядталып жатыр"</string>
     <string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB арқылы файл жіберу мүмкіндігі қосылды"</string>
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP режимі USB арқылы қосылды"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB-тетеринг режимі қосылды"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Қосу"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Артқа"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Дайын емес…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satellite SOS функциясы енді қолжетімді"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Мобильдік немесе Wi-Fi желісі жоқ болған жағдайда, құтқару қызметтеріне хабар жіберуге болады. Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satellite SOS функциясына қолдау көрсетілмейді"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satellite SOS функциясына бұл құрылғыда қолдау көрсетілмейді."</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satellite SOS функциясы реттелмеген"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Құрылғыңыздың интернетке қосылғанын тексеріп, қайта реттеп көріңіз."</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satellite SOS функциясы қолжетімді емес"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satellite SOS функциясы бұл елде немесе аймақта қолжетімді емес."</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS функциясы реттелмеген"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Жерсерік арқылы хабар алмасу үшін, Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS функциясы қолжетімді емес"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Satellite SOS функциясының бұл елде немесе аймақта қолжетімді екенін тексеру үшін, локация параметрлерін қосыңыз."</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Жерсерік арқылы хабар алмасу функциясы қолжетімді"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Мобильдік немесе Wi-Fi желісі жоқ болған жағдайда, жерсерік арқылы хабар алмаса аласыз. Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Жерсерік арқылы хабар алмасу функциясына қолдау көрсетілмейді"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Жерсерік арқылы хабар алмасу функциясына бұл құрылғыда қолдау көрсетілмейді."</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Жерсерік арқылы хабар алмасу функциясы реттелмеген"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Құрылғыңыздың интернетке қосылғанын тексеріп, қайта реттеп көріңіз."</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Жерсерік арқылы хабар алмасу функциясы қолжетімді емес"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Жерсерік арқылы хабар алмасу функциясы бұл елде немесе аймақта қолжетімді емес."</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Жерсерік арқылы хабар алмасу функциясы реттелмеген"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Жерсерік арқылы хабар алмасу үшін, Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Жерсерік арқылы хабар алмасу функциясы қолжетімді емес"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Жерсерік арқылы хабар алмасу функциясының бұл елде немесе аймақта қолжетімді екенін тексеру үшін, локация параметрлерін қосыңыз."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Саусақ ізімен ашу функциясын қайта реттеу"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> бұдан былай танылмайды."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> бұдан былай танылмайды."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 0ecad8f..4163be4 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"អនុញ្ញាតឱ្យ​កម្មវិធី​កំណត់ចម្ងាយ​ពាក់ព័ន្ធ​រវាងឧបករណ៍ Ultra-Wideband ដែលនៅជិត"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ធ្វើអន្តរកម្ម​ជាមួយឧបករណ៍ Wi‑Fi ដែលនៅជិត"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"អនុញ្ញាតឱ្យ​កម្មវិធី​ផ្សាយពាណិជ្ជកម្ម ភ្ជាប់ និងកំណត់ទីតាំង​ពាក់ព័ន្ធរបស់​ឧបករណ៍ Wi‑Fi ដែលនៅជិត"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"កំណត់ទីតាំងធៀបរវាងឧបករណ៍នៅជិត"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"អនុញ្ញាតឱ្យកម្មវិធីកំណត់ទីតាំងធៀបរវាងឧបករណ៍នៅជិត"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ព័ត៌មានអំពី​សេវាបង់ប្រាក់តាម NFC ជាអាទិភាព"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"អនុញ្ញាតឱ្យ​កម្មវិធី​ទទួលបាន​ព័ត៌មានអំពី​សេវាបង់ប្រាក់តាម nfc ជាអាទិភាព​ដូចជា គោលដៅផ្លូវ និង​ព័ត៌មាន​កំណត់អត្តសញ្ញាណ​កម្មវិធី ដែលបានចុះឈ្មោះ​ជាដើម។"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ពិនិត្យ​ការ​ទាក់ទង​នៅ​ក្បែរ (NFC)"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index c64f6ec..234ba66 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ಸಮೀಪದಲ್ಲಿರುವ ಅಲ್ಟ್ರಾ-ವೈಡ್‌ಬ್ಯಾಂಡ್ ಸಾಧನಗಳ ನಡುವೆ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಿ"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ಹತ್ತಿರದ ವೈ -ಫೈ ಸಾಧನಗಳ ಜೊತೆಗೆ ಸಂವಹನ ನಡೆಸಿ"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ಹತ್ತಿರದ ವೈ -ಫೈ ಸಾಧನಗಳ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ಸೂಚಿಸಲು, ಕನೆಕ್ಟ್ ಮಾಡಲು ಮತ್ತು ನಿರ್ಧರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"ಸಮೀಪದ ಸಾಧನಗಳ ನಡುವಿನ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸಿ"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳ ನಡುವಿನ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಿ"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವಾ ಮಾಹಿತಿ"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ನೋಂದಾಯಿತ ಆ್ಯಪ್ ಗುರುತಿಸುವಿಕೆಗಳು ಮತ್ತು ಮಾರ್ಗ ಗಮ್ಯಸ್ಥಾನಗಳಂತಹ ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವೆಗಳ ಬಗ್ಗೆ ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ಸಮೀಪ ಕ್ಷೇತ್ರ ಸಂವಹನವನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
@@ -837,7 +835,7 @@
     <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"ಇತರ ಆ್ಯಪ್‌ಗಳ ಮಾಲೀಕತ್ವದ E2EE ಸಂಪರ್ಕ ಕೀಗಳ ಪರಿಶೀಲನೆಯ ಸ್ಥಿತಿಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಿ"</string>
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"ಇತರ ಆ್ಯಪ್‌ಗಳ ಮಾಲೀಕತ್ವದ E2EE ಸಂಪರ್ಕ ಕೀಗಳ ಪರಿಶೀಲನೆಯ ಸ್ಥಿತಿಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"ಪಾಸ್‌ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
-    <string name="policydesc_limitPassword" msgid="4105491021115793793">"ಪರದೆ ಲಾಕ್‌ನಲ್ಲಿನ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಪಿನ್‌ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
+    <string name="policydesc_limitPassword" msgid="4105491021115793793">"ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ನಲ್ಲಿನ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಪಿನ್‌ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"ಪರದೆಯ ಅನ್‌ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ಸ್ಕ್ರೀನ್ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್‌ ಮಾಡಿದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ, ಮತ್ತು ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಟೈಪ್‌ ಮಾಡಿದ್ದರೆ ಟ್ಯಾಬ್ಲೆಟ್‌ ಅನ್ನು ಲಾಕ್‌ ಮಾಡಿ ಅಥವಾ ಟ್ಯಾಬ್ಲೆಟ್‌ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"ಪರದೆಯನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಲಾಕ್ ಮಾಡುತ್ತದೆ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಟೈಪ್ ಮಾಡಿದರೆ ನಿಮ್ಮ ಎಲ್ಲಾ Android TV ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
@@ -871,7 +869,7 @@
     <string name="policylab_disableCamera" msgid="5749486347810162018">"ಕ್ಯಾಮರಾಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="policydesc_disableCamera" msgid="3204405908799676104">"ಎಲ್ಲಾ ಸಾಧನ ಕ್ಯಾಮರಾಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
     <string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"ಕೆಲವು ಸ್ಕ್ರೀನ್ ಲಾಕ್ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"ಕೆಲವು ಪರದೆ ಲಾಕ್‌ನ ವೈಶಿಷ್ಟ್ಯಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"ಕೆಲವು ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ನ ವೈಶಿಷ್ಟ್ಯಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
   <string-array name="phoneTypes">
     <item msgid="8996339953292723951">"ಮನೆ"</item>
     <item msgid="7740243458912727194">"ಮೊಬೈಲ್"</item>
@@ -1410,7 +1408,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ಅನ್‌ಲಾಗ್ ಆಡಿಯೋ ಆ್ಯಕ್ಸೆಸರಿ ಪತ್ತೆಯಾಗಿದೆ"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ಲಗತ್ತಿಸಲಾದ ಸಾಧನವು ಈ ಫೋನಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಕನೆಕ್ಟ್‌ ಆಗಿದೆ"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ಡೀಬಗಿಂಗ್ ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
@@ -1680,8 +1678,8 @@
     <string name="media_route_status_available" msgid="1477537663492007608">"ಲಭ್ಯ"</string>
     <string name="media_route_status_not_available" msgid="480912417977515261">"ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="media_route_status_in_use" msgid="6684112905244944724">"ಬಳಕೆಯಲ್ಲಿದೆ"</string>
-    <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"ಬಿಲ್ಟ್-ಇನ್ ಪರದೆ"</string>
-    <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI ಪರದೆ"</string>
+    <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"ಬಿಲ್ಟ್-ಇನ್ ಸ್ಕ್ರೀನ್"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI ಸ್ಕ್ರೀನ್"</string>
     <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"ಓವರ್‌ಲೇ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", ಸುರಕ್ಷಿತ"</string>
@@ -2409,7 +2407,7 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಅನ್ನು <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ಗೆ ಸೆಟ್ ಮಾಡಲಾಗಿದೆ… ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="profile_label_private" msgid="6463418670715290696">"ಖಾಸಗಿ"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"ಪ್ರೈವೆಟ್"</string>
     <string name="profile_label_clone" msgid="769106052210954285">"ಕ್ಲೋನ್"</string>
     <string name="profile_label_work" msgid="3495359133038584618">"ಕೆಲಸ"</string>
     <string name="profile_label_work_2" msgid="4691533661598632135">"ಕೆಲಸ 2"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d63d43e..59af8fb 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"앱이 근처의 초광대역 기기 간 상대적 위치를 파악하도록 허용"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"근처 Wi‑Fi 기기와 상호작용"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"앱이 광역 신호를 보내 근처에 있는 Wi‑Fi 기기의 상대적인 위치를 확인하고 연결할 수 있도록 허용합니다."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"근처 기기 간 상대 위치 파악"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"앱이 근처 기기 간 상대 위치를 파악하도록 허용"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"기본 NFC 결제 서비스 정보"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"앱이 등록된 AID와 경로 목적지 같은 기본 NFC 결제 서비스 정보를 확인하도록 허용합니다."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"NFC(Near Field Communication) 제어"</string>
@@ -659,7 +657,7 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"화면 잠금 사용"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"계속하려면 화면 잠금용 사용자 인증 정보를 입력하세요"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"센서를 세게 누르세요"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"지문을 인식할 수 없습니다. 다시 시도해 주세요"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"지문 센서를 닦은 후 다시 시도해 보세요."</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"센서를 닦은 후 다시 시도해 보세요."</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"센서를 세게 누르세요"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index e09036a..cbb0a13 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Колдонмо кең тилкелүү тармак аркылуу туташа турган жакын жердеги түзмөктөрдү аныктай алат"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Жакын жердеги Wi‑Fi түзмөктөрүнө байланышуу"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Колдонмо жакын жердеги Wi-Fi түзмөктөргө туташып, алардын жайгашкан жерин аныктап, ар кандай нерселерди өткөрө алат."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"жакын жердеги түзмөктөр арасындагы салыштырмалуу абалды аныктоо"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Колдонмого жакын жердеги түзмөктөр ортосундагы салыштырмалуу абалды аныктоого уруксат берүү"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Тандалган NFC төлөм кызматы жөнүндө маалымат"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Колдонмого катталган жардам же көздөлгөн жерге маршрут сыяктуу тандалган nfc төлөм кызматы жөнүндө маалыматты алууга уруксат берүү."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication көзөмөлү"</string>
@@ -2409,7 +2407,7 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Баскычтопко төмөнкү калып коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Өзгөртүү үчүн басыңыз."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физикалык баскычтоптор конфигурацияланды"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Баскычтопторду көрүү үчүн басыңыз"</string>
-    <string name="profile_label_private" msgid="6463418670715290696">"Купуя"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Жеке"</string>
     <string name="profile_label_clone" msgid="769106052210954285">"Клон"</string>
     <string name="profile_label_work" msgid="3495359133038584618">"Жумуш"</string>
     <string name="profile_label_work_2" msgid="4691533661598632135">"Жумуш 2"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Күйгүзүү"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Артка кайтуу"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Кезекте турат..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Спутник SOS эми жеткиликтүү"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Мобилдик Интернет же Wi-Fi тармагы жок болсо, кырсыктаганда жардамга келчү кызматтарга билдирүү жөнөтө аласыз. Google Messages демейки жазышуу колдонмоңуз болушу керек."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Спутник SOS колдоого алынбайт"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Бул түзмөктө спутник SOS колдоого алынбайт"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Спутник SOS туураланган жок"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Интернет байланышыңызды текшерип, кайра тууралап көрүңүз"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Спутник SOS жеткиликсиз"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Спутник SOS бул өлкөдө же аймакта жеткиликсиз"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Спутник SOS туураланган жок"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Спутник аркылуу жазышуу үчүн Google Messages кызматын демейки жазышуу колдонмосу катары тандаңыз"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Спутник SOS жеткиликсиз"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Бул өлкөдө же аймакта спутник SOS функциясынын жеткиликтүүлүгүн текшерүү үчүн жайгашкан жерди аныктоо параметрлерин күйгүзүңүз"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Спутник аркылуу байланышуу жеткиликтүү"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Мобилдик же Wi-Fi тармагы жок болсо, спутник аркылуу жазыша аласыз. Google Messages демейки жазышуу колдонмоңуз болушу керек."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Спутник аркылуу байланышуу колдоого алынбайт"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Бул түзмөктө спутник аркылуу байланышуу колдоого алынбайт"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Спутник аркылуу байланышуу туураланган жок"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Интернет байланышыңызды текшерип, кайра тууралап көрүңүз"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Спутник аркылуу байланышуу жеткиликсиз"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Бул өлкөдө же аймакта спутник аркылуу байланышуу жеткиликсиз"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Спутник аркылуу байланышуу туураланган жок"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Спутник аркылуу жазышуу үчүн Google Messages кызматын демейки жазышуу колдонмосу катары тандаңыз"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Спутник аркылуу байланышуу жеткиликсиз"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Бул өлкөдө же аймакта спутник аркылуу байланышуу функциясынын жеткиликтүүлүгүн текшерүү үчүн жайгашкан жерди аныктоо параметрлерин күйгүзүңүз"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Манжа изи менен ачуу функциясын кайра тууралаңыз"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> мындан ары таанылбайт."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> мындан ары таанылбайт."</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index a9ebcd7..5af4a84 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ອະນຸຍາດໃຫ້ແອັບກຳນົດຕຳແໜ່ງທີ່ສຳພັນກັນລະຫວ່າງອຸປະກອນ Ultra-Wideband ທີ່ຢູ່ໃກ້ຄຽງ"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ໂຕ້ຕອບກັບອຸປະກອນ Wi‑Fi ທີ່ຢູ່ໃກ້ຄຽງ"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ອະນຸຍາດໃຫ້ແອັບໂຄສະນາ, ເຊື່ອມຕໍ່ ແລະ ກຳນົດຕຳແໜ່ງສຳພັນຂອງອຸປະກອນ Wi-Fi ທີ່ຢູ່ໃກ້ຄຽງໄດ້"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"ກຳນົດຕຳແໜ່ງທີ່ກ່ຽວຂ້ອງກັນລະຫວ່າງອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"ອະນຸຍາດໃຫ້ແອັບກຳນົດຕຳແໜ່ງທີ່ກ່ຽວຂ້ອງກັນລະຫວ່າງອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ຂໍ້ມູນບໍລິການການຈ່າຍເງິນ NFC ທີ່ຕ້ອງການ"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ອະນຸຍາດໃຫ້ແອັບຮັບຂໍ້ມູນບໍລິການການຈ່າຍເງິນ NFC ທີ່ຕ້ອງການໄດ້ ເຊັ່ນ: ການຊ່ວຍເຫຼືອແບບລົງທະບຽນ ແລະ ປາຍທາງເສັ້ນທາງ."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ຄວບຄຸມ Near Field Communication"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 21fddd0..cb7cc89 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -614,10 +614,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Leisti programai nustatyti apytikslę netoliese esančių itin plataus dažnio juostos įrenginių poziciją"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"sąveikauti su „Wi‑Fi“ įrenginiais netoliese"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Leidžiama programai reklamuoti, prisijungti ir nustatyti apytikslę netoliese esančių „Wi-Fi“ įrenginių poziciją"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"nustatyti apytikslę netoliese esančių įrenginių poziciją"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Leisti programai nustatyti apytikslę netoliese esančių įrenginių poziciją"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Pageidaujama ARL mokėjimo paslaugos informacija"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Programai leidžiama gauti pageidaujamą ARL mokamos paslaugos informaciją, pvz., užregistruotą pagalbą ir maršrutų tikslus."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"valdyti artimo lauko perdavimą (angl. „Near Field Communication“)"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 15ee04a..b72fb07 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Atļaut lietotnei noteikt relatīvo atrašanās vietu starp tuvumā esošām ultraplatjoslas ierīcēm"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Mijiedarbība ar tuvumā esošām Wi‑Fi ierīcēm"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Atļauj lietotnei nodot datus tuvumā esošām Wi‑Fi ierīcē, izveidot savienojumu ar tām un noteikt to relatīvo pozīciju."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"atrašanās vietas noteikšana relatīvi ierīcēm"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Atļaut lietotnei noteikt relatīvo atrašanās vietu starp tuvumā esošām ierīcēm"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informācija par vēlamo NFC maksājumu pakalpojumu"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ļauj lietotnei iegūt informāciju par vēlamo NFC maksājumu pakalpojumu, piemēram, par reģistrētajiem lietojumprogrammu ID un maršruta galamērķi."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrolē tuvlauka saziņu"</string>
@@ -2436,54 +2434,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ieslēgt"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Atpakaļ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Gaida…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Funkcija “Satelīta SOS” tagad ir pieejama"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Varat nosūtīt ziņojumu ārkārtas palīdzības dienestiem, ja nav pieejams ne mobilais, ne Wi-Fi tīkls. Lietotnei Google ziņojumi ir jābūt iestatītai kā noklusējuma ziņojumapmaiņas lietotnei."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Funkcija “Satelīta SOS” netiek atbalstīta"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Šajā ierīcē funkcija Satelīta SOS netiek atbalstīta."</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Funkcija “Satelīta SOS” nav iestatīta"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Pārliecinieties, vai ir izveidots savienojums ar internetu, un vēlreiz mēģiniet veikt iestatīšanu."</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Funkcija “Satelīta SOS” nav pieejama"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Šajā valstī vai reģionā funkcija “Satelīta SOS” nav pieejama."</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Funkcija “Satelīta SOS” nav iestatīta"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Lai varētu sūtīt ziņojumus, izmantojot satelītu, iestatiet lietotni Google ziņojumi kā noklusējuma ziņojumapmaiņas lietotni."</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Funkcija “Satelīta SOS” nav pieejama"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Lai pārbaudītu, vai funkcija “Satelīta SOS” ir pieejama šajā valstī vai reģionā, ieslēdziet atrašanās vietas iestatījumus."</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satelīta ziņojumapmaiņa ir pieejama"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Varat sūtīt ziņojumus, izmantojot satelītu, ja nav pieejams ne mobilais, ne Wi-Fi tīkls. Lietotnei Google ziņojumi ir jābūt iestatītai kā noklusējuma ziņojumapmaiņas lietotnei."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelīta ziņojumapmaiņa netiek atbalstīta"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Šajā ierīcē satelīta ziņojumapmaiņa netiek atbalstīta."</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelīta ziņojumapmaiņa nav iestatīta"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Pārliecinieties, vai ir izveidots savienojums ar internetu, un vēlreiz mēģiniet veikt iestatīšanu."</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelīta ziņojumapmaiņa nav pieejama"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Šajā valstī vai reģionā satelīta ziņojumapmaiņa nav pieejama."</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelīta ziņojumapmaiņa nav iestatīta"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Lai varētu sūtīt ziņojumus, izmantojot satelītu, iestatiet lietotni Google ziņojumi kā noklusējuma ziņojumapmaiņas lietotni."</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelīta ziņojumapmaiņa nav pieejama"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Lai pārbaudītu, vai satelīta ziņojumapmaiņa ir pieejama šajā valstī vai reģionā, ieslēdziet atrašanās vietas iestatījumus."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Pirksta nospiedumu (<xliff:g id="FINGERPRINT">%s</xliff:g>) vairs nevar atpazīt."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Pirkstu nospiedumus (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) vairs nevar atpazīt."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index b518772..0b0e3ef 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дозволува апликацијата да ја одреди релативната положба помеѓу уредите со ултраширок појас во близина"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"да има интеракција со уредите со Wi‑Fi во близина"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Дозволува апликацијата да рекламира, да се поврзува и да ја одредува релативната положба на уреди со Wi‑Fi во близина"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"да ја одредува рел. положба меѓу уреди во близина"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Дозволува апликацијата да ја одредува релативната положба меѓу уредите во близина"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информации за претпочитаната услуга за плаќање преку NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволува апликацијата да добие информации за претпочитаната услуга за плаќање преку NFC, како регистрирани помагала и дестинација на маршрутата."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"контролирај комуникација на блиско поле"</string>
@@ -2409,9 +2407,9 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Распоредот на тастатурата е поставен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Допрете за да промените."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физичките тастатури се конфигурирани"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Допрете за да ги видите тастатурите"</string>
-    <string name="profile_label_private" msgid="6463418670715290696">"Приватно"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Приватен"</string>
     <string name="profile_label_clone" msgid="769106052210954285">"Клониран профил"</string>
-    <string name="profile_label_work" msgid="3495359133038584618">"Работно"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Работен"</string>
     <string name="profile_label_work_2" msgid="4691533661598632135">"Работен профил 2"</string>
     <string name="profile_label_work_3" msgid="4834572253956798917">"Работен профил 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Профил за тестирање"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Вклучи"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Врати се назад"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Во фаза на чекање…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"„Сателитски SOS“ сега е достапна"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Може да разменувате пораки со службите за итни случаи ако нема мобилна или Wi-Fi мрежа. Google Messages мора да биде ваша стандардна апликација за разменување пораки."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"„Сателитски SOS“ не е поддржана"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"„Сателитски SOS“ не е поддржана на уредов"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"„Сателитски SOS“ не е поставена"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Проверете дали сте поврзани на интернет и обидете се да поставите повторно"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"„Сателитски SOS“ не е достапна"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"„Сателитски SOS“ не е достапна во земјава или регионов"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"„Сателитски SOS“ не е поставена"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"За да разменувате пораки преку сателит, поставете ја Google Messages како стандардна апликација за разменување пораки"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"„Сателитски SOS“ не е достапна"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"За да проверите дали „Сателитски SOS“ е достапна во земјава или регионов, вклучете ги поставките за локација"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Достапна е „Сателитска размена на пораки“"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Може да разменувате пораки преку сателит ако нема мобилна или Wi-Fi мрежа. Google Messages мора да биде ваша стандардна апликација за разменување пораки."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"„Сателитска размена на пораки“ не е поддржана"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"„Сателитска размена на пораки“ не е поддржана на уредов"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"„Сателитска размена на пораки“ не е поставена"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Проверете дали сте поврзани на интернет и обидете се да поставите повторно"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"„Сателитска размена на пораки“ не е достапна"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"„Сателитска размена на пораки“ не е достапна во земјава или регионов"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"„Сателитска размена на пораки“ не е поставена"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"За да разменувате пораки преку сателит, поставете ја Google Messages како стандардна апликација за разменување пораки"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"„Сателитска размена на пораки“ не е достапна"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"За да проверите дали е достапна „Сателитска размена на пораки“ во земјава или регионов, вклучете ги поставките за локација"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поставете „Отклучување со отпечаток“ повторно"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> веќе не може да се препознае."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> веќе не може да се препознаат."</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index aabeb9b..fe5974b 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"സമീപമുള്ള അൾട്രാ-വെെഡ്ബാൻഡ് ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"സമീപമുള്ള വൈഫൈ ഉപകരണങ്ങളുമായി ഇടപഴകുക"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"സമീപമുള്ള വൈഫൈ ഉപകരണങ്ങൾ കാണിക്കാനും അവയിലേക്ക് കണക്റ്റ് ചെയ്യാനും അവയുടെ ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാനും ആപ്പിനെ അനുവദിക്കൂ"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"സമീപമുള്ള ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കൂ"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"സമീപമുള്ള ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"റൂട്ട് ലക്ഷ്യസ്ഥാനം, രജിസ്‌റ്റർ ചെയ്തിരിക്കുന്ന സഹായങ്ങൾ എന്നിവ പോലുള്ള, തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ ലഭിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"സമീപ ഫീൽഡുമായുള്ള ആശയവിനിമയം നിയന്ത്രിക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index c625d31..376a033 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Аппад ойролцоох ультра өргөн зурвасын төхөөрөмжүүдийн хоорондох холбоотой байрлалыг тодорхойлохыг зөвшөөрөх"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ойролцоох Wi-Fi төхөөрөмжүүдтэй харилцах"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Аппад ойролцоох Wi-Fi төхөөрөмжүүдтэй холбоотой байрлалыг мэдэгдэх, холбох, тодорхойлохыг зөвшөөрнө"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"ойр төхөөрөмжүүдийн хоорондох харьцангуй байрлалыг тодорхойл"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Аппад ойролцоох төхөөрөмжүүдийн хоорондох харьцангуй байрлалыг тодорхойлохыг зөвшөөрнө үү"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сонгосон NFC төлбөрийн үйлчилгээний мэдээлэл"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Бүртгүүлсэн төхөөрөмж болон маршрутын хүрэх цэг зэрэг сонгосон nfc төлбөрийн үйлчилгээний мэдээллийг авахыг аппад зөвшөөрдөг."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ойролцоо талбарын холбоог удирдах"</string>
@@ -917,7 +915,7 @@
   </string-array>
     <string name="phoneTypeCustom" msgid="5120365721260686814">"Тусгай"</string>
     <string name="phoneTypeHome" msgid="3880132427643623588">"Гэрийн"</string>
-    <string name="phoneTypeMobile" msgid="1178852541462086735">"Мобайл"</string>
+    <string name="phoneTypeMobile" msgid="1178852541462086735">"Гар утас"</string>
     <string name="phoneTypeWork" msgid="6604967163358864607">"Ажлын"</string>
     <string name="phoneTypeFaxWork" msgid="6757519896109439123">"Ажлын факс"</string>
     <string name="phoneTypeFaxHome" msgid="6678559953115904345">"Гэрийн Факс"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Асаах"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Буцах"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Хүлээгдэж буй..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Хиймэл дагуул SOS одоо боломжтой боллоо"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Та хөдөлгөөнт холбооны эсвэл Wi-Fi сүлжээ байхгүй бол яаралтай тусламжийн үйлчилгээ рүү мессеж бичих боломжтой. Google Мессеж таны өгөгдмөл мессеж апп байх ёстой."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Хиймэл дагуул SOS-г дэмждэггүй"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Хиймэл дагуул SOS-г энэ төхөөрөмж дээр дэмждэггүй"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Хиймэл дагуул SOS-г тохируулаагүй байна"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Та интернэтэд холбогдсон эсэхийг шалгаад, тохируулгыг дахин оролдоно уу"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Хиймэл дагуул SOS боломжгүй байна"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Хиймэл дагуул SOS энэ улс эсвэл бүс нутагт боломжгүй"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Хиймэл дагуул SOS-г тохируулаагүй байна"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Хиймэл дагуулаар дамжин мессеж бичихийн тулд Google Мессежийг өгөгдмөл мессеж аппаараа тохируулна уу"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Хиймэл дагуул SOS боломжгүй байна"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Энэ улс эсвэл бүс нутагт Хиймэл дагуул SOS боломжтой эсэхийг шалгахын тулд байршлын тохиргоог асаана уу"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Хиймэл дагуулаар дамжин мессеж бичих боломжтой"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Хэрэв хөдөлгөөнт холбооны эсвэл Wi-Fi сүлжээ байхгүй бол та хиймэл дагуулаар дамжин мессеж бичих боломжтой. Google Мессеж таны өгөгдмөл мессеж апп байх ёстой."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Хиймэл дагуулаар дамжин мессеж бичихийг дэмждэггүй"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Хиймэл дагуулаар дамжин мессеж бичихийг энэ төхөөрөмж дээр дэмждэггүй"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Хиймэл дагуулаар дамжин мессеж бичихийг тохируулаагүй"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Та интернэтэд холбогдсон эсэхийг шалгаад, тохируулгыг дахин оролдоно уу"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Хиймэл дагуулаар дамжин мессеж бичих боломжгүй"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Энэ улс эсвэл бүс нутагт хиймэл дагуулаар дамжин мессеж бичих боломжгүй"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Хиймэл дагуулаар дамжин мессеж бичихийг тохируулаагүй"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Хиймэл дагуулаар дамжин мессеж бичихийн тулд Google Мессежийг өгөгдмөл мессеж аппаараа тохируулна уу"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Хиймэл дагуулаар дамжин мессеж бичих боломжгүй"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Энэ улс эсвэл бүс нутагт хиймэл дагуулаар дамжин мессеж бичих боломжтой эсэхийг шалгахын тулд байршлын тохиргоог асаана уу"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>-г цаашид таних боломжгүй."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-г цаашид таних боломжгүй."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 3240d59..e640f72 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ॲपला जवळच्या अल्ट्रा-वाइडबँड डिव्हाइसदरम्यानचे संबंधित स्थान निर्धारित करण्याची अनुमती द्या"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"जवळपासच्या वाय-फाय डिव्हाइसशी संवाद साधा"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ॲपला जाहिरात करण्याची, कनेक्ट करण्याची आणि जवळपासच्या वाय-फाय डिव्हाइसचे संबंधित स्थान निर्धारित करण्याची परवानगी देते"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"जवळपासच्या डिव्हाइसदरम्यान संबंधित स्थान निश्चित करा"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"ॲपला जवळच्या डिव्हाइसदरम्यानचे संबंधित स्थान निर्धारित करण्याची अनुमती द्या"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"प्राधान्यकृत NFC पेमेंट सेवा माहिती"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"नोंदणीकृत एड्स आणि मार्ग गंतव्यस्थान सारखी प्राधान्यकृत एनएफसी पेमेंट सेवेची माहिती मिळवण्यासाठी अ‍ॅपला अनुमती देते."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"फील्ड जवळील कम्युनिकेशन नियंत्रित करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index bd780ae..3946ac1 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Benarkan apl menentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"berinteraksi dengan peranti Wi-Fi berdekatan"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Membenarkan apl mengiklankan, menyambung dan menentukan kedudukan relatif peranti Wi-Fi berdekatan"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"tentukan kedudukan relatif antara peranti berdekatan"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Benarkan apl menentukan kedudukan relatif antara peranti berdekatan"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maklumat Perkhidmatan Pembayaran NFC Pilihan"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Membenarkan apl mendapatkan maklumat perkhidmatan pembayaran nfc pilihan seperti bantuan berdaftar dan destinasi laluan."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"mengawal Komunikasi Medan Dekat"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index e4c2aca..fc00725 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"အနီးရှိ ‘အလွန်ကျယ်ပြန့်သော လှိုင်းအလျားသုံးစက်များ’ ကြား မှန်းခြေနေရာကို သတ်မှတ်ရန် အက်ပ်ကို ခွင့်ပြုမည်"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"အနီးရှိ Wi-Fi စက်များနှင့် ပြန်လှန်တုံ့ပြန်ခြင်း"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ကြော်ငြာရန်၊ ချိတ်ဆက်ရန်နှင့် အနီးတစ်ဝိုက်ရှိ Wi-Fi စက်များ၏ နေရာကို သတ်မှတ်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"အနီးတစ်ဝိုက်ရှိ စက်များကြား ဆက်စပ်နေရာသတ်မှတ်ခြင်း"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"အနီးတစ်ဝိုက်ရှိ စက်များကြား ဆက်စပ်နေရာသတ်မှတ်ရန် အက်ပ်ကိုခွင့်ပြုသည်"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ဦးစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များ"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"အက်ပ်အား ဦစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များဖြစ်သည့် မှတ်ပုံတင်ထားသော အကူအညီများနှင့် သွားလာရာ လမ်းကြောင်းတို့ကို ရယူရန် ခွင့်ပြုသည်။"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communicationအား ထိန်းချုပ်ရန်"</string>
@@ -2446,7 +2444,7 @@
     <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS ကို စနစ်ထည့်သွင်းမထားပါ"</string>
     <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"ဂြိုဟ်တုမှတစ်ဆင့် မက်ဆေ့ဂျ်ပို့ရန် Google Messages ကို သင်၏ မက်ဆေ့ဂျ်ပို့ရန် မူရင်းအက်ပ်အဖြစ် သတ်မှတ်ပါ"</string>
     <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS မရနိုင်ပါ"</string>
-    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"satellite SOS ကို ဤနိုင်ငံ (သို့) ဒေသတွင် ရနိုင်ခြင်းရှိ၊ မရှိ စစ်ဆေးရန် တည်နေရာပြ ဆက်တင်များကို ဖွင့်ပါ"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Satellite SOS ကို ဤနိုင်ငံ (သို့) ဒေသတွင် ရနိုင်ခြင်းရှိ၊ မရှိ စစ်ဆေးရန် တည်နေရာပြ ဆက်တင်များကို ဖွင့်ပါ"</string>
     <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"ဂြိုဟ်တုမှတစ်ဆင့် မက်ဆေ့ဂျ်ပို့ခြင်း ရနိုင်သည်"</string>
     <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက် မရှိသည့်အခါ ဂြိုဟ်တုမှတစ်ဆင့် မက်ဆေ့ဂျ်ပို့နိုင်သည်။ Google Messages သည် သင်၏ မူရင်းမက်ဆေ့ဂျ်ပို့ရန်အက်ပ် ဖြစ်ရမည်။"</string>
     <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"ဂြိုဟ်တုမှတစ်ဆင့် မက်ဆေ့ဂျ်ပို့ခြင်းကို ပံ့ပိုးမထားပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index ec4cd96..c1095d3 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"tillate at appen fastslår den relative posisjonen mellom enheter i nærheten som bruker ultrabredbånd"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"samhandle med wifi-enheter i nærheten"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lar appen annonsere, koble til og fastslå den relative posisjonen til wifi-enheter i nærheten"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"Relativ posisjon mellom enheter i nærheten"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Tillat at appen avgjør den relative posisjonen mellom enheter i nærheten"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasjon om prioritert NFC-betalingstjeneste"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gir appen tilgang til informasjon om prioritert NFC-betalingstjeneste, for eksempel registrerte hjelpemidler og destinasjon."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontroller overføring av data med NFC-teknologi"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Slå på"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Gå tilbake"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Venter …"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Nå er SOS-alarm via satellitt tilgjengelig"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Du kan sende meldinger til nødtjenestene hvis du ikke har mobil- eller wifi-dekning. Google Meldinger må være standardappen for meldinger."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS-alarm via satellitt støttes ikke"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS-alarm via satellitt støttes ikke på denne enheten"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS-alarm via satellitt er ikke konfigurert"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Sjekk at du er koblet til internett, og prøv konfigureringen på nytt"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS-alarm via satellitt er ikke tilgjengelig"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS-alarm via satellitt er ikke tilgjengelig i dette landet eller denne regionen"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS-alarm via satellitt er ikke konfigurert"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"For å sende meldinger via satellitt må du angi Google Meldinger som standardapp for meldinger"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS-alarm via satellitt er ikke tilgjengelig"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"For å sjekke om SOS-alarm via satellitt er tilgjengelig i dette landet eller denne regionen, slå på posisjonsinnstillingene"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satellittmeldinger er tilgjengelige"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Du kan sende meldinger via satellitt hvis du ikke har mobil- eller wifi-dekning. Google Meldinger må være standardappen for meldinger."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satellittmeldinger støttes ikke"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satellittmeldinger støttes ikke på denne enheten"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satellittmeldinger er ikke konfigurert"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Sjekk at du er koblet til internett, og prøv konfigureringen på nytt"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satellittmeldinger er ikke tilgjengelige"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satellittmeldinger er ikke tilgjengelige i dette landet eller denne regionen"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satellittmeldinger er ikke konfigurert"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"For å sende meldinger via satellitt må du angi Google Meldinger som standardapp for meldinger"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satellittmeldinger er ikke tilgjengelige"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"For å sjekke om satellittmeldinger er tilgjengelige i dette landet eller denne regionen, slå på posisjonsinnstillinger"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer opplåsingen med fingeravtrykk på nytt"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> gjenkjennes ikke lenger."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> gjenkjennes ikke lenger."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 0dc0bd3..beda131 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"यो एपलाई नजिकै रहेका अल्ट्रा-वाइडब्यान्ड चल्ने डिभाइसहरूबिचको तुलनात्मक स्थान पत्ता लगाउन दिनुहोस्"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Wi-Fi चल्ने नजिकै रहेका डिभाइसहरूमा चलाउन दिन्छ"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"यसले एपलाई Wi-Fi चल्ने नजिकै रहेका डिभाइसहरूमा विज्ञापन गर्न, कनेक्ट गर्न र सापेक्ष स्थिति निर्धारण गर्न दिन्छ"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"नजिकै रहेका डिभाइसहरूबिचको तुलनात्मक स्थान पत्ता लगाउने"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"यो एपलाई नजिकै रहेका डिभाइसहरूबिचको तुलनात्मक स्थान पत्ता लगाउन दिनुहोस्"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC भुक्तानी सेवासम्बन्धी रुचाइएको जानकारी"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"यसले एपलाई दर्ता गरिएका सहायता तथा मार्गको गन्तव्य जस्ता रुचाइएका NFC भुक्तानी सेवासम्बन्धी जानकारी प्राप्त गर्न दिन्छ।"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"नजिक क्षेत्र संचार नियन्त्रणहरू"</string>
@@ -2173,8 +2171,8 @@
     <string name="mime_type_audio_ext" msgid="2615491023840514797">"<xliff:g id="EXTENSION">%1$s</xliff:g> अडियो"</string>
     <string name="mime_type_video" msgid="7071965726609428150">"भिडियो"</string>
     <string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> भिडियो"</string>
-    <string name="mime_type_image" msgid="2134307276151645257">"छवि"</string>
-    <string name="mime_type_image_ext" msgid="5743552697560999471">"<xliff:g id="EXTENSION">%1$s</xliff:g> छवि"</string>
+    <string name="mime_type_image" msgid="2134307276151645257">"फोटो"</string>
+    <string name="mime_type_image_ext" msgid="5743552697560999471">"<xliff:g id="EXTENSION">%1$s</xliff:g> फोटो"</string>
     <string name="mime_type_compressed" msgid="8737300936080662063">"अभिलेख"</string>
     <string name="mime_type_compressed_ext" msgid="4775627287994475737">"<xliff:g id="EXTENSION">%1$s</xliff:g> अभिलेख"</string>
     <string name="mime_type_document" msgid="3737256839487088554">"कागजात"</string>
@@ -2211,7 +2209,7 @@
     <string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad को बिचको बटन"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> लाई प्रतिबन्धित बाल्टीमा राखियो"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
-    <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"छवि पठाइयो"</string>
+    <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"फोटो पठाइयो"</string>
     <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"वार्तालाप"</string>
     <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"सामूहिक वार्तालाप"</string>
     <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
@@ -2409,7 +2407,7 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"किबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> भाषामा सेट गरिएको छ… बदल्न ट्याप गर्नुहोस्।"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"भौतिक किबोर्डहरू कन्फिगर गरिएका छन्"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"किबोर्डहरू हेर्न ट्याप गर्नुहोस्"</string>
-    <string name="profile_label_private" msgid="6463418670715290696">"निजी"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"निजी स्पेस"</string>
     <string name="profile_label_clone" msgid="769106052210954285">"क्लोन"</string>
     <string name="profile_label_work" msgid="3495359133038584618">"कार्य"</string>
     <string name="profile_label_work_2" msgid="4691533661598632135">"कार्य प्रोफाइल २"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index e553347..48c8be1 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"De app toestaan om de relatieve positie tussen ultrabreedbandapparaten in de buurt te bepalen"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactie met wifi-apparaten in de buurt"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Hiermee kan de app uitzenden, verbindingen maken en de relatieve positie bepalen van wifi-apparaten in de buurt"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"relatieve positie tussen apparaten in de buurt bepalen"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Sta toe dat de app de relatieve positie tussen apparaten in de buurt bepaalt"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informatie over voorkeursservice voor NFC-betaling"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Hiermee kun je zorgen dat de app informatie krijgt over de voorkeursservice voor NFC-betaling, zoals geregistreerde hulpmiddelen en routebestemmingen."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication regelen"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 2515bb5..a99afa5 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ଆଖପାଖର ଅଲଟ୍ରା-ୱାଇଡବ୍ୟାଣ୍ଡ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପେକ୍ଷିକ ଅବସ୍ଥିତିକୁ ନିର୍ଦ୍ଧାରଣ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ଆଖପାଖର ୱାଇ-ଫାଇ ଡିଭାଇସଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରନ୍ତୁ"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ଆଖପାଖର ୱାଇ-ଫାଇ ଡିଭାଇସରେ ବିଜ୍ଞାପନ ଦେବା, ତା ସହ ସଂଯୋଗ କରିବା ଓ ତା’ର ଆପେକ୍ଷିକ ଅବସ୍ଥିତି ନିର୍ଦ୍ଧାରଣ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"ଆଖପାଖର ଡିଭାଇସ ମଧ୍ୟରେ ଆପେକ୍ଷିକ ଅବସ୍ଥିତିକୁ ନିର୍ଦ୍ଧାରଣ କର"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପେକ୍ଷିକ ଅବସ୍ଥିତିକୁ ନିର୍ଦ୍ଧାରଣ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ପସନ୍ଦର NFC ପେମେଣ୍ଟ ସେବା ସୂଚନା"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ପଞ୍ଜିକୃତ ଯନ୍ତ୍ର ଏବଂ ମାର୍ଗ ଲକ୍ଷସ୍ଥଳ ପରି ପସନ୍ଦର nfc ପେମେଣ୍ଟ ସେବା ସୂଚନା ପାଇବାକୁ ଆପ୍ ଅନୁମତି କରିଥାଏ।"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ନିଅର୍ ଫିଲ୍ଡ କମ୍ୟୁନିକେଶନ୍ ଉପରେ ନିୟନ୍ତ୍ରଣ ରଖନ୍ତୁ"</string>
@@ -1993,7 +1991,7 @@
     <string name="importance_from_user" msgid="2782756722448800447">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ପ୍ରମୁଖତା ଆପଣ ସେଟ୍‍ କରନ୍ତି।"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ସମ୍ପୃକ୍ତ ଲୋକଙ୍କ କାରଣରୁ ଏହା ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ ଅଟେ।"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"କଷ୍ଟମ୍ ଆପ୍ ବିଜ୍ଞପ୍ତି"</string>
-    <string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ (ପୂର୍ବରୁ ଏହି ଆକାଉଣ୍ଟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନାମରେ ଅଛି) ଅନୁମତି ଦେବେ?"</string>
+    <string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ୟୁଜର ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ (ପୂର୍ବରୁ ଏହି ଆକାଉଣ୍ଟ ୟୁଜରଙ୍କ ନାମରେ ଅଛି) ଅନୁମତି ଦେବେ?"</string>
     <string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ୟୁଜର ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
     <string name="supervised_user_creation_label" msgid="6884904353827427515">"ନିରୀକ୍ଷିତ ୟୁଜର ଯୋଗ କରନ୍ତୁ"</string>
     <string name="language_selection_title" msgid="52674936078683285">"ଏକ ଭାଷା ଯୋଗ କରନ୍ତୁ"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ପଛକୁ ଫେରନ୍ତୁ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"ବାକି ଅଛି…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"ବର୍ତ୍ତମାନ ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ଅଛି"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"କୌଣସି ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ନଥିଲେ ଆପଣ ଜରୁରୀକାଳୀନ ସେବାଗୁଡ଼ିକୁ ମେସେଜ କରିପାରିବେ। Google Messages ଆପଣଙ୍କର ଡିଫଲ୍ଟ ମେସେଜିଂ ଆପ ହେବା ଆବଶ୍ୟକ।"</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"ସେଟେଲାଇଟ SOS ସପୋର୍ଟ କରୁନାହିଁ"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"ଏହି ଡିଭାଇସରେ ସେଟେଲାଇଟ SOS ସପୋର୍ଟ କରୁନାହିଁ"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"ସେଟେଲାଇଟ SOS ସେଟ ଅପ କରାଯାଇନାହିଁ"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"ଆପଣ ଇଣ୍ଟର୍ନେଟ ସହ କନେକ୍ଟ ଅଛନ୍ତି ବୋଲି ସୁନିଶ୍ଚିତ କରି ପୁଣି ସେଟଅପ କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"ଏହି ଦେଶ କିମ୍ବା ଅଞ୍ଚଳରେ ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"ସେଟେଲାଇଟ SOS ସେଟ ଅପ କରାଯାଇନାହିଁ"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"ସେଟେଲାଇଟ ମାଧ୍ୟମରେ ମେସେଜ କରିବା ପାଇଁ Google Messagesକୁ ଆପଣଙ୍କର ଡିଫଲ୍ଟ ମେସେଜିଂ ଆପ ଭାବେ ସେଟ କରନ୍ତୁ"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"ଏହି ଦେଶ କିମ୍ବା ଅଞ୍ଚଳରେ ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ଅଛି ନା ନାହିଁ ତାହା ଯାଞ୍ଚ କରିବାକୁ ଲୋକେସନ ସେଟିଂସ ଚାଲୁ କରନ୍ତୁ"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ଅଛି"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"କୌଣସି ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ନଥିଲେ ଆପଣ ସେଟେଲାଇଟ ମାଧ୍ୟମରେ ମେସେଜ କରିପାରିବେ। Google Messages ଆପଣଙ୍କର ଡିଫଲ୍ଟ ମେସେଜିଂ ଆପ ହେବା ଆବଶ୍ୟକ।"</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"ସେଟେଲାଇଟ ମେସେଜିଂ ସପୋର୍ଟ କରୁନାହିଁ"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"ଏହି ଡିଭାଇସରେ ସେଟେଲାଇଟ ମେସେଜିଂ ସପୋର୍ଟ କରୁନାହିଁ"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"ସେଟେଲାଇଟ ମେସେଜିଂ ସେଟ ଅପ କରାଯାଇନାହିଁ"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"ଆପଣ ଇଣ୍ଟର୍ନେଟ ସହ କନେକ୍ଟ ଅଛନ୍ତି ବୋଲି ସୁନିଶ୍ଚିତ କରି ପୁଣି ସେଟଅପ କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"ଏହି ଦେଶ କିମ୍ବା ଅଞ୍ଚଳରେ ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"ସେଟେଲାଇଟ ମେସେଜିଂ ସେଟ ଅପ କରାଯାଇନାହିଁ"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"ସେଟେଲାଇଟ ମାଧ୍ୟମରେ ମେସେଜ କରିବା ପାଇଁ Google Messagesକୁ ଆପଣଙ୍କର ଡିଫଲ୍ଟ ମେସେଜିଂ ଆପ ଭାବେ ସେଟ କରନ୍ତୁ"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"ଏହି ଦେଶ କିମ୍ବା ଅଞ୍ଚଳରେ ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ଅଛି ନା ନାହିଁ ତାହା ଯାଞ୍ଚ କରିବାକୁ ଲୋକେସନ ସେଟିଂସ ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 574d991..b4630174 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਅਲਟ੍ਰਾ-ਵਾਈਡਬੈਂਡ ਡੀਵਾਈਸਾਂ ਦੇ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨੂੰ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ਨਜ਼ਦੀਕੀ ਵਾਈ-ਫਾਈ ਡੀਵਾਈਸਾਂ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰੋ"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਵਾਈ-ਫਾਈ ਡੀਵਾਈਸਾਂ \'ਤੇ ਵਿਗਿਆਪਨ ਦੇਣ, ਕਨੈਕਟ ਕਰਨ ਅਤੇ ਉਨ੍ਹਾਂ ਦੀ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨੂੰ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨਿਰਧਾਰਿਤ ਕਰੋ"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਦੇ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨੂੰ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ਐਪ ਨੂੰ ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ ਕਿ ਰਜਿਸਟਰ ਕੀਤੇ ਸਾਧਨ ਅਤੇ ਮੰਜ਼ਿਲ ਰਸਤਾ।"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f267877..4f34fc5 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -614,10 +614,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Zezwól na określanie przez aplikację względnego położenia urządzeń ultraszerokopasmowych w pobliżu"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcje z urządzeniami Wi-Fi w pobliżu"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Zezwala aplikacji na przesyłanie informacji o sobie, łączenie się z urządzeniami Wi‑Fi w pobliżu i określanie ich względnego położenia"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"określanie względnego położenia urządzeń w pobliżu"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Zezwól na określanie przez aplikację względnego położenia urządzeń w pobliżu"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacje o preferowanych usługach płatniczych NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pozwala aplikacji uzyskiwać informacje o preferowanych usługach płatniczych NFC, np. zarejestrowanych pomocach i miejscach docelowych tras."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrolowanie łączności Near Field Communication"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 1719648..a219276 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -323,7 +323,7 @@
     <string name="permgrouplab_location" msgid="1858277002233964394">"Localização"</string>
     <string name="permgroupdesc_location" msgid="1995955142118450685">"acesse o local do dispositivo"</string>
     <string name="permgrouplab_calendar" msgid="6426860926123033230">"Agenda"</string>
-    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
+    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acessar sua agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
     <string name="permgrouplab_storage" msgid="17339216290379241">"Arquivos"</string>
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi-Fi por perto"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app divulgue, faça conexão e determine a posição relativa de dispositivos Wi-Fi por perto."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"determinar o posicionamento relativo entre dispositivos por perto"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Permitir que o app determine o posicionamento relativo entre dispositivos por perto"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index b8fc6a9..a898121 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permita que a app determine a posição relativa entre os dispositivos de banda ultralarga próximos"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi‑Fi próximos"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que a app anuncie, estabeleça ligação e determine a posição relativa de dispositivos Wi‑Fi próximos"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"determinar a posição relativa entre disp. próximos"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Permita que a app determine a posição relativa entre os dispositivos próximos"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações de serviços de pagamento com NFC preferenciais"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a app obtenha informações de serviços de pagamento com NFC preferenciais, como apoios registados e destino da rota."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlo Near Field Communication"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1719648..a219276 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -323,7 +323,7 @@
     <string name="permgrouplab_location" msgid="1858277002233964394">"Localização"</string>
     <string name="permgroupdesc_location" msgid="1995955142118450685">"acesse o local do dispositivo"</string>
     <string name="permgrouplab_calendar" msgid="6426860926123033230">"Agenda"</string>
-    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
+    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acessar sua agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
     <string name="permgrouplab_storage" msgid="17339216290379241">"Arquivos"</string>
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi-Fi por perto"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app divulgue, faça conexão e determine a posição relativa de dispositivos Wi-Fi por perto."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"determinar o posicionamento relativo entre dispositivos por perto"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Permitir que o app determine o posicionamento relativo entre dispositivos por perto"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7843bbe..8b7a296 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite-i aplicației să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"să interacționeze cu dispozitive Wi‑Fi din apropiere"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite aplicației să se conecteze la dispozitive Wi-Fi din apropiere, să transmită anunțuri și să stabilească poziția relativă a acestora"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"stabilește poziția dispozitivelor din apropiere"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Permite-i aplicației să stabilească poziția relativă dintre dispozitivele din apropiere"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informații despre serviciul de plăți NFC preferat"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite aplicației să obțină informații despre serviciul de plăți NFC preferat, de exemplu, identificatorii de aplicație înregistrați și destinația traseului."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlare schimb de date prin Near Field Communication"</string>
@@ -2437,7 +2435,7 @@
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Înapoi"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"În așteptare..."</string>
     <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Funcția SOS prin satelit este acum disponibilă"</string>
-    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Poți să trimiți mesaje serviciilor de urgență dacă nu este disponibilă o rețea mobilă sau Wi-Fi. Mesaje Google trebuie să fie aplicația ta pentru mesaje prestabilită."</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Poți să trimiți mesaje serviciilor de urgență dacă nu este disponibilă o rețea mobilă sau Wi-Fi. Mesaje Google trebuie să fie aplicația ta prestabilită pentru mesaje."</string>
     <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Funcția SOS prin satelit nu este acceptată"</string>
     <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Funcția SOS prin satelit nu este acceptată pe acest dispozitiv"</string>
     <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Funcția SOS prin satelit nu este configurată"</string>
@@ -2445,11 +2443,11 @@
     <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Funcția SOS prin satelit nu este disponibilă"</string>
     <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Funcția SOS prin satelit nu este disponibilă în această țară sau regiune"</string>
     <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Funcția SOS prin satelit nu este configurată"</string>
-    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Pentru a trimite mesaje prin satelit, setează Mesaje Google ca aplicație pentru mesaje prestabilită"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Pentru a trimite mesaje prin satelit, setează Mesaje Google ca aplicație prestabilită pentru mesaje"</string>
     <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Funcția SOS prin satelit nu este disponibilă"</string>
     <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Pentru a verifica dacă funcția SOS prin satelit este disponibilă în această țară sau regiune, activează setările privind locația"</string>
     <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Mesajele prin satelit sunt disponibile"</string>
-    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Dacă nu este disponibilă o rețea mobilă sau Wi-Fi, poți să trimiți mesaje prin satelit. Mesaje Google trebuie să fie aplicația ta pentru mesaje prestabilită."</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Dacă nu este disponibilă o rețea mobilă sau Wi-Fi, poți să trimiți mesaje prin satelit. Mesaje Google trebuie să fie aplicația ta prestabilită pentru mesaje."</string>
     <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Mesajele prin satelit nu sunt acceptate"</string>
     <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Mesajele prin satelit nu sunt acceptate pe acest dispozitiv"</string>
     <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Mesajele prin satelit nu sunt configurate"</string>
@@ -2457,7 +2455,7 @@
     <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Mesajele prin satelit nu sunt disponibile"</string>
     <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Mesajele prin satelit nu sunt disponibile în această țară sau regiune"</string>
     <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Mesajele prin satelit nu sunt configurate"</string>
-    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Pentru a trimite mesaje prin satelit, setează Mesaje Google ca aplicație pentru mesaje prestabilită"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Pentru a trimite mesaje prin satelit, setează Mesaje Google ca aplicație prestabilită pentru mesaje"</string>
     <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Mesajele prin satelit nu sunt disponibile"</string>
     <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Pentru a verifica dacă mesajele prin satelit sunt disponibile în această țară sau regiune, activează setările privind locația"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurează din nou Deblocarea cu amprenta"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 8caa8b6..386830e 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -614,10 +614,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Приложение сможет определять относительное позиционирование устройств с технологией сверхширокополосной связи поблизости"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Взаимодействие с устройствами Wi‑Fi поблизости"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Приложение сможет передавать данные на устройства Wi‑Fi рядом, подключаться к ним и определять их примерное местоположение."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"относительное местоположение устройств поблизости"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Приложение сможет определять относительное местоположение устройств поблизости."</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сведения о предпочтительном платежном сервисе NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Приложение сможет получать сведения о предпочтительном платежном сервисе NFC (например, зарегистрированные идентификаторы AID и конечный пункт маршрута)."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Управление NFC-модулем"</string>
@@ -2444,11 +2442,11 @@
     <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Спутниковый SOS не настроен"</string>
     <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Проверьте подключение к интернету и повторите попытку."</string>
     <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Спутниковый SOS недоступен"</string>
-    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Функция недоступна в этой стране или регионе."</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Функция недоступна в стране или в этом регионе."</string>
     <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Спутниковый SOS не настроен"</string>
     <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Чтобы использовать эту функцию, необходимо выбрать Google Сообщения в качестве мессенджера по умолчанию."</string>
     <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Спутниковый SOS недоступен"</string>
-    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Чтобы узнать, можно ли использовать спутниковый SOS в этой стране или регионе, включите настройки геолокации."</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Чтобы узнать, можно ли использовать спутниковый SOS в стране или в этом регионе, включите настройки геолокации."</string>
     <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Доступен спутниковый обмен сообщениями"</string>
     <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Вы можете обмениваться сообщениями по спутниковой связи, даже когда подключение к мобильной сети или Wi-Fi недоступно. Google Сообщения должны быть выбраны в качестве мессенджера по умолчанию."</string>
     <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Спутниковый обмен сообщениями не поддерживается"</string>
@@ -2456,11 +2454,11 @@
     <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Спутниковый обмен сообщениями не настроен"</string>
     <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Проверьте подключение к интернету и повторите попытку."</string>
     <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Спутниковый обмен сообщениями недоступен"</string>
-    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Функция недоступна в этой стране или регионе."</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Функция недоступна в стране или в этом регионе."</string>
     <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Спутниковый обмен сообщениями не настроен"</string>
     <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Чтобы использовать эту функцию, необходимо выбрать Google Сообщения в качестве мессенджера по умолчанию."</string>
     <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Спутниковый обмен сообщениями недоступен"</string>
-    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Чтобы узнать, можно ли обмениваться сообщениями по спутниковой связи в этой стране или регионе, включите настройки геолокации."</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Чтобы узнать, можно ли обмениваться сообщениями по спутниковой связи в стране или в этом регионе, включите настройки геолокации."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Настройте разблокировку по отпечатку пальца заново"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Отпечаток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больше нельзя распознать."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Отпечатки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больше нельзя распознать."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index f150cd1..e969a8e 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"අවට ඇති අල්ට්‍රා-වයිඩ්බෑන්ඩ් උපාංග අතර සාපේක්ෂ පිහිටීම නිර්ණය කිරීමට යෙදුමට ඉඩ දීම"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"අවට Wi‑Fi උපාංග සමග අන්තර්ක්‍රියා කරන්න"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"වෙළඳ දැන්වීම් පළ කිරීමට, සම්බන්ධ වීමට සහ අවට ඇති Wi-Fi උපාංගවල සාපේක්ෂ පිහිටීම නිර්ණය කිරීමට යෙදුමට ඉඩ දෙයි"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"අවට උපාංග අතර සාපේක්ෂ පිහිටීම තීරණය කරන්න"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"අවට උපාංග අතර සාපේක්ෂ පිහිටීම තීරණය කිරීමට යෙදුමට ඉඩ දෙන්න"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"කැමති NFC ගෙවීම් සේවා තොරතුරු"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ලියාපදිංචි කළ ආධාර සහ ගමන් මාර්ග ගමනාන්ත වැනි කැමති nfc ගෙවීම් සේවා තොරතුරු ලබා ගැනීමට යෙදුමට ඉඩ දෙයි."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ආසන්න ක්ෂේත්‍ර සන්නිවේදනය පාලනය කරන්න"</string>
@@ -2409,7 +2407,7 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"යතුරු පුවරුව <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ලෙස සකසා ඇත… වෙනස් කිරීමට තට්ටු කරන්න."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"භෞතික යතුරු පුවරුව වින්‍යාස කෙරිණි"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"යතුරු පුවරු බැලීමට තට්ටු කරන්න"</string>
-    <string name="profile_label_private" msgid="6463418670715290696">"පෞද්ගලික"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"රහසිගත"</string>
     <string name="profile_label_clone" msgid="769106052210954285">"ක්ලෝන කරන්න"</string>
     <string name="profile_label_work" msgid="3495359133038584618">"කාර්යාලය"</string>
     <string name="profile_label_work_2" msgid="4691533661598632135">"කාර්යාලය 2"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ක්‍රියාත්මක කරන්න"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ආපසු යන්න"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"පොරොත්තුයි..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"චන්ද්‍රිකා SOS දැන් ලබා ගත හැක"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"ජංගම හෝ Wi-Fi ජාලයක් නොමැති නම් ඔබට හදිසි සේවා පණිවිඩ යැවීමට හැක. Google Messages ඔබේ පෙරනිමි පණිවිඩකරණ යෙදුම විය යුතු යි."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"චන්ද්‍රිකා SOS සහාය නොදක්වයි"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"මෙම උපාංගය මත චන්ද්‍රිකා SOS සහාය නොදක්වයි"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"චන්ද්‍රිකා SOS පිහිටුවා නැත"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"ඔබ අන්තර්ජාලයට සම්බන්ධ වී ඇති බවට වග බලා ගෙන නැවත පිහිටුවීමට උත්සාහ කරන්න"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"චන්‍ද්‍රික SOS ලබා ගත නොහැක"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"චන්ද්‍රිකා SOS මෙම රටෙහි හෝ කලාපයෙහි ලබා ගත නොහැක"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"චන්ද්‍රිකා SOS පිහිටුවා නැත"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"චන්ද්‍රිකා මඟින් පණිවිඩ යැවීමට, Google Messages ඔබේ පෙරනිමි පණිවිඩ යැවීමේ යෙදුම ලෙස සකසන්න"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"චන්‍ද්‍රික SOS ලබා ගත නොහැක"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"මෙම රටෙහි හෝ කලාපය තුළ චන්ද්‍රිකා SOS ලබා ගත හැකි දැයි පරීක්ෂා කිරීමට, ස්ථාන සැකසීම් ක්‍රියාත්මක කරන්න"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"චන්ද්‍රිකා පණිවිඩ යැවීම ලබා ගත හැක"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"ජංගම හෝ Wi-Fi ජාලයක් නොමැති නම් ඔබට චන්ද්‍රිකාවෙන් පණිවිඩයක් යැවිය හැක. Google Messages ඔබේ පෙරනිමි පණිවිඩකරණ යෙදුම විය යුතු යි."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"චන්ද්‍රිකා පණිවිඩ යැවීමට සහය නොදක්වයි"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"මෙම උපාංගය මත චන්ද්‍රිකා පණිවිඩ යැවීමට සහය නොදක්වයි"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"චන්ද්‍රිකා පණිවිඩ යැවීම පිහිටුවා නැත"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"ඔබ අන්තර්ජාලයට සම්බන්ධ වී ඇති බවට වග බලා ගෙන නැවත පිහිටුවීමට උත්සාහ කරන්න"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"චන්ද්‍රිකා පණිවිඩ යැවීම ලබා ගත නොහැක"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"චන්ද්‍රිකා පණිවිඩ යැවීම මෙම රටෙහි හෝ කලාපයෙහි ලබා ගත නොහැක"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"චන්ද්‍රිකා පණිවිඩ යැවීම පිහිටුවා නැත"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"චන්ද්‍රිකා මඟින් පණිවිඩ යැවීමට, Google Messages ඔබේ පෙරනිමි පණිවිඩ යැවීමේ යෙදුම ලෙස සකසන්න"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"චන්ද්‍රිකා පණිවිඩ යැවීම ලබා ගත නොහැක"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"මෙම රටෙහි හෝ කලාපය තුළ චන්ද්‍රිකා පණිවිඩ යැවීම ලබා ගත හැකි දැයි පරීක්ෂා කිරීමට, ස්ථාන සැකසීම් ක්‍රියාත්මක කරන්න"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ඇඟිලි සලකුණු අගුලු හැරීම නැවත සකසන්න"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index e17e25f..d211d8c 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -614,10 +614,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Povoľte aplikácii určovať relatívnu polohu medzi zariadeniami s ultraširokopásmovým pripojením v okolí"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcia so zariadeniami Wi-Fi v okolí"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Umožňuje aplikácii oznamovať a rozpoznávať relatívnu polohu zariadení Wi‑Fi v okolí a pripájať sa k nim"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"určovať relatívnu polohu medzi zariadeniami v okolí"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Povoľte aplikácii určovať relatívnu polohu medzi zariadeniami v okolí"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferované informácie platenej služby NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikácii získavať preferované informácie platenej služby NFC, napríklad o registrovanej pomoci a trasách k cieľu."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ovládať technológiu NFC"</string>
@@ -2437,54 +2435,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Zapnúť"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Prejsť späť"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Nespracovaná…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Pomoc cez satelit je teraz k dispozícii"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Tiesňovej linke môžete poslať správu, keď nie je dostupná mobilná sieť ani sieť Wi‑Fi. Správy Google musíte mať nastavené ako predvolený komunikátor."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Pomoc cez satelit nie je podporovaná"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Pomoc cez satelit nie je v tomto zariadení podporovaná"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Pomoc cez satelit nie je nastavená"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Skontrolujte, či máte internetové pripojenie, a skúste nastavenie zopakovať"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Pomoc cez satelit nie je k dispozícii"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Pomoc cez satelit nie je v tejto krajine alebo regióne k dispozícii"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Pomoc cez satelit nie je nastavená"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Ak chcete posielať správy cez satelit, nastavte Správy Google ako predvolený komunikátor"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Pomoc cez satelit nie je k dispozícii"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Ak chcete skontrolovať, či je pomoc cez satelit v tejto krajine alebo regióne k dispozícii, zapnite nastavenia polohy"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Správy cez satelit sú k dispozícii"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Keď nie je dostupná mobilná sieť ani sieť Wi‑Fi, môžete posielať správy cez satelit. Správy Google musíte mať nastavené ako predvolený komunikátor."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Správy cez satelit nie sú podporované"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Správy cez satelit nie sú v tomto zariadení podporované"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Správy cez satelit nie sú nastavené"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Skontrolujte, či máte internetové pripojenie, a skúste nastavenie zopakovať"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Správy cez satelit nie sú k dispozícii"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Správy cez satelit nie sú v tejto krajine alebo regióne k dispozícii"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Správy cez satelit nie sú nastavené"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Ak chcete posielať správy cez satelit, nastavte Správy Google ako predvolený komunikátor"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Správy cez satelit nie sú k dispozícii"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Ak chcete skontrolovať, či sú správy cez satelit v tejto krajine alebo regióne k dispozícii, zapnite nastavenia polohy"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Znova nastavte odomknutie odtlačkom prsta"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> sa už nedari rozpoznať."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> sa už nedari rozpoznať."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index da9f1c1..ca85434 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -614,10 +614,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikaciji dovoli, da določi relativno oddaljenost med napravami UWB v bližini."</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"komunikacija z napravami Wi‑Fi v bližini"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Aplikaciji dovoljuje objavljanje in določanje relativnega položaja naprav Wi‑Fi v bližini ter povezovanje z njimi."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"določanje relativne oddaljenosti med napravami v bližini"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Aplikaciji dovoli, da določi relativno oddaljenost med napravami v bližini"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Podatki o prednostni storitvi za plačevanje prek povezave NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Aplikaciji omogoča pridobivanje podatkov o prednostni storitvi za plačevanje prek povezave NFC, kot so registrirani pripomočki in cilj preusmeritve."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"nadzor nad komunikacijo s tehnologijo bližnjega polja"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 1b8d0a0..45cf31a 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Lejo që aplikacioni të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi me brezin ultra të gjerë"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"të ndërveprojë me pajisjet Wi-Fi në afërsi"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lejon që aplikacioni të reklamojë, të lidhet dhe të përcaktojë pozicionin përkatës të pajisjeve Wi-Fi në afërsi"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Lejo që aplikacioni të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacionet për shërbimin e preferuar të pagesës me NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lejon aplikacionin të marrë informacione për shërbimin e preferuar të pagesës me NFC si p.sh. ndihmat e regjistruara dhe destinacionin e itinerarit."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrollo \"Komunikimin e fushës në afërsi\" NFC"</string>
@@ -2186,7 +2184,7 @@
     <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth-i do të qëndrojë i aktivizuar gjatë modalitetit të aeroplanit"</string>
     <string name="car_loading_profile" msgid="8219978381196748070">"Po ngarkohet"</string>
     <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # skedar}other{{file_name} + # skedarë}}"</string>
-    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nuk ka persona të rekomanduar për ta ndarë"</string>
+    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nuk ka persona të rekomanduar për të ndarë"</string>
     <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista e aplikacioneve"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Këtij aplikacioni nuk i është dhënë leje për regjistrim, por mund të regjistrojë audio përmes kësaj pajisjeje USB."</string>
     <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Ekrani bazë"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivizo"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Kthehu prapa"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Në pritje..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"\"SOS satelitor\" ofrohet tani"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Mund t\'u dërgosh mesazhe shërbimeve të urgjencës nëse nuk ka rrjet celular ose Wi-Fi. \"Mesazhet e Google\" duhet të jenë aplikacioni yt i parazgjedhur i mesazheve."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"\"SOS satelitor\" nuk mbështetet"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"\"SOS satelitor\" nuk mbështetet në këtë pajisje"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"\"SOS satelitor\" nuk është konfiguruar"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Sigurohu që të jesh lidhur me internetin dhe provo përsëri konfigurimin"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"\"SOS satelitor\" nuk ofrohet"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"\"SOS satelitor\" nuk ofrohet në këtë shtet ose rajon"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"\"SOS satelitor\" nuk është konfiguruar"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Për të shkëmbyer mesazhe nëpërmjet satelitit, cakto \"Mesazhet e Google\" si aplikacionin e parazgjedhur të mesazheve"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"\"SOS satelitor\" nuk ofrohet"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Për të kontrolluar nëse \"SOS satelitor\" ofrohet në këtë shtet ose rajon, aktivizo cilësimet e vendndodhjes"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Ofrohet shkëmbimi i mesazheve nëpërmjet satelitit"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Mund të shkëmbesh mesazhe nëpërmjet satelitit nëse nuk ka rrjet celular ose Wi-Fi. \"Mesazhet e Google\" duhet të jenë aplikacioni yt i parazgjedhur i mesazheve."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk mbështetet"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk mbështetet në këtë pajisje"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk është konfiguruar"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Sigurohu që të jesh lidhur me internetin dhe provo përsëri konfigurimin"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk ofrohet"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk ofrohet në këtë shtet ose rajon"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk është konfiguruar"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Për të shkëmbyer mesazhe nëpërmjet satelitit, cakto \"Mesazhet e Google\" si aplikacionin e parazgjedhur të mesazheve"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk ofrohet"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Për të kontrolluar nëse shkëmbimi i mesazheve nëpërmjet satelitit ofrohet në këtë shtet ose rajon, aktivizo cilësimet e vendndodhjes"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\""</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk mund të njihet më."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk mund të njihen më."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index bdf5571..5a3bae0 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -613,10 +613,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дозвољава апликацији да одређује релативну раздаљину између уређаја ултра-широког појаса у близини"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"интеракција са WiFi уређајима у близини"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Дозвољава апликацији да се оглашава, повезује и утврђује релативну позицију WiFi уређаја у близини"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"одређивање раздаљине између уређаја у близини"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Дозволите апликацији да одређује релативну раздаљину између уређаја у близини"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информације о жељеној NFC услузи за плаћање"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозвољава апликацији да преузима информације о жељеној NFC услузи за плаћање, попут регистрованих идентификатора апликација и одредишта преусмеравања."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"контрола комуникације у ужем пољу (Near Field Communication)"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 8bef5ca..fde9023 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tillåt att appen fastställer den relativa positionen mellan Ultra Wideband-enheter i närheten"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagera med wifi-enheter i närheten"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Tillåter appen att sända ut till, ansluta till och fastställa relativ position för wifi-enheter i närheten"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"fastställa relativ position för enheter i närheten"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Tillåt att appen fastställer den relativa positionen mellan enheter i närheten"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information kopplad till standardtjänsten för NFC-betalning"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillåter att appen hämtar information kopplad till standardtjänsten för NFC-betalning, till exempel registrerade hjälpmedel och ruttdestinationer."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrollera närfältskommunikationen"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 010415e..2a62c87 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ruhusu programu ibainishe nafasi kati ya vifaa vyenye Bendi Pana Zaidi vilivyo karibu"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"tumia vifaa vya Wi‑Fi vilivyo karibu"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Huruhusu programu kutangaza, kuunganisha na kubaini mahali palipokadiriwa vilipo vifaa vya Wi-Fi vilivyo karibu"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"kubainisha nafasi kati ya vifaa vilivyo karibu"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Ruhusu programu ibainishe nafasi kati ya vifaa vilivyo karibu"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maelezo ya Huduma Inayopendelewa ya Malipo ya NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Huruhusu programu kupata maelezo ya huduma inayopendelewa ya malipo ya nfc kama vile huduma zilizosajiliwa na njia."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kudhibiti Mawasiliano ya Vifaa Vilivyokaribu (NFC)"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Washa"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Rudi nyuma"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Inashughulikiwa..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Kipengele cha Msaada kupitia Setilaiti sasa kinapatikana"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Unaweza kutumia huduma za dharura ujumbe iwapo hakuna mtandao wa simu au wa Wi-Fi. Ni sharti uweke Google Messages iwe programu yako chaguomsingi ya kutuma ujumbe."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Kipengele cha Msaada kupitia Setilaiti hakiwezi kutumika"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Kipengele cha Msaada kupitia Setilaiti hakiwezi kutumika kwenye kifaa hiki"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Mipangilio ya kipengele cha Msaada kupitia Setilaiti haijawekwa"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Hakikisha kuwa umeunganisha kifaa chako kwenye intaneti kisha ujaribu kuweka mipangilio tena"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Kipengele cha Msaada kupitia Setilaiti hakipatikani"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Kipengele cha Msaada kupitia Setilaiti hakipatikani katika nchi au eneo hili"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Mipangilio ya kipengele cha Msaada kupitia Setilaiti haijawekwa"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Ili utume ujumbe kupitia setilaiti, weka Google Messages iwe programu yako chaguomsingi ya kutuma ujumbe"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Kipengele cha Msaada kupitia Setilaiti hakipatikani"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Ili uangalie iwapo kipengele cha Msaada kupitia Setilaiti kinapatikana katika nchi au eneo hili, washa mipangilio ya mahali"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Kipengele cha kutuma ujumbe kupitia setilaiti kinapatikana"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Unaweza kutuma ujumbe kupitia setilaiti iwapo hakuna mtandao wa simu au wa Wi-Fi. Ni sharti uweke Google Messages iwe programu yako chaguomsingi ya kutuma ujumbe."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Kipengele cha kutuma ujumbe kupitia setilaiti hakiwezi kutumika"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Kipengele cha kutuma ujumbe kupitia setilaiti hakiwezi kutumika kwenye kifaa hiki"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Mipangilio ya kutuma ujumbe kupitia setilaiti haijawekwa"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Hakikisha kuwa umeunganisha kifaa chako kwenye intaneti kisha ujaribu kuweka mipangilio tena"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Kipengele cha kutuma ujumbe kupitia setilaiti hakipatikani"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Kipengele cha kutuma ujumbe kupitia setilaiti hakipatikani katika nchi au eneo hili"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Mipangilio ya kutuma ujumbe kupitia setilaiti haijawekwa"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Ili utume ujumbe kupitia setilaiti, weka Google Messages iwe programu yako chaguomsingi ya kutuma ujumbe"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Kipengele cha kutuma ujumbe kupitia setilaiti hakipatikani"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Ili uangalie iwapo kipengele cha kutuma ujumbe kupitia setilaiti kinapatikana katika nchi au eneo hili, washa mipangilio ya mahali"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Weka tena mipangilio ya Kufungua kwa Alama ya Kidole"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> haitambuliki tena."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> havitambuliki tena."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 1915f29..6ff96c0 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"அருகிலுள்ள அல்ட்ரா-வைடுபேண்ட் சாதனங்களுக்கிடையிலான தூரத்தைத் தீர்மானிக்க ஆப்ஸை அனுமதிக்கும்"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"அருகிலுள்ள வைஃபை சாதனங்களுடன் தொடர்பு கொள்ளுதல்"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"அருகிலுள்ள வைஃபை சாதனங்களைத் தெரியப்படுத்தவும் இணைக்கவும் இருப்பிடத்தைத் தீர்மானிக்கவும் இது ஆப்ஸை அனுமதிக்கும்"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"அருகிலுள்ள சாதனங்களுக்கான தூரத்தைத் தீர்மானித்தல்"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"அருகிலுள்ள சாதனங்களுக்கு இடையிலான தூரத்தைத் தீர்மானிக்க ஆப்ஸை அனுமதிக்கும்"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்கள்"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"பதிவுசெய்யப்பட்ட கருவிகள், சேருமிடத்திற்கான வழி போன்ற விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்களைப் பெற ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"குறுகிய இடைவெளி தகவல்பரிமாற்றத்தைக் கட்டுப்படுத்துதல்"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"இயக்கு"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"பின்செல்"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"நிலுவையிலுள்ளது..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"சாட்டிலைட் SOS அம்சம் இப்போது கிடைக்கிறது"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"மொபைல்/வைஃபை நெட்வொர்க் இல்லையென்றால், அவசரகால சேவைகளுக்கு மெசேஜ் அனுப்பலாம். Google Messages உங்கள் இயல்புநிலை மெசேஜிங் ஆப்ஸாக இருக்க வேண்டும்."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"சாட்டிலைட் SOS ஆதரிக்கப்படவில்லை"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"இந்தச் சாதனத்தில் சாட்டிலைட் SOS ஆதரிக்கப்படவில்லை"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"சாட்டிலைட் SOS அமைக்கப்படவில்லை"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"இணையத்துடன் இணைக்கப்பட்டிருப்பதை உறுதிசெய்துகொண்டு மீண்டும் அமைக்க முயலுங்கள்"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"சாட்டிலைட் SOS கிடைக்கவில்லை"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"இந்த நாடு/பிராந்தியத்தில் சாட்டிலைட் SOS கிடைக்கவில்லை"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"சாட்டிலைட் SOS அமைக்கப்படவில்லை"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"சாட்டிலைட் மூலம் மெசேஜ் செய்ய, Google Messages ஆப்ஸை உங்கள் இயல்புநிலை மெசேஜிங் ஆப்ஸாக அமையுங்கள்"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"சாட்டிலைட் SOS கிடைக்கவில்லை"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"இந்த நாட்டிலோ பிராந்தியத்திலோ சாட்டிலைட் SOS கிடைக்கிறதா எனப் பார்க்க இருப்பிட அமைப்புகளை இயக்குங்கள்"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"சாட்டிலைட் மெசேஜிங் கிடைக்கிறது"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"மொபைல்/வைஃபை நெட்வொர்க் இல்லையென்றால் சாட்டிலைட் மூலம் மெசேஜ் அனுப்பலாம். Google Messages உங்கள் இயல்புநிலை மெசேஜிங் ஆப்ஸாக இருக்க வேண்டும்."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"சாட்டிலைட் மெசேஜிங் ஆதரிக்கப்படவில்லை"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"இந்தச் சாதனத்தில் சாட்டிலைட் மெசேஜிங் ஆதரிக்கப்படவில்லை"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"சாட்டிலைட் மெசேஜிங் அமைக்கப்படவில்லை"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"இணையத்துடன் இணைக்கப்பட்டிருப்பதை உறுதிசெய்துகொண்டு மீண்டும் அமைக்க முயலுங்கள்"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"சாட்டிலைட் மெசேஜிங் கிடைக்கவில்லை"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"இந்த நாடு/பிராந்தியத்தில் சாட்டிலைட் மெசேஜிங் கிடைக்கவில்லை"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"சாட்டிலைட் மெசேஜிங் அமைக்கப்படவில்லை"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"சாட்டிலைட் மூலம் மெசேஜ் செய்ய, Google Messages ஆப்ஸை உங்கள் இயல்புநிலை மெசேஜிங் ஆப்ஸாக அமையுங்கள்"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"சாட்டிலைட் மெசேஜிங் கிடைக்கவில்லை"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"இந்த நாட்டிலோ பிராந்தியத்திலோ சாட்டிலைட் மெசேஜிங் கிடைக்கிறதா எனப் பார்க்க இருப்பிட அமைப்புகளை இயக்குங்கள்"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>ஐ இனி அடையாளம் காண முடியாது."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ஆகியவற்றை இனி அடையாளம் காண முடியாது."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6ac8164..68fce1f 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -354,7 +354,7 @@
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"మీరు టైప్ చేస్తున్న వచనాన్ని పరిశీలిస్తుంది"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"క్రెడిట్ కార్డు నంబర్‌లు మరియు పాస్‌వర్డ్‌ల వంటి వ్యక్తిగత డేటాను కలిగి ఉంటుంది."</string>
     <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"డిస్‌ప్లే మ్యాగ్నిఫికేషన్‌ను నియంత్రించండి"</string>
-    <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"డిస్‌ప్లే జూమ్ స్థాయి మరియు స్థానాన్ని నియంత్రిస్తుంది."</string>
+    <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"డిస్‌ప్లే జూమ్ స్థాయి మరియు లొకేషన్‌ని నియంత్రిస్తుంది."</string>
     <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"సంజ్ఞలను చేయడం"</string>
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"నొక్కగలరు, స్వైప్ చేయగలరు, స్క్రీన్‌పై రెండు వేళ్లను ఉంచి ఆ వేళ్లను దగ్గరకు లేదా దూరానికి లాగగలరు మరియు ఇతర సంజ్ఞలను చేయగలరు."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"వేలిముద్ర సంజ్ఞలు"</string>
@@ -608,14 +608,12 @@
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"పెయిర్ చేసిన బ్లూటూత్ పరికరాలకు కనెక్ట్ అవ్వడానికి యాప్‌ను అనుమతిస్తుంది"</string>
     <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"సమీపంలోని బ్లూటూత్ పరికరాలలో అడ్వర్టయిజ్ చేయండి"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"సమీపంలోని బ్లూటూత్ పరికరాలలో అడ్వర్టయిజ్ చేయడానికి యాప్‌కు అనుమతిని ఇస్తుంది"</string>
-    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"సమీపంలోని అల్ట్రా-వైడ్‌బ్యాండ్ పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించండి"</string>
-    <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"సమీపంలోని అల్ట్రా-వైడ్‌బ్యాండ్ పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించడానికి యాప్‌ను అనుమతించండి"</string>
+    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"సమీపంలోని అల్ట్రా-వైడ్‌బ్యాండ్ పరికరాల మధ్య సంబంధిత పొజిషన్‌ను నిర్ణయించండి"</string>
+    <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"సమీపంలోని అల్ట్రా-వైడ్‌బ్యాండ్ పరికరాల మధ్య సంబంధిత పొజిషన్‌ను నిర్ణయించడానికి యాప్‌ను అనుమతించండి"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"సమీపంలోని Wi-Fi పరికరాలతో ఇంటరాక్ట్ చేస్తుంది"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"అడ్వర్టయిజ్, కనెక్ట్ చేయడానికి, సమీపంలోని Wi-Fi పరికరాల సంబంధిత పొజిషన్‌ను నిర్ణయించడానికి యాప్‌ను అనుమతిస్తుంది"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"సమీపంలో పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించండి"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"సమీపంలోని పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించడానికి యాప్‌ను అనుమతించండి"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారం"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారాన్ని, అంటే రిజిస్టర్ చేయబడిన సహాయక సాధనాలు, మార్గం, గమ్యస్థానం వంటి వాటిని పొందేందుకు యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"సమీప క్షేత్ర కమ్యూనికేషన్‌ను నియంత్రించడం"</string>
@@ -724,7 +722,7 @@
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"బాగా కదుపుతున్నారు. ఫోన్‌ను స్థిరంగా పట్టుకోండి"</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"దయచేసి మీ ముఖాన్ని మళ్లీ నమోదు చేయండి."</string>
     <string name="face_acquired_too_different" msgid="4505278456634706967">"ముఖం గుర్తించబడలేదు. మళ్లీ ట్రై చేయండి."</string>
-    <string name="face_acquired_too_similar" msgid="8882920552674125694">"మీ తల స్థానాన్ని కొద్దిగా మార్చండి"</string>
+    <string name="face_acquired_too_similar" msgid="8882920552674125694">"మీ తల లొకేషన్‌ను కొద్దిగా మార్చండి"</string>
     <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"మీ ఫోన్ వైపు మరింత నేరుగా చూడండి"</string>
     <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"మీ ఫోన్ వైపు మరింత నేరుగా చూడండి"</string>
     <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"మీ ఫోన్ వైపు మరింత నేరుగా చూడండి"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ఆన్ చేయండి"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"వెనుకకు వెళ్లండి"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"పెండింగ్‌లో ఉంది..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"ఎమర్జెన్సీ శాటిలైట్ సహాయం ఇప్పుడు అందుబాటులో ఉంది"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"మొబైల్ లేదా Wi-Fi నెట్‌వర్క్ ఏదీ లేనట్లయితే మీరు ఎమర్జెన్సీ సర్వీసులకు మెసేజ్ చేయవచ్చు. Google Messages అనేది తప్పనిసరిగా మీ ఆటోమేటిక్ మెసేజింగ్ యాప్‌గా సెట్ చేసి ఉండాలి."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"ఎమర్జెన్సీ శాటిలైట్ సహాయం సపోర్ట్ చేయదు"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"ఈ పరికరంలో ఎమర్జెన్సీ శాటిలైట్ సహాయం సపోర్ట్ చేయదు"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"ఎమర్జెన్సీ శాటిలైట్ సహాయం సెటప్ కాలేదు"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"మీరు ఇంటర్నెట్‌కు కనెక్ట్ అయి ఉన్నారని నిర్ధారించుకుని, మళ్లీ సెటప్‌ను ట్రై చేయండి"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో లేదు"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"ఈ దేశంలో లేదా ప్రాంతంలో ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో లేదు"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"ఎమర్జెన్సీ శాటిలైట్ సహాయం సెటప్ చేయలేదు"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"శాటిలైట్ ద్వారా మెసేజ్ చేయడానికి, Google Messagesను మీ ఆటోమేటిక్ సెట్టింగ్ మెసేజింగ్ యాప్‌గా సెట్ చేయండి"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో లేదు"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"ఈ దేశంలో లేదా ప్రాంతంలో ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో ఉందో లేదో చెక్ చేయడానికి, లొకేషన్ సెట్టింగ్‌లను ఆన్ చేయండి"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"శాటిలైట్ మెసేజింగ్ అందుబాటులో ఉంది"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"మొబైల్ లేదా Wi-Fi నెట్‌వర్క్ లేకుంటే మీరు శాటిలైట్ ద్వారా మెసేజ్‌ను పంపవచ్చు. Google Messages అనేది తప్పనిసరిగా మీ ఆటోమేటిక్ మెసేజింగ్ యాప్‌గా సెట్ చేసి ఉండాలి."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"శాటిలైట్ మెసేజింగ్ సపోర్ట్ చేయదు"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"ఈ పరికరంలో శాటిలైట్ మెసేజింగ్ సపోర్ట్ చేయదు"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"శాటిలైట్ మెసేజింగ్‌ను సెటప్ చేయలేదు"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"మీరు ఇంటర్నెట్‌కు కనెక్ట్ అయి ఉన్నారని నిర్ధారించుకుని, మళ్లీ సెటప్‌ను ట్రై చేయండి"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"శాటిలైట్ మెసేజింగ్ అందుబాటులో లేదు"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"ఈ దేశంలో లేదా ప్రాంతంలో శాటిలైట్ మెసేజింగ్ అందుబాటులో లేదు"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"శాటిలైట్ మెసేజింగ్‌ను సెటప్ చేయలేదు"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"శాటిలైట్ ద్వారా మెసేజ్ చేయడానికి, Google Messagesను మీ ఆటోమేటిక్ సెట్టింగ్ మెసేజింగ్ యాప్‌గా సెట్ చేయండి"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"శాటిలైట్ మెసేజింగ్ అందుబాటులో లేదు"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"ఈ దేశంలో లేదా ప్రాంతంలో శాటిలైట్ మెసేజింగ్ అందుబాటులో ఉందో లేదో చెక్ చేయడానికి, లొకేషన్ సెట్టింగ్‌లను ఆన్ చేయండి"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>‌ను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‌లను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 763eb62..178a76d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"อนุญาตให้แอประบุตำแหน่งสัมพันธ์ระหว่างอุปกรณ์ที่ใช้แถบความถี่กว้างยิ่งยวดซึ่งอยู่ใกล้เคียง"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"โต้ตอบกับอุปกรณ์ Wi-Fi ที่อยู่ใกล้เคียง"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"อนุญาตให้แอปแสดงข้อมูล เชื่อมต่อ และระบุตำแหน่งซึ่งสัมพันธ์กับอุปกรณ์ Wi-Fi ที่อยู่ใกล้เคียง"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"ระบุตำแหน่งสัมพันธ์ระหว่างอุปกรณ์ที่อยู่ใกล้เคียง"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"อนุญาตให้แอประบุตำแหน่งสัมพันธ์ระหว่างอุปกรณ์ที่อยู่ใกล้เคียง"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ข้อมูลบริการชำระเงิน NFC ที่ต้องการ"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"อนุญาตให้แอปรับข้อมูลบริการชำระเงิน NFC ที่ต้องการ เช่น รหัสแอป (AID) ที่ลงทะเบียนและปลายทางของเส้นทาง"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"ควบคุม Near Field Communication"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index b44faae..8e3c5e7 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Payagan ang app na tukuyin ang relatibong posisyon sa pagitan ng mga kalapit na Ultra-Wideband device"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"makipag-ugnayan sa mga kalapit na Wi‑Fi device"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Nagbibigay-daan sa app na i-advertise ang, kumonekta sa, at tukuyin ang nauugnay na posisyon ng mga kalapit na Wi‑Fi device"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"alamin ang relative position sa kalapit na device"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Payagan ang app na alamin ang relatibong posisyon sa pagitan ng mga kalapit na device"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Impormasyon sa Gustong NFC na Serbisyo sa Pagbabayad"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pinapayagan ang app na makakuha ng impormasyon sa gustong nfc na serbisyo sa pagbabayad tulad ng mga nakarehistrong application ID at destinasyon ng ruta."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrolin ang Near Field Communication"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index e54b899..98b1dd3 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Uygulamanın, yakındaki Ultra Geniş Bant cihazların birbirine göre konumunu belirlemesine izin verin"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"yakındaki kablosuz cihazlarla etkileşim kur"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Uygulamanın reklam sunmasına, bağlanmasına ve yakındaki kablosuz cihazların göreli konumunu belirlemesine izin verir"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"yakındaki cihazların göreli konumunu belirleme"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Uygulamanın, yakındaki cihazların birbirine göre konumunu belirlemesine izin verin"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tercih Edilen NFC Ödeme Hizmeti Bilgileri"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Uygulamaya, kayıtlı yardımlar ve rota hedefi gibi tercih edilen NFC ödeme hizmeti bilgilerini alma izni verir."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Yakın Alan İletişimini denetle"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Etkinleştir"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Geri dön"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Bekliyor..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Acil Uydu Bağlantısı kullanıma sunuldu"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Mobil veya kablosuz ağ bağlantısı yoksa acil durum hizmetleriyle mesajlaşabilirsiniz. Google Mesajlar varsayılan mesajlaşma uygulamanız olmalıdır."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Acil Uydu Bağlantısı desteklenmiyor"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Acil Uydu Bağlantısı bu cihazda desteklenmiyor"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Acil Uydu Bağlantısı özelliği ayarlanmamış"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"İnternete bağlı olup olmadığınızı kontrol edip tekrar ayarlamayı deneyin"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Acil Uydu Bağlantısı kullanılamıyor"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Acil Uydu Bağlantısı özelliği bu ülkede veya bölgede kullanıma sunulmamıştır"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Acil Uydu Bağlantısı özelliği ayarlanmamış"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Uydu üzerinden mesajlaşmak için Google Mesajlar\'ı varsayılan mesajlaşma uygulamanız olarak ayarlayın"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Acil Uydu Bağlantısı kullanılamıyor"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Acil Uydu Bağlantısı özelliğinin bu ülkede veya bölgede kullanılıp kullanılamadığını kontrol etmek için konum ayarlarını açın"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Uydu üzerinden mesajlaşma özelliği kullanılabilir"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Mobil veya kablosuz ağ bağlantısı yoksa uydu üzerinden mesaj gönderebilirsiniz. Google Mesajlar varsayılan mesajlaşma uygulamanız olmalıdır."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Uydu üzerinden mesajlaşma desteklenmiyor"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Uydu üzerinden mesajlaşma bu cihazda desteklenmiyor"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Uydu üzerinden mesajlaşma özelliği ayarlanmamış"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"İnternete bağlı olup olmadığınızı kontrol edip tekrar ayarlamayı deneyin"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Uydu üzerinden mesajlaşma özelliği kullanılamıyor"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Uydu üzerinden mesajlaşma özelliği bu ülkede veya bölgede kullanılamıyor"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Uydu üzerinden mesajlaşma özelliği ayarlanmamış"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Uydu üzerinden mesajlaşmak için Google Mesajlar\'ı varsayılan mesajlaşma uygulamanız olarak ayarlayın"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Uydu üzerinden mesajlaşma özelliği kullanılamıyor"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Uydu üzerinden mesajlaşma özelliğinin bu ülkede veya bölgede kullanılıp kullanılamadığını kontrol etmek için konum ayarlarını açın"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Parmak İzi Kilidi\'ni tekrar kurun"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artık tanınamayacak."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artık tanınamayacak."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 344cb28..d5e6bd8 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -614,10 +614,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"З цим дозволом додаток може визначати відстань між розташованими поблизу пристроями з надширокосмуговим зв’язком"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"взаємодіяти з пристроями Wi‑Fi поблизу"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Додаток може виявляти пристрої Wi‑Fi поблизу, підключатися до них і визначати їх відносне розташування"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"визначати відстань між пристроями поблизу"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Із цим дозволом додаток може визначати відстань між розташованими поблизу пристроями"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Використання інформації з платіжного NFC-сервісу"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволяє додатку отримувати доступ до інформації потрібного платіжного NFC-сервісу (наприклад, пов\'язаних ідентифікаторів чи даних про маршрутизацію трансакцій)."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"контрол. Near Field Communication"</string>
@@ -2437,54 +2435,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Увімкнути"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Назад"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Обробка…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Супутниковий сигнал SOS тепер доступний"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Ви можете надсилати повідомлення службам екстреної допомоги, якщо немає з’єднання з Wi-Fi або мобільною мережею. Потрібно зробити Google Повідомлення додатком для обміну повідомленнями за умовчанням."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Супутниковий сигнал SOS не підтримується"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Супутниковий сигнал SOS не підтримується на цьому пристрої"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Супутниковий сигнал SOS не налаштовано"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Переконайтеся, що пристрій підключено до Інтернету, і повторіть спробу налаштування"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Супутниковий сигнал SOS недоступний"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Супутниковий сигнал SOS недоступний у цій країні або регіоні"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Супутниковий сигнал SOS не налаштовано"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Щоб обмінюватися повідомленнями через супутник, потрібно зробити Google Повідомлення додатком для обміну повідомленнями за умовчанням"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Супутниковий сигнал SOS недоступний"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Щоб дізнатися, чи доступний супутниковий сигнал SOS у цій країні або регіоні, увімкніть доступ до геоданих"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Доступний супутниковий обмін повідомленнями"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Ви можете надсилати й отримувати повідомлення через супутник, якщо немає з’єднання з Wi-Fi або мобільною мережею. Потрібно зробити Google Повідомлення додатком для обміну повідомленнями за умовчанням."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Супутниковий обмін повідомленнями не підтримується"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Супутниковий обмін повідомленнями не підтримується на цьому пристрої"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Супутниковий обмін повідомленнями не налаштовано"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Переконайтеся, що пристрій підключено до Інтернету, і повторіть спробу налаштування"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Супутниковий обмін повідомленнями недоступний"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Супутниковий обмін повідомленнями недоступний у цій країні або регіоні"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Супутниковий обмін повідомленнями не налаштовано"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Щоб обмінюватися повідомленнями через супутник, потрібно зробити Google Повідомлення додатком для обміну повідомленнями за умовчанням"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Супутниковий обмін повідомленнями недоступний"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Щоб дізнатися, чи доступний супутниковий обмін повідомленнями в цій країні або регіоні, увімкніть доступ до геоданих"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Налаштуйте розблокування відбитком пальця повторно"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Відбиток пальця <xliff:g id="FINGERPRINT">%s</xliff:g> більше не розпізнається."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Відбитки пальців <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> і <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> більше не розпізнаються."</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 45e1a23..b26b1c1 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ایپ کو قریبی الٹرا وائڈ بینڈ آلات کے مابین متعلقہ پوزیشن کا تعین کرنے کی اجازت دیں"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"‏قریبی Wi-Fi آلات کے ساتھ تعامل کریں"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏ایپ کو اشتہار دینے، منسلک کرنے اور قریبی Wi-Fi آلات کی متعلقہ پوزیشن کا تعین کرنے کی اجازت دیتا ہے"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"قریبی آلات کے مابین متعلقہ پوزیشن کا تعین کریں"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"ایپ کو قریبی آلات کے مابین متعلقہ پوزیشن کا تعین کرنے کی اجازت دیں"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏ترجیح شدہ NFC ادائیگی کی سروس کی معلومات"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏ایپ کو رجسٹرشدہ ایڈز اور روٹ ڈسٹنیشن جیسی ترجیح شدہ nfc ادائیگی سروس کی معلومات حاصل کرنے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"‏Near Field کمیونیکیشن کنٹرول کریں"</string>
@@ -2409,7 +2407,7 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> پر سیٹ ہے… تبدیل کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"فزیکل کی بورڈز کنفیگر کئے گئے"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"کی بورڈز دیکھنے کے لیے تھپتھپائیں"</string>
-    <string name="profile_label_private" msgid="6463418670715290696">"نجی"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"پرائیویٹ"</string>
     <string name="profile_label_clone" msgid="769106052210954285">"کلون"</string>
     <string name="profile_label_work" msgid="3495359133038584618">"دفتری پروفائل"</string>
     <string name="profile_label_work_2" msgid="4691533661598632135">"دوسری دفتری پروفائل"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index f123bea..97e0448 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ilovaga yaqin atrofdagi ultra keng polosali qurilmalarining nisbiy joylashishini aniqlashga ruxsat beradi"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Yaqin-atrofdagi Wi-Fi qurilmalar bilan ishlash"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Ilovaga yaqin-atrofdagi Wi-Fi qurilmalarga reklama yuborish, ulanish va ularning taxminiy joylashuvini aniqlash imkonini beradi."</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"atrofdagi qurilmalarning nisbiy joylashuvini aniqlash"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Ilova atrofdagi qurilmalarning nisbiy joylashuvini aniqlashi mumkin"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Asosiy NFC toʻlov xizmati haqidagi axborot"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Bu ilovaga asosiy NFC toʻlov xizmati haqidagi axborotni olish imkonini beradi (masalan, qayd qilingan AID identifikatorlari va marshrutning yakuniy manzili)."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"NFC modulini boshqarish"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ef50a9b..1ebff32 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Cho phép ứng dụng xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"tương tác với các thiết bị Wi‑Fi lân cận"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Cho phép ứng dụng này thông báo, kết nối và xác định vị trí tương đối của các thiết bị Wi‑Fi lân cận"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"xác định vị trí tương đối giữa các thiết bị ở gần"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Cho phép ứng dụng xác định vị trí tương đối giữa các thiết bị ở gần"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần (NFC) được ưu tiên"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Cho phép ứng dụng nhận thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần mà bạn ưu tiên, chẳng hạn như các hình thức hỗ trợ đã đăng ký và điểm đến trong hành trình."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kiểm soát Liên lạc trường gần"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Bật"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Quay lại"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Đang chờ xử lý..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Tính năng Liên lạc khẩn cấp qua vệ tinh đang hoạt động"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Bạn có thể nhắn tin cho dịch vụ khẩn cấp khi không có mạng di động hay mạng Wi-Fi. Google Tin nhắn phải là ứng dụng nhắn tin mặc định của bạn."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Chưa hỗ trợ tính năng Liên lạc khẩn cấp qua vệ tinh"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Thiết bị này chưa hỗ trợ tính năng Liên lạc khẩn cấp qua vệ tinh"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Chưa thiết lập tính năng Liên lạc khẩn cấp qua vệ tinh"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Hãy kiểm tra để chắc chắn rằng bạn đã kết nối Internet, rồi thử thiết lập lại"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Tính năng Liên lạc khẩn cấp qua vệ tinh chưa hoạt động"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Tính năng Liên lạc khẩn cấp qua vệ tinh chưa hoạt động ở quốc gia hoặc khu vực này"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Chưa thiết lập tính năng Liên lạc khẩn cấp qua vệ tinh"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Để nhắn tin qua vệ tinh, hãy đặt Google Tin nhắn làm ứng dụng nhắn tin mặc định của bạn"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Tính năng Liên lạc khẩn cấp qua vệ tinh chưa hoạt động"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Để kiểm tra xem tính năng Liên lạc khẩn cấp qua vệ tinh có hoạt động ở quốc gia hoặc khu vực này không, hãy bật chế độ cài đặt vị trí"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Tính năng nhắn tin qua vệ tinh đang hoạt động"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Bạn có thể nhắn tin qua vệ tinh khi không có mạng di động hay mạng Wi-Fi. Google Tin nhắn phải là ứng dụng nhắn tin mặc định của bạn."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Chưa hỗ trợ tính năng nhắn tin qua vệ tinh"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Thiết bị này chưa hỗ trợ tính năng nhắn tin qua vệ tinh"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Chưa thiết lập tính năng nhắn tin qua vệ tinh"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Hãy kiểm tra để chắc chắn rằng bạn đã kết nối Internet, rồi thử thiết lập lại"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Tính năng nhắn tin qua vệ tinh chưa hoạt động"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Tính năng nhắn tin qua vệ tinh chưa hoạt động ở quốc gia hoặc khu vực này"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Chưa thiết lập tính năng nhắn tin qua vệ tinh"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Để nhắn tin qua vệ tinh, hãy đặt Google Tin nhắn làm ứng dụng nhắn tin mặc định của bạn"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Tính năng nhắn tin qua vệ tinh chưa hoạt động"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Để kiểm tra xem tính năng nhắn tin qua vệ tinh có hoạt động ở quốc gia hoặc khu vực này không, hãy bật chế độ cài đặt vị trí"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Thiết lập lại tính năng Mở khoá bằng vân tay"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Không nhận dạng được <xliff:g id="FINGERPRINT">%s</xliff:g> nữa."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Không nhận dạng được <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nữa."</string>
diff --git a/core/res/res/values-watch-v36/config.xml b/core/res/res/values-watch-v36/config.xml
index bb9da17..679dc70 100644
--- a/core/res/res/values-watch-v36/config.xml
+++ b/core/res/res/values-watch-v36/config.xml
@@ -15,7 +15,6 @@
   -->
 
 <resources>
-    <!-- Overrides system value -->
-    <dimen name="config_buttonCornerRadius">26dp</dimen>
-    <dimen name="config_bottomDialogCornerRadius">18dp</dimen>
+    <dimen name="config_wearMaterial3_buttonCornerRadius">26dp</dimen>
+    <dimen name="config_wearMaterial3_bottomDialogCornerRadius">18dp</dimen>
 </resources>
diff --git a/core/res/res/values-watch-v36/styles_material.xml b/core/res/res/values-watch-v36/styles_material.xml
index b2760e7..7da7435 100644
--- a/core/res/res/values-watch-v36/styles_material.xml
+++ b/core/res/res/values-watch-v36/styles_material.xml
@@ -18,13 +18,13 @@
 <resources>
     <!--  Button Styles  -->
     <!-- Material Button - Filled  -->
-    <style name="Widget.DeviceDefault.Button.Filled" parent="Widget.DeviceDefault.Button">
+    <style name="Widget.DeviceDefault.Button.Filled" parent="Widget.DeviceDefault.Button.WearMaterial3">
         <item name="android:background">@drawable/btn_background_material_filled</item>
         <item name="textAppearance">@style/TextAppearance.Widget.Button.Material.Filled</item>
     </style>
 
     <!-- Material Button - Filled Tonal(Override system default button styles) -->
-    <style name="Widget.DeviceDefault.Button">
+    <style name="Widget.DeviceDefault.Button.WearMaterial3">
         <item name="background">@drawable/btn_background_material_filled_tonal</item>
         <item name="textAppearance">@style/TextAppearance.Widget.Button.Material</item>
         <item name="minHeight">@dimen/btn_material_height</item>
@@ -57,7 +57,7 @@
     </style>
 
     <!--  AlertDialog Styles  -->
-    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog" parent="Widget.DeviceDefault.Button">
+    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3" parent="Widget.DeviceDefault.Button">
         <item name="android:textSize">0sp</item>
         <item name="android:gravity">center</item>
         <item name="android:paddingStart">0dp</item>
@@ -65,14 +65,14 @@
         <item name="android:drawablePadding">0dp</item>
     </style>
 
-    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.Confirm" parent="Widget.DeviceDefault.Button.ButtonBar.AlertDialog">
+    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Confirm">
         <!-- Use a ImageView as background -->
         <item name="background">@android:color/transparent</item>
         <item name="minWidth">@dimen/dialog_btn_confirm_width</item>
         <item name="minHeight">@dimen/dialog_btn_confirm_height</item>
     </style>
 
-    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.Negative" parent="Widget.DeviceDefault.Button.ButtonBar.AlertDialog">
+    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Negative">
         <item name="background">@drawable/dialog_alert_button_negative</item>
         <item name="minWidth">@dimen/dialog_btn_negative_width</item>
         <item name="minHeight">@dimen/dialog_btn_negative_height</item>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index e2f66fc..64c2f70 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允许应用确定附近超宽带设备之间的相对位置"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"与附近的 WLAN 设备互动"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允许该应用向附近的 WLAN 设备进行广播、连接到这些设备以及确定这些设备的相对位置"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"确定附近的设备之间的相对位置"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"允许应用确定附近的设备之间的相对位置"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首选 NFC 付款服务信息"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允许应用获取首选 NFC 付款服务信息,例如注册的应用标识符和路线目的地。"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"控制近距离通信"</string>
@@ -659,7 +657,7 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用屏幕锁定凭据"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"输入您的屏幕锁定凭据才能继续"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"请用力按住传感器"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"无法识别指纹。请重试。"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"无法识别指纹,请重试。"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"请清洁指纹传感器,然后重试"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"请清洁传感器,然后重试"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"请用力按住传感器"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index a2d3280..53c5d15 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置之間的相對位置"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"與附近的 Wi‑Fi 裝置互動"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允許應用程式向附近的 Wi-Fi 裝置顯示此裝置、連接這些裝置並判斷其相對位置"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"判斷附近裝置之間的相對位置"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"允許應用程式判斷附近裝置之間的相對位置"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"由用戶允許授權的 NFC 付款服務資訊"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得由用戶允許授權的 NFC 付款服務資訊 (如已註冊的付款輔助功能和最終付款對象)。"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"開啟"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"返回"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"「緊急衛星連接」現已推出"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"在沒有流動網絡或 Wi-Fi 網絡的情況下,你可向緊急服務收發訊息,但你必須將「Google 訊息」設定為預設訊息應用程式。"</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"不支援「緊急衛星連接」"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"此裝置不支援「緊急衛星連接」"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"未設定「緊急衛星連接」"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"請確保已連接互聯網,然後再試一次"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"無法使用「緊急衛星連接」"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"此國家或地區不支援「緊急衛星連接」"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"未設定「緊急衛星連接」"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"你必須將「Google 訊息」設定為預設訊息應用程式,才能透過衛星收發訊息"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"無法使用「緊急衛星連接」"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"如要查看此國家或地區是否可以使用緊急衛星連接功能,請開啟位置設定"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"可以使用衛星訊息功能"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"在沒有流動網絡或 Wi-Fi 網絡的情況下,你可透過衛星收發訊息,但你必須將「Google 訊息」設定為預設訊息應用程式。"</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"無法使用衛星訊息功能"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"此裝置不支援衛星訊息功能"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"未設定衛星訊息功能"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"請確保已連接互聯網,然後再試一次"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"無法使用衛星訊息功能"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"此國家或地區不支援衛星訊息功能"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"未設定衛星訊息功能"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"你必須將「Google 訊息」設定為預設訊息應用程式,才能透過衛星收發訊息"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"無法使用衛星訊息功能"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"如要查看此國家或地區是否支援衛星訊息功能,請開啟位置設定"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定「指紋解鎖」功能"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"無法再辨識<xliff:g id="FINGERPRINT">%s</xliff:g>。"</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"無法再辨識<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d1f8b5a..cbd6bd2 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置間的相對位置"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"與鄰近的 Wi-Fi 裝置互動"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允許應用程式顯示鄰近的 Wi-Fi 裝置的資料、與其連線並判斷相對位置"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"判斷鄰近裝置間的相對位置"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"允許應用程式判斷鄰近裝置間的相對位置"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首選 NFC 付費服務資訊"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得首選 NFC 付費服務資訊,例如已註冊的輔助工具和路線目的地。"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"開啟"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"返回"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"現在可使用「緊急衛星連線」"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"如果沒有行動網路或 Wi-Fi 網路,也可以傳訊息給緊急救援服務。Google 訊息必須是預設訊息應用程式,你才能使用這項功能。"</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"不支援「緊急衛星連線」"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"這部裝置不支援「緊急衛星連線」"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"未設定「緊急衛星連線」"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"請確定已連上網際網路,然後再重新嘗試設定"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"「緊急衛星連線」無法使用"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"無法在這個國家/地區使用「緊急衛星連線」"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"未設定「緊急衛星連線」"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"如要透過衛星傳送訊息,請將 Google 訊息設為預設訊息應用程式"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"「緊急衛星連線」無法使用"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"如要確認「緊急衛星連線」能否在這個國家/地區使用,請開啟位置資訊設定"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"現在可使用「衛星訊息」"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"如果沒有行動網路或 Wi-Fi 網路,可以透過衛星傳送訊息。Google 訊息必須是預設訊息應用程式,你才能使用這項功能。"</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"不支援「衛星訊息」"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"這部裝置不支援「衛星訊息」"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"未設定「衛星訊息」"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"請確定已連上網際網路,然後再重新嘗試設定"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"「衛星訊息」無法使用"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"無法在這個國家/地區使用「衛星訊息」"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"未設定「衛星訊息」"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"如要透過衛星傳送訊息,請將 Google 訊息設為預設訊息應用程式"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"「衛星訊息」無法使用"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"如要確認「衛星訊息」能否在這個國家/地區使用,請開啟位置資訊設定"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定指紋解鎖"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"系統無法再辨識「<xliff:g id="FINGERPRINT">%s</xliff:g>」。"</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"系統無法再辨識「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index d1b7e51..f498fe2 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -612,10 +612,8 @@
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Vumela i-app inqume indawo ehambelanayo phakathi kwamadivayisi e-Ultra-Wideband aseduze"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"xhumana namadivayisi we-Wi‑Fi aseduze"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Ivumela i-app ikhangise, ixhume, futhi inqume isimo esihambisanayo samadivayisi we-Wi-Fi aseduze"</string>
-    <!-- no translation found for permlab_ranging (2854543350668593390) -->
-    <skip />
-    <!-- no translation found for permdesc_ranging (6703905535621521710) -->
-    <skip />
+    <string name="permlab_ranging" msgid="2854543350668593390">"nquma indawo ehlobene phakathi kwamadivayisi aseduze"</string>
+    <string name="permdesc_ranging" msgid="6703905535621521710">"Vumela i-app inqume indawo ehambelanayo phakathi kwamadivayisi aseduze"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ulwazi Lwesevisi Yenkokhelo Ye-NFC Okhethwayo"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ivuemela uhlelo lokusebenza ukuthola ulwazi lesevisi yenkokhelo ye-nfc njengezinsiza zokubhalisa nezindawo zomzila."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"lawula Uxhumano Lwenkambu Eseduze"</string>
@@ -2435,54 +2433,30 @@
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Vula"</string>
     <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Iya emuva"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Ilindile..."</string>
-    <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
-    <skip />
-    <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
-    <skip />
-    <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
-    <skip />
-    <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
-    <skip />
-    <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
-    <skip />
-    <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
-    <skip />
+    <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Isethelayithi yokuxhumana ngezimo eziphuthumayo isiyatholakala manje"</string>
+    <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Ungathumela imiyalezo kumasevisi ezimo eziphuthumayo uma ingekho inethiwekhi yeselula noma ye-Wi-Fi. IGoogle Messages kumelwe kube iyona app yakho yemiyalezo ezenzekelayo."</string>
+    <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayisekelwe"</string>
+    <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayisekelwe kule divayisi"</string>
+    <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayisethiwe"</string>
+    <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Qiniseka ukuthi uxhumeke ku-inthanethi bese uzama ukusetha futhi"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayitholakali"</string>
+    <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayitholakali kuleli zwe noma kulesi sifunda"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayisethiwe"</string>
+    <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Ukuze uthumele umlayezo ngesathelayithi, setha iGoogle Messages ngenge-app yakho yemilayezo ezenzakalelayo"</string>
+    <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayitholakali"</string>
+    <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Ukuze uhlole ukuthi isethelayithi yokuxhumana ngezimo eziphuthumayo iyatholakala yini kuleli zwe noma kulesi sifunda, vula amasethingi endawo"</string>
+    <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Ukuthumela umyalezo ngesethelayithi kuyatholakala"</string>
+    <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Ungathumela umlayezo ngesathelayithi uma ingekho inethiwekhi yeselula noma ye-Wi-Fi. IGoogle Messages kumelwe kube iyona app yakho yemiyalezo ezenzekelayo."</string>
+    <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Ukuthumela umyalezo ngesethelayithi akusekelwe"</string>
+    <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Ukuthumela umyalezo ngesethelayithi akusekelwe kule divayisi"</string>
+    <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Ukuthumela umyalezo ngesethelayithi akusethiwe"</string>
+    <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Qiniseka ukuthi uxhumeke ku-inthanethi bese uzama ukusetha futhi"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Ukuthumela umyalezo ngesethelayithi akutholakali"</string>
+    <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Ukuthumela umyalezo ngesethelayithi akutholakali kuleli zwe noma kulesi sifunda"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Ukuthumela umyalezo ngesethelayithi akusethiwe"</string>
+    <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Ukuze uthumele umlayezo ngesathelayithi, setha iGoogle Messages ngenge-app yakho yemilayezo ezenzakalelayo"</string>
+    <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Ukuthumela umyalezo ngesethelayithi akutholakali"</string>
+    <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Ukuze uhlole ukuthi ukuthumela umyalezo ngesethelayithi kuyatholakala yini kuleli zwe noma kulesi sifunda, vula amasethingi endawo"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setha Ukuvula ngesigxivizo somunwe futhi"</string>
     <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> angeke isaziwa."</string>
     <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> angeke isaziwa."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f6590b1..8c46ccc 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4808,6 +4808,12 @@
         <!-- Whether the device should default to observe mode when this service is
              default or in the foreground. -->
         <attr name="shouldDefaultToObserveMode" format="boolean"/>
+        <!-- Whether this service should share the same AID routing priority as the role
+             owner. This package and the role owner must have the same signature, and the
+             role owner must opt into this behavior by using the property named by
+             {@link android.nfc.cardemulation.CardEmulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY }
+             in the <code>&lt;application&rt;</code> tag. -->
+        <attr name="shareRolePriority" format="boolean"/>
     </declare-styleable>
 
     <!-- Use <code>offhost-apdu-service</code> as the root tag of the XML resource that
@@ -4835,6 +4841,7 @@
         <!-- Whether the device should default to observe mode when this service is
              default or in the foreground. -->
         <attr name="shouldDefaultToObserveMode"/>
+        <attr name="shareRolePriority"/>
     </declare-styleable>
 
     <!-- Specify one or more <code>aid-group</code> elements inside a
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 7ef5394..cdf184c 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1867,8 +1867,12 @@
          16 KB device. 4 KB natives libs will be loaded app-compat mode if they are eligible.
          @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB) -->
     <attr name="pageSizeCompat">
-        <enum name="enabled" value="5" />
-        <enum name="disabled" value="6" />
+        <!-- value for enabled must match with
+        ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_ENABLED -->
+        <enum name="enabled" value="32" />
+        <!-- value for disabled must match with
+        ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_DISABLED -->
+        <enum name="disabled" value="64" />
     </attr>
 
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 48ce8af..73d696b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2731,6 +2731,8 @@
     </string-array>
     <!-- The list of supported dream complications -->
     <integer-array name="config_supportedDreamComplications">
+        <!-- COMPLICATION_TYPE_TIME -->
+        <item>1</item>
     </integer-array>
 
     <!-- Are we allowed to dream while not plugged in? -->
@@ -6001,6 +6003,12 @@
     <!-- If true, show multiuser switcher by default unless the user specifically disables it. -->
     <bool name="config_showUserSwitcherByDefault">false</bool>
 
+    <!-- If true, user can change state of multiuser switcher. -->
+    <bool name="config_allowChangeUserSwitcherEnabled">true</bool>
+
+    <!-- If true, multiuser switcher would be automatically enabled when second user is created on the device. -->
+    <bool name="config_enableUserSwitcherUponUserCreation">true</bool>
+
     <!-- Set to true to make assistant show in front of the dream/screensaver. -->
     <bool name="config_assistantOnTopOfDream">false</bool>
 
@@ -7237,4 +7245,10 @@
 
     <!-- The name of the system package that will hold the dependency installer role. -->
     <string name="config_systemDependencyInstaller" translatable="false" />
+
+    <!-- Whether allow normal brightness when doze policy can be requested. When this is false,
+        brightness follows the display state i.e. ON means bright, DOZE means dim. If true,
+        POLICY_DOZE can also dim the screen unless parameter useNormalBrightnessForDoze of
+        DreamService#setDozeScreenState requests an exception. -->
+    <bool name="config_allowNormalBrightnessForDozePolicy">false</bool>
 </resources>
diff --git a/core/res/res/values/config_display.xml b/core/res/res/values/config_display.xml
index 2e66060..c458d0e9 100644
--- a/core/res/res/values/config_display.xml
+++ b/core/res/res/values/config_display.xml
@@ -29,5 +29,7 @@
 
     <!-- Whether even dimmer feature is enabled. -->
     <bool name="config_evenDimmerEnabled">false</bool>
+    <!-- Jar file path to look for PluginProvider -->
+    <string name="config_pluginsProviderJarPath"/>
 
 </resources>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 6378d5a..e8063a2 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -466,6 +466,11 @@
     <integer name="config_satellite_location_query_throttle_interval_minutes">10</integer>
     <java-symbol type="integer" name="config_satellite_location_query_throttle_interval_minutes" />
 
+    <!-- The file contains satellite access configuration like supported frequencies, bands,
+    satellite positions, and so on -->
+    <string name="satellite_access_config_file" translatable="false"></string>
+    <java-symbol type="string" name="satellite_access_config_file" />
+
     <!-- 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" />
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 3757487..c8df662 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -1055,12 +1055,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" 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>
+    <dimen name="system_app_widget_background_radius" android:featureFlag="!android.appwidget.flags.use_smaller_app_widget_system_radius">28dp</dimen>
+    <dimen name="system_app_widget_background_radius" android:featureFlag="android.appwidget.flags.use_smaller_app_widget_system_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>
+    <dimen name="system_app_widget_inner_radius" android:featureFlag="!android.appwidget.flags.use_smaller_app_widget_system_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>
+    <dimen name="system_app_widget_inner_radius" android:featureFlag="android.appwidget.flags.use_smaller_app_widget_system_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/values/ids.xml b/core/res/res/values/ids.xml
index e71277d..3b39a65 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -290,4 +290,7 @@
 
   <!-- View tag associating a view with its overridden id, to ensure valid recycling only. -->
   <item type="id" name="remote_views_override_id" />
+
+  <!-- View tag associating a view with its id for widget metrics. -->
+  <item type="id" name="remoteViewsMetricsId" />
 </resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index b0b87d1d..e75371d 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -133,9 +133,13 @@
     <public name="alternateLauncherLabels"/>
     <!-- @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB) -->
     <public name="pageSizeCompat" />
+    <!-- @FlaggedApi(android.nfc.Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES) -->
+    <public name="shareRolePriority"/>
   </staging-public-group>
 
   <staging-public-group type="id" first-id="0x01b60000">
+    <!-- @FlaggedApi(android.appwidget.flags.Flags.FLAG_ENGAGEMENT_METRICS) -->
+    <public name="remoteViewsMetricsId"/>
   </staging-public-group>
 
   <staging-public-group type="style" first-id="0x01b50000">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c13fdb1..d498b91 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -199,6 +199,21 @@
     <!-- Displayed to confirm to the user that caller ID will not be restricted on the next call or in general. -->
     <string name="CLIRDefaultOffNextCallOff">Caller ID defaults to not restricted. Next call: Not restricted</string>
 
+    <!-- Message displayed in dialog when APK is not 16 KB aligned. [CHAR LIMIT=NONE] -->
+    <string name="page_size_compat_apk_warning">This app isn’t 16 KB compatible. APK alignment check failed.
+        This app will be run using page size compatible mode. For best compatibility, please recompile the application with 16 KB support.
+        For more information, see &lt;a href=\"https://developer.android.com/16kb-page-size\"&gt;https://developer.android.com/16kb-page-size&lt;/a&gt; </string>
+
+    <!-- Message displayed in dialog when ELF is not 16 KB aligned. [CHAR LIMIT=NONE] -->
+    <string name="page_size_compat_elf_warning">This app isn’t 16 KB compatible. ELF alignment check failed.
+        This app will be run using page size compatible mode. For best compatibility, please recompile the application with 16 KB support.
+        For more information, see &lt;a href=\"https://developer.android.com/16kb-page-size\"&gt;https://developer.android.com/16kb-page-size&lt;/a&gt;</string>
+
+    <!-- Message displayed in dialog when APK and ELF are not 16 KB aligned. [CHAR LIMIT=NONE] -->
+    <string name="page_size_compat_apk_and_elf_warning">This app isn’t 16 KB compatible. APK and ELF alignment checks failed.
+        This app will be run using page size compatible mode. For best compatibility, please recompile the application with 16 KB support.
+        For more information, see &lt;a href=\"https://developer.android.com/16kb-page-size\"&gt;https://developer.android.com/16kb-page-size&lt;/a&gt;</string>
+
 
     <!-- Displayed to tell the user that caller ID is not provisioned for their SIM. -->
     <string name="serviceNotProvisioned">Service not provisioned.</string>
@@ -5357,6 +5372,8 @@
     <string name="zen_mode_trigger_summary_range_symbol_combination"><xliff:g id="start" example="Sun">%1$s</xliff:g> - <xliff:g id="end" example="Thu">%2$s</xliff:g></string>
     <!-- [CHAR LIMIT=40] General template for a start - end range in a text summary, used for the trigger description of a Zen mode -->
     <string name="zen_mode_trigger_summary_range_words"><xliff:g id="start" example="Sunday">%1$s</xliff:g> to <xliff:g id="end" example="Thursday">%2$s</xliff:g></string>
+    <!-- [CHAR LIMIT=NONE] General template for combining a days of week start-end range with a time-based start-end range, for example: "Sun-Thurs, 10:00 PM - 7:00 AM" -->
+    <string name="zen_mode_trigger_summary_combined"><xliff:g id="days" example="Sat-Thurs">%1$s</xliff:g>,\u0020<xliff:g id="times" example="10:00 PM - 7:00 AM">%2$s</xliff:g></string>
     <!-- [CHAR LIMIT=40] Event-based rule calendar option value for any calendar, used for the trigger description of a Zen mode -->
     <string name="zen_mode_trigger_event_calendar_any">Any calendar</string>
 
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 3b2f244..acc1ff8 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -43,6 +43,7 @@
         <item name="textAppearance">?attr/textAppearanceButton</item>
         <item name="textColor">@color/btn_colored_text_material</item>
     </style>
+    <style name="Widget.DeviceDefault.Button.WearMaterial3"/>
     <style name="Widget.DeviceDefault.TextView" parent="Widget.Material.TextView" />
     <style name="Widget.DeviceDefault.CheckedTextView" parent="Widget.Material.CheckedTextView"/>
     <style name="Widget.DeviceDefault.AutoCompleteTextView" parent="Widget.Material.AutoCompleteTextView"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1d3e85f..c817269 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2390,8 +2390,11 @@
   <java-symbol type="layout" name="notification_material_action_list" />
   <java-symbol type="layout" name="notification_material_action_tombstone" />
   <java-symbol type="layout" name="notification_2025_template_collapsed_base" />
+  <java-symbol type="layout" name="notification_2025_template_expanded_base" />
   <java-symbol type="layout" name="notification_2025_template_heads_up_base" />
   <java-symbol type="layout" name="notification_2025_template_header" />
+  <java-symbol type="layout" name="notification_2025_template_collapsed_messaging" />
+  <java-symbol type="layout" name="notification_2025_template_collapsed_media" />
   <java-symbol type="layout" name="notification_template_material_base" />
   <java-symbol type="layout" name="notification_template_material_heads_up_base" />
   <java-symbol type="layout" name="notification_template_material_compact_heads_up_base" />
@@ -2666,6 +2669,7 @@
   <java-symbol type="string" name="zen_mode_trigger_summary_divider_text" />
   <java-symbol type="string" name="zen_mode_trigger_summary_range_symbol_combination" />
   <java-symbol type="string" name="zen_mode_trigger_summary_range_words" />
+  <java-symbol type="string" name="zen_mode_trigger_summary_combined" />
   <java-symbol type="string" name="zen_mode_trigger_event_calendar_any" />
 
   <java-symbol type="string" name="display_rotation_camera_compat_toast_after_rotation" />
@@ -3308,6 +3312,11 @@
   <java-symbol type="string" name="language_selection_title" />
   <java-symbol type="string" name="search_language_hint" />
 
+  <!-- Strings for page size app compat dialog -->
+  <java-symbol type="string" name="page_size_compat_apk_warning" />
+  <java-symbol type="string" name="page_size_compat_elf_warning" />
+  <java-symbol type="string" name="page_size_compat_apk_and_elf_warning" />
+
   <!--  Work profile unlaunchable app alert dialog-->
   <java-symbol type="style" name="AlertDialogWithEmergencyButton"/>
   <java-symbol type="string" name="work_mode_emergency_call_button" />
@@ -3439,6 +3448,8 @@
   <!-- Notifications: CallStyle -->
   <java-symbol type="layout" name="notification_template_material_call" />
   <java-symbol type="layout" name="notification_template_material_big_call" />
+  <java-symbol type="layout" name="notification_2025_template_collapsed_call" />
+  <java-symbol type="layout" name="notification_2025_template_expanded_call" />
   <java-symbol type="string" name="call_notification_answer_action" />
   <java-symbol type="string" name="call_notification_answer_video_action" />
   <java-symbol type="string" name="call_notification_decline_action" />
@@ -4090,6 +4101,7 @@
   <java-symbol type="layout" name="notification_template_messaging_text_message" />
   <java-symbol type="layout" name="notification_template_messaging_image_message" />
   <java-symbol type="layout" name="notification_template_messaging_group" />
+  <java-symbol type="layout" name="notification_2025_messaging_group" />
   <java-symbol type="id" name="message_text" />
   <java-symbol type="id" name="message_name" />
   <java-symbol type="id" name="message_icon" />
@@ -4620,9 +4632,11 @@
   <java-symbol type="dimen" name="conversation_icon_container_top_padding" />
   <java-symbol type="dimen" name="conversation_icon_container_top_padding_small_avatar" />
   <java-symbol type="layout" name="notification_template_material_conversation" />
+  <java-symbol type="layout" name="notification_2025_template_conversation" />
   <java-symbol type="dimen" name="button_padding_horizontal_material" />
   <java-symbol type="dimen" name="button_inset_horizontal_material" />
   <java-symbol type="layout" name="conversation_face_pile_layout" />
+  <java-symbol type="layout" name="notification_2025_conversation_face_pile_layout" />
   <java-symbol type="string" name="unread_convo_overflow" />
   <java-symbol type="drawable" name="conversation_badge_background" />
   <java-symbol type="drawable" name="conversation_badge_ring" />
@@ -4693,6 +4707,8 @@
 
   <!-- If true, show multiuser switcher by default unless the user specifically disables it. -->
   <java-symbol type="bool" name="config_showUserSwitcherByDefault" />
+  <java-symbol type="bool" name="config_allowChangeUserSwitcherEnabled" />
+  <java-symbol type="bool" name="config_enableUserSwitcherUponUserCreation" />
 
   <!-- Set to true to make assistant show in front of the dream/screensaver. -->
   <java-symbol type="bool" name="config_assistantOnTopOfDream"/>
@@ -5109,7 +5125,6 @@
   <java-symbol type="layout" name="notification_expand_button"/>
   <java-symbol type="id" name="close_button" />
   <java-symbol type="layout" name="notification_close_button"/>
-  <java-symbol type="id" name="notification_buttons_column" />
 
   <java-symbol type="bool" name="config_supportsMicToggle" />
   <java-symbol type="bool" name="config_supportsCamToggle" />
@@ -5318,6 +5333,91 @@
   <java-symbol type="integer" name="config_accumulatedBatteryUsageStatsSpanSize" />
 
   <!--Dynamic Tokens-->
+  <java-symbol name="materialColorBackground" type="color"/>
+  <java-symbol name="materialColorControlActivated" type="color"/>
+  <java-symbol name="materialColorControlHighlight" type="color"/>
+  <java-symbol name="materialColorControlNormal" type="color"/>
+  <java-symbol name="materialColorError" type="color"/>
+  <java-symbol name="materialColorErrorContainer" type="color"/>
+  <java-symbol name="materialColorInverseOnSurface" type="color"/>
+  <java-symbol name="materialColorInversePrimary" type="color"/>
+  <java-symbol name="materialColorInverseSurface" type="color"/>
+  <java-symbol name="materialColorOnBackground" type="color"/>
+  <java-symbol name="materialColorOnError" type="color"/>
+  <java-symbol name="materialColorOnErrorContainer" type="color"/>
+  <java-symbol name="materialColorOnPrimary" type="color"/>
+  <java-symbol name="materialColorOnPrimaryContainer" type="color"/>
+  <java-symbol name="materialColorOnSecondary" type="color"/>
+  <java-symbol name="materialColorOnSecondaryContainer" type="color"/>
+  <java-symbol name="materialColorOnSurface" type="color"/>
+  <java-symbol name="materialColorOnSurfaceVariant" type="color"/>
+  <java-symbol name="materialColorOnTertiary" type="color"/>
+  <java-symbol name="materialColorOnTertiaryContainer" type="color"/>
+  <java-symbol name="materialColorOutline" type="color"/>
+  <java-symbol name="materialColorOutlineVariant" type="color"/>
+  <java-symbol name="materialColorPaletteKeyColorNeutral" type="color"/>
+  <java-symbol name="materialColorPaletteKeyColorNeutralVariant" type="color"/>
+  <java-symbol name="materialColorPaletteKeyColorPrimary" type="color"/>
+  <java-symbol name="materialColorPaletteKeyColorSecondary" type="color"/>
+  <java-symbol name="materialColorPaletteKeyColorTertiary" type="color"/>
+  <java-symbol name="materialColorPrimary" type="color"/>
+  <java-symbol name="materialColorPrimaryContainer" type="color"/>
+  <java-symbol name="materialColorScrim" type="color"/>
+  <java-symbol name="materialColorSecondary" type="color"/>
+  <java-symbol name="materialColorSecondaryContainer" type="color"/>
+  <java-symbol name="materialColorShadow" type="color"/>
+  <java-symbol name="materialColorSurface" type="color"/>
+  <java-symbol name="materialColorSurfaceBright" type="color"/>
+  <java-symbol name="materialColorSurfaceContainer" type="color"/>
+  <java-symbol name="materialColorSurfaceContainerHigh" type="color"/>
+  <java-symbol name="materialColorSurfaceContainerHighest" type="color"/>
+  <java-symbol name="materialColorSurfaceContainerLow" type="color"/>
+  <java-symbol name="materialColorSurfaceContainerLowest" type="color"/>
+  <java-symbol name="materialColorSurfaceDim" type="color"/>
+  <java-symbol name="materialColorSurfaceTint" type="color"/>
+  <java-symbol name="materialColorSurfaceVariant" type="color"/>
+  <java-symbol name="materialColorTertiary" type="color"/>
+  <java-symbol name="materialColorTertiaryContainer" type="color"/>
+  <java-symbol name="materialColorTextHintInverse" type="color"/>
+  <java-symbol name="materialColorTextPrimaryInverse" type="color"/>
+  <java-symbol name="materialColorTextPrimaryInverseDisableOnly" type="color"/>
+  <java-symbol name="materialColorTextSecondaryAndTertiaryInverse" type="color"/>
+  <java-symbol name="materialColorTextSecondaryAndTertiaryInverseDisabled" type="color"/>
+  <java-symbol name="materialColorOnPrimaryFixed" type="color"/>
+  <java-symbol name="materialColorOnPrimaryFixedVariant" type="color"/>
+  <java-symbol name="materialColorOnSecondaryFixed" type="color"/>
+  <java-symbol name="materialColorOnSecondaryFixedVariant" type="color"/>
+  <java-symbol name="materialColorOnTertiaryFixed" type="color"/>
+  <java-symbol name="materialColorOnTertiaryFixedVariant" type="color"/>
+  <java-symbol name="materialColorPrimaryFixed" type="color"/>
+  <java-symbol name="materialColorPrimaryFixedDim" type="color"/>
+  <java-symbol name="materialColorSecondaryFixed" type="color"/>
+  <java-symbol name="materialColorSecondaryFixedDim" type="color"/>
+  <java-symbol name="materialColorTertiaryFixed" type="color"/>
+  <java-symbol name="materialColorTertiaryFixedDim" type="color"/>
+  <java-symbol name="customColorBrandA" type="color"/>
+  <java-symbol name="customColorBrandB" type="color"/>
+  <java-symbol name="customColorBrandC" type="color"/>
+  <java-symbol name="customColorBrandD" type="color"/>
+  <java-symbol name="customColorClockHour" type="color"/>
+  <java-symbol name="customColorClockMinute" type="color"/>
+  <java-symbol name="customColorClockSecond" type="color"/>
+  <java-symbol name="customColorOnShadeActive" type="color"/>
+  <java-symbol name="customColorOnShadeActiveVariant" type="color"/>
+  <java-symbol name="customColorOnShadeInactive" type="color"/>
+  <java-symbol name="customColorOnShadeInactiveVariant" type="color"/>
+  <java-symbol name="customColorOnThemeApp" type="color"/>
+  <java-symbol name="customColorOverviewBackground" type="color"/>
+  <java-symbol name="customColorShadeActive" type="color"/>
+  <java-symbol name="customColorShadeDisabled" type="color"/>
+  <java-symbol name="customColorShadeInactive" type="color"/>
+  <java-symbol name="customColorThemeApp" type="color"/>
+  <java-symbol name="customColorThemeAppRing" type="color"/>
+  <java-symbol name="customColorThemeNotif" type="color"/>
+  <java-symbol name="customColorUnderSurface" type="color"/>
+  <java-symbol name="customColorWeatherTemp" type="color"/>
+  <java-symbol name="customColorWidgetBackground" type="color"/>
+
   <java-symbol type="attr" name="materialColorBackground"/>
   <java-symbol type="attr" name="materialColorControlActivated"/>
   <java-symbol type="attr" name="materialColorControlHighlight"/>
@@ -5607,6 +5707,7 @@
 
   <!-- DisplayManager configs. -->
   <java-symbol type="bool" name="config_evenDimmerEnabled" />
+  <java-symbol type="string" name="config_pluginsProviderJarPath" />
 
   <java-symbol type="bool" name="config_watchlistUseFileHashesCache" />
   <java-symbol type="string" name="config_defaultContextualSearchPackageName" />
@@ -5711,4 +5812,9 @@
 
   <!-- Fingerprint screen off unlock config -->
   <java-symbol type="bool" name="config_screen_off_udfps_enabled" />
+
+  <!-- Style for Wear Material3 Button. Will only be used for sdk 36 or above. -->
+  <java-symbol type="style" name="Widget.DeviceDefault.Button.WearMaterial3" />
+
+  <java-symbol type="bool" name="config_allowNormalBrightnessForDozePolicy" />
 </resources>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_ltr.9.png b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_ltr.9.png
new file mode 100644
index 0000000..c7e937c
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_ltr.9.png
Binary files differ
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_tr.9.png b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_tr.9.png
new file mode 100644
index 0000000..a3cff98
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_tr.9.png
Binary files differ
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/power_other_24.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/power_other_24.xml
new file mode 100644
index 0000000..c9fb53e
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/power_other_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="?attr/colorControlNormal"
+    android:viewportHeight="960"
+    android:viewportWidth="960">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M720,600L720,520L800,520Q817,520 828.5,531.5Q840,543 840,560Q840,577 828.5,588.5Q817,600 800,600L720,600ZM720,760L720,680L800,680Q817,680 828.5,691.5Q840,703 840,720Q840,737 828.5,748.5Q817,760 800,760L720,760ZM560,800Q527,800 503.5,776.5Q480,753 480,720L400,720L400,560L480,560Q480,527 503.5,503.5Q527,480 560,480L680,480L680,800L560,800ZM280,680Q214,680 167,633Q120,586 120,520Q120,454 167,407Q214,360 280,360L340,360Q365,360 382.5,342.5Q400,325 400,300Q400,275 382.5,257.5Q365,240 340,240L200,240Q183,240 171.5,228.5Q160,217 160,200Q160,183 171.5,171.5Q183,160 200,160L340,160Q398,160 439,201Q480,242 480,300Q480,358 439,399Q398,440 340,440L280,440Q247,440 223.5,463.5Q200,487 200,520Q200,553 223.5,576.5Q247,600 280,600L360,600L360,680L280,680Z" />
+</vector>
\ No newline at end of file
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_off_24.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_off_24.xml
new file mode 100644
index 0000000..ca94825
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_off_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="?attr/colorControlNormal"
+    android:viewportHeight="960"
+    android:viewportWidth="960">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M280,920Q247,920 223.5,896.5Q200,873 200,840L200,120Q200,87 223.5,63.5Q247,40 280,40L680,40Q713,40 736.5,63.5Q760,87 760,120L760,840Q760,873 736.5,896.5Q713,920 680,920L280,920ZM280,800L280,840Q280,840 280,840Q280,840 280,840L680,840Q680,840 680,840Q680,840 680,840L680,800L280,800ZM280,720L680,240L280,720ZM280,160L680,160L680,120Q680,120 680,120Q680,120 680,120L280,120Q280,120 280,120Q280,120 280,120L280,160ZM280,160L280,120Q280,120 280,120Q280,120 280,120L280,120Q280,120 280,120Q280,120 280,120L280,160ZM280,800L280,800L280,840Q280,840 280,840Q280,840 280,840L280,840Q280,840 280,840Q280,840 280,840L280,800Z" />
+</vector>
\ No newline at end of file
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_on_24.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_on_24.xml
new file mode 100644
index 0000000..48f990c
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_on_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="?attr/colorControlNormal"
+    android:viewportHeight="960"
+    android:viewportWidth="960">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M280,920Q247,920 223.5,896.5Q200,873 200,840L200,120Q200,87 223.5,63.5Q247,40 280,40L680,40Q713,40 736.5,63.5Q760,87 760,120L760,840Q760,873 736.5,896.5Q713,920 680,920L280,920ZM280,800L280,840Q280,840 280,840Q280,840 280,840L680,840Q680,840 680,840Q680,840 680,840L680,800L280,800ZM280,720L680,720L680,240L280,240L280,720ZM280,160L680,160L680,120Q680,120 680,120Q680,120 680,120L280,120Q280,120 280,120Q280,120 280,120L280,160ZM280,160L280,120Q280,120 280,120Q280,120 280,120L280,120Q280,120 280,120Q280,120 280,120L280,160ZM280,800L280,800L280,840Q280,840 280,840Q280,840 280,840L280,840Q280,840 280,840Q280,840 280,840L280,800Z" />
+</vector>
\ No newline at end of file
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
index be0e135..e1f4623 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   ~ Copyright (C) 2020 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,46 +13,127 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="horizontal"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:paddingTop="8dp"
-    android:paddingBottom="8dp">
+    android:orientation="vertical">
 
-    <ImageView
-        android:id="@+id/icon"
-        android:layout_width="wrap_content"
+    <LinearLayout
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:layout_marginEnd="8dp"
-        android:paddingBottom="8dp"/>
+        android:minHeight="?android:attr/listPreferredItemHeightSmall"
+        android:orientation="horizontal"
+        android:paddingBottom="8dp"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:paddingTop="8dp">
 
-    <TextView
-        android:id="@+id/title"
-        android:layout_width="0dp"
-        android:layout_weight="1"
-        android:layout_height="wrap_content"
-        android:textAppearance="@style/TextAppearanceBody"/>
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_marginEnd="8dp"
+            android:paddingBottom="8dp" />
 
-    <TextView
-        android:id="@+id/value1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
-        android:gravity="right"
-        android:maxLines="1"
-        android:textAppearance="@style/TextAppearanceBody"/>
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:textAppearance="@style/TextAppearanceBody" />
 
-    <TextView
-        android:id="@+id/value2"
-        android:layout_width="76dp"
+        <TextView
+            android:id="@+id/value1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:gravity="right"
+            android:maxLines="1"
+            android:textAppearance="@style/TextAppearanceBody" />
+
+        <TextView
+            android:id="@+id/value2"
+            android:layout_width="76dp"
+            android:layout_height="wrap_content"
+            android:gravity="right"
+            android:maxLines="1"
+            android:textAppearance="@style/TextAppearanceBody" />
+    </LinearLayout>
+
+    <TableLayout
+        android:id="@+id/table"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:gravity="right"
-        android:maxLines="1"
-        android:textAppearance="@style/TextAppearanceBody"/>
+        android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:layout_marginStart="50dp"
+        android:stretchColumns="1,2,3,4">
+
+        <TableRow android:background="#EEFFEE">
+            <LinearLayout
+                style="@style/TableCell.Start"
+                android:layout_width="65dp">
+            <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:padding="3dip"
+                    android:text="State"
+                    android:textStyle="bold" />
+            </LinearLayout>
+
+            <RelativeLayout style="@style/TableCell.Inner">
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerInParent="true"
+                    android:src="@drawable/screen_on_24"
+                    android:tint="@color/battery_consumer_slice_icon" />
+            </RelativeLayout>
+
+            <RelativeLayout style="@style/TableCell.Inner">
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerInParent="true"
+                    android:src="@drawable/screen_off_24"
+                    android:tint="@color/battery_consumer_slice_icon" />
+            </RelativeLayout>
+
+            <RelativeLayout style="@style/TableCell.Inner">
+                <ImageView
+                    android:id="@+id/screen_on_24_icon"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerInParent="true"
+                    android:src="@drawable/screen_on_24"
+                    android:tint="@color/battery_consumer_slice_icon" />
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_toRightOf="@id/screen_on_24_icon"
+                    android:src="@drawable/power_other_24"
+                    android:tint="@color/battery_consumer_slice_icon" />
+            </RelativeLayout>
+
+            <RelativeLayout style="@style/TableCell.End">
+                <ImageView
+                    android:id="@+id/screen_off_24_icon"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerInParent="true"
+                    android:src="@drawable/screen_off_24"
+                    android:tint="@color/battery_consumer_slice_icon" />
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_toRightOf="@id/screen_off_24_icon"
+                    android:src="@drawable/power_other_24"
+                    android:tint="@color/battery_consumer_slice_icon" />
+            </RelativeLayout>
+        </TableRow>
+
+        <View
+            android:layout_height="1dip"
+            android:background="#000000" />
+    </TableLayout>
 </LinearLayout>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
index 987de6b..b88425a 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
@@ -14,16 +14,30 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/swipe_refresh"
-    android:paddingTop="?attr/actionBarSize"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:fitsSystemWindows="true">
 
-    <androidx.recyclerview.widget.RecyclerView
-        android:id="@+id/list_view"
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/toolbar"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
+        android:layout_height="?attr/actionBarSize"
+        android:background="?attr/colorPrimary"
+        android:elevation="4dp"
+        android:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
 
-</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+        android:id="@+id/swipe_refresh"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1">
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/list_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+
+    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+</LinearLayout>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_slices_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_slices_layout.xml
new file mode 100644
index 0000000..642c0de
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_slices_layout.xml
@@ -0,0 +1,87 @@
+<?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.
+  -->
+
+<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <LinearLayout style="@style/TableCell.Start">
+        <TextView
+            android:id="@+id/procState"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <LinearLayout
+        style="@style/TableCell.Inner"
+        android:orientation="vertical">
+        <TextView
+            android:id="@+id/power_b_on"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right" />
+        <TextView
+            android:id="@+id/duration_b_on"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right" />
+    </LinearLayout>
+
+    <LinearLayout
+        style="@style/TableCell.Inner"
+        android:orientation="vertical">
+        <TextView
+            android:id="@+id/power_b_off"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right" />
+        <TextView
+            android:id="@+id/duration_b_off"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right" />
+    </LinearLayout>
+
+    <LinearLayout
+        style="@style/TableCell.Inner"
+        android:orientation="vertical">
+        <TextView
+            android:id="@+id/power_c_on"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right" />
+        <TextView
+            android:id="@+id/duration_c_on"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right" />
+    </LinearLayout>
+
+    <LinearLayout
+        style="@style/TableCell.End"
+        android:orientation="vertical">
+        <TextView
+            android:id="@+id/power_c_off"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right" />
+        <TextView
+            android:id="@+id/duration_c_off"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right" />
+    </LinearLayout>
+</TableRow>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
index 2d276a5..46d8f04 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
@@ -17,13 +17,12 @@
 <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/swipe_refresh"
-    android:paddingTop="?attr/actionBarSize"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:fitsSystemWindows="true">
 
     <LinearLayout
         android:orientation="vertical"
-        android:paddingTop="?attr/actionBarSize"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/values/colors.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/values/colors.xml
index 6cc70bd..1dc288a 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/values/colors.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/values/colors.xml
@@ -18,4 +18,5 @@
 <resources>
     <color name="battery_consumer_bg_power_profile">#ffffff</color>
     <color name="battery_consumer_bg_energy_consumption">#fff5eb</color>
+    <color name="battery_consumer_slice_icon">#aaaaaa</color>
 </resources>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml
index fa30b2c..a298cc9 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml
@@ -17,11 +17,9 @@
   -->
 
 <resources>
-    <style name="Theme" parent="Theme.MaterialComponents.Light">
+    <style name="Theme" parent="Theme.MaterialComponents.Light.NoActionBar">
         <item name="colorPrimary">#34a853</item>
-        <item name="android:windowActionBar">true</item>
-        <item name="android:windowNoTitle">false</item>
-        <item name="android:windowDrawsSystemBarBackgrounds">false</item>
+        <item name="toolbarStyle">@style/Widget.AppCompat.Toolbar</item>
     </style>
 
     <style name="LoadTestCardView" parent="Widget.MaterialComponents.CardView">
@@ -32,4 +30,25 @@
         <item name="android:textColor">#000000</item>
         <item name="android:textSize">18sp</item>
     </style>
-</resources>
\ No newline at end of file
+
+    <style name="TableCell">
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:padding">4dp</item>
+    </style>
+
+    <style name="TableCell.Start" parent="TableCell">
+        <item name="android:background">@drawable/border_ltr</item>
+    </style>
+
+    <style name="TableCell.Inner" parent="TableCell">
+        <item name="android:background">@drawable/border_tr</item>
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_weight">1</item>
+    </style>
+
+    <style name="TableCell.End" parent="TableCell">
+        <item name="android:background">@drawable/border_tr</item>
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_weight">1</item>
+    </style>
+</resources>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
index f691a1b..35175a7 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
@@ -31,22 +31,16 @@
     public static final String UID_BATTERY_CONSUMER_ID_PREFIX = "APP|";
     public static final String AGGREGATE_BATTERY_CONSUMER_ID = "SYS|";
 
-    enum EntryType {
-        UID_TOTAL_POWER,
-        UID_POWER_PROFILE,
-        UID_POWER_PROFILE_PROCESS_STATE,
-        UID_POWER_ENERGY_CONSUMPTION,
-        UID_POWER_ENERGY_PROCESS_STATE,
-        UID_POWER_CUSTOM,
-        UID_DURATION,
+    public enum EntryType {
         DEVICE_TOTAL_POWER,
-        DEVICE_POWER_MODELED,
+        DEVICE_POWER,
         DEVICE_POWER_ENERGY_CONSUMPTION,
         DEVICE_POWER_CUSTOM,
         DEVICE_DURATION,
+        UID,
     }
 
-    enum ConsumerType {
+    public enum ConsumerType {
         UID_BATTERY_CONSUMER,
         DEVICE_POWER_COMPONENT,
     }
@@ -56,34 +50,38 @@
         public String title;
         public double value1;
         public double value2;
+        public List<Slice> slices;
+    }
+
+    public static class Slice {
+        public int powerState;
+        public int screenState;
+        public int processState;
+        public double powerMah;
+        public long durationMs;
     }
 
     private BatteryConsumerInfoHelper.BatteryConsumerInfo mBatteryConsumerInfo;
     private final List<Entry> mEntries = new ArrayList<>();
 
     public BatteryConsumerData(Context context,
-            List<BatteryUsageStats> batteryUsageStatsList, String batteryConsumerId) {
+            BatteryUsageStats batteryUsageStats, String batteryConsumerId) {
         switch (getConsumerType(batteryConsumerId)) {
             case UID_BATTERY_CONSUMER:
-                populateForUidBatteryConsumer(context, batteryUsageStatsList, batteryConsumerId);
+                populateForUidBatteryConsumer(context, batteryUsageStats, batteryConsumerId);
                 break;
             case DEVICE_POWER_COMPONENT:
-                populateForAggregateBatteryConsumer(context, batteryUsageStatsList);
+                populateForAggregateBatteryConsumer(context, batteryUsageStats);
                 break;
         }
     }
 
-    private void populateForUidBatteryConsumer(
-            Context context, List<BatteryUsageStats> batteryUsageStatsList,
+    private void populateForUidBatteryConsumer(Context context, BatteryUsageStats batteryUsageStats,
             String batteryConsumerId) {
-        BatteryUsageStats batteryUsageStats = batteryUsageStatsList.get(0);
-        BatteryUsageStats modeledBatteryUsageStats = batteryUsageStatsList.get(1);
         BatteryConsumer requestedBatteryConsumer = getRequestedBatteryConsumer(batteryUsageStats,
                 batteryConsumerId);
-        BatteryConsumer requestedModeledBatteryConsumer = getRequestedBatteryConsumer(
-                modeledBatteryUsageStats, batteryConsumerId);
 
-        if (requestedBatteryConsumer == null || requestedModeledBatteryConsumer == null) {
+        if (requestedBatteryConsumer == null) {
             mBatteryConsumerInfo = null;
             return;
         }
@@ -92,118 +90,95 @@
                 batteryUsageStats, batteryConsumerId, context.getPackageManager());
 
         double[] totalPowerByComponentMah = new double[BatteryConsumer.POWER_COMPONENT_COUNT];
-        double[] totalModeledPowerByComponentMah =
-                new double[BatteryConsumer.POWER_COMPONENT_COUNT];
         long[] totalDurationByComponentMs = new long[BatteryConsumer.POWER_COMPONENT_COUNT];
-        final int customComponentCount =
-                requestedBatteryConsumer.getCustomPowerComponentCount();
+        final int customComponentCount = requestedBatteryConsumer.getCustomPowerComponentCount();
         double[] totalCustomPowerByComponentMah = new double[customComponentCount];
 
         computeTotalPower(batteryUsageStats, totalPowerByComponentMah);
-        computeTotalPower(modeledBatteryUsageStats, totalModeledPowerByComponentMah);
         computeTotalPowerForCustomComponent(batteryUsageStats, totalCustomPowerByComponentMah);
         computeTotalDuration(batteryUsageStats, totalDurationByComponentMs);
 
-        if (isPowerProfileModelsOnly(requestedBatteryConsumer)) {
-            addEntry("Consumed", EntryType.UID_TOTAL_POWER,
-                    requestedBatteryConsumer.getConsumedPower(),
-                    batteryUsageStats.getAggregateBatteryConsumer(
-                            BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
-                            .getConsumedPower());
-        } else {
-            addEntry("Consumed (PowerStats)", EntryType.UID_TOTAL_POWER,
-                    requestedBatteryConsumer.getConsumedPower(),
-                    batteryUsageStats.getAggregateBatteryConsumer(
-                            BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
-                            .getConsumedPower());
-            addEntry("Consumed (PowerProfile)", EntryType.UID_TOTAL_POWER,
-                    requestedModeledBatteryConsumer.getConsumedPower(),
-                    modeledBatteryUsageStats.getAggregateBatteryConsumer(
-                            BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
-                            .getConsumedPower());
+        Entry totalsEntry = addEntry("Consumed", EntryType.UID,
+                requestedBatteryConsumer.getConsumedPower(),
+                batteryUsageStats.getAggregateBatteryConsumer(
+                                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
+                        .getConsumedPower());
+        addSlices(totalsEntry, requestedBatteryConsumer, BatteryConsumer.POWER_COMPONENT_BASE);
+        for (Slice slice : totalsEntry.slices) {
+            slice.powerMah = requestedBatteryConsumer.getConsumedPower(
+                    new BatteryConsumer.Dimensions(BatteryConsumer.POWER_COMPONENT_ANY,
+                            slice.processState, slice.screenState, slice.powerState));
         }
 
         for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
+            if (component == BatteryConsumer.POWER_COMPONENT_BASE) {
+                continue;
+            }
             final String metricTitle = getPowerMetricTitle(component);
-            final int powerModel = requestedBatteryConsumer.getPowerModel(component);
-            if (powerModel == BatteryConsumer.POWER_MODEL_POWER_PROFILE
-                    || powerModel == BatteryConsumer.POWER_MODEL_UNDEFINED) {
-                addEntry(metricTitle, EntryType.UID_POWER_PROFILE,
-                        requestedBatteryConsumer.getConsumedPower(component),
+            double consumedPower = requestedBatteryConsumer.getConsumedPower(component);
+            if (consumedPower != 0) {
+                Entry entry = addEntry(metricTitle, EntryType.UID, consumedPower,
                         totalPowerByComponentMah[component]);
-                addProcessStateEntries(metricTitle, EntryType.UID_POWER_PROFILE_PROCESS_STATE,
-                        requestedBatteryConsumer, component);
-            } else {
-                addEntry(metricTitle + " (PowerStats)", EntryType.UID_POWER_ENERGY_CONSUMPTION,
-                        requestedBatteryConsumer.getConsumedPower(component),
-                        totalPowerByComponentMah[component]);
-                addProcessStateEntries(metricTitle, EntryType.UID_POWER_ENERGY_PROCESS_STATE,
-                        requestedBatteryConsumer, component);
-                addEntry(metricTitle + " (PowerProfile)", EntryType.UID_POWER_PROFILE,
-                        requestedModeledBatteryConsumer.getConsumedPower(component),
-                        totalModeledPowerByComponentMah[component]);
-                addProcessStateEntries(metricTitle, EntryType.UID_POWER_PROFILE_PROCESS_STATE,
-                        requestedModeledBatteryConsumer, component);
+                addSlices(entry, requestedBatteryConsumer, component);
             }
         }
 
         for (int component = 0; component < customComponentCount; component++) {
-            final String name = requestedBatteryConsumer.getCustomPowerComponentName(
-                    BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component);
-            addEntry(name + " (PowerStats)", EntryType.UID_POWER_CUSTOM,
-                    requestedBatteryConsumer.getConsumedPowerForCustomComponent(
-                            BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component),
-                    totalCustomPowerByComponentMah[component]
-            );
-        }
-
-        for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
-            final String metricTitle = getTimeMetricTitle(component);
-            addEntry(metricTitle, EntryType.UID_DURATION,
-                    requestedBatteryConsumer.getUsageDurationMillis(component),
-                    totalDurationByComponentMs[component]
-            );
+            int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component;
+            final String name = requestedBatteryConsumer.getCustomPowerComponentName(componentId);
+            double consumedPower = requestedBatteryConsumer.getConsumedPower(componentId);
+            if (consumedPower != 0) {
+                Entry entry = addEntry(name, EntryType.UID, consumedPower,
+                        totalCustomPowerByComponentMah[component]);
+                addSlices(entry, requestedBatteryConsumer, componentId);
+            }
         }
 
         mBatteryConsumerInfo = BatteryConsumerInfoHelper.makeBatteryConsumerInfo(batteryUsageStats,
                 batteryConsumerId, context.getPackageManager());
     }
 
-    private void addProcessStateEntries(String metricTitle, EntryType entryType,
-            BatteryConsumer batteryConsumer, int component) {
+    private void addSlices(Entry entry, BatteryConsumer batteryConsumer, int component) {
         final BatteryConsumer.Key[] keys = batteryConsumer.getKeys(component);
         if (keys == null || keys.length <= 1) {
             return;
         }
 
+        boolean hasProcStateData = false;
         for (BatteryConsumer.Key key : keys) {
-            String label;
-            switch (key.processState) {
-                case BatteryConsumer.PROCESS_STATE_FOREGROUND:
-                    label = "foreground";
-                    break;
-                case BatteryConsumer.PROCESS_STATE_BACKGROUND:
-                    label = "background";
-                    break;
-                case BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE:
-                    label = "FGS";
-                    break;
-                case BatteryConsumer.PROCESS_STATE_CACHED:
-                    label = "cached";
-                    break;
-                default:
-                    continue;
+            if (key.processState != BatteryConsumer.PROCESS_STATE_UNSPECIFIED) {
+                hasProcStateData = true;
+                break;
             }
-            addEntry(metricTitle + " \u2022 " + label, entryType,
-                    batteryConsumer.getConsumedPower(key), 0);
         }
+
+        ArrayList<Slice> slices = new ArrayList<>();
+        for (BatteryConsumer.Key key : keys) {
+            if (hasProcStateData && key.processState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED) {
+                continue;
+            }
+
+            double powerMah = batteryConsumer.getConsumedPower(key);
+            long durationMs = batteryConsumer.getUsageDurationMillis(key);
+
+            if (powerMah == 0 && durationMs == 0) {
+                continue;
+            }
+
+            Slice slice = new Slice();
+            slice.powerState = key.powerState;
+            slice.screenState = key.screenState;
+            slice.processState = key.processState;
+            slice.powerMah = powerMah;
+            slice.durationMs = durationMs;
+
+            slices.add(slice);
+        }
+        entry.slices = slices;
     }
 
     private void populateForAggregateBatteryConsumer(Context context,
-            List<BatteryUsageStats> batteryUsageStatsList) {
-        BatteryUsageStats batteryUsageStats = batteryUsageStatsList.get(0);
-        BatteryUsageStats modeledBatteryUsageStats = batteryUsageStatsList.get(1);
-
+            BatteryUsageStats batteryUsageStats) {
         final BatteryConsumer deviceBatteryConsumer =
                 batteryUsageStats.getAggregateBatteryConsumer(
                         BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
@@ -211,46 +186,18 @@
                 batteryUsageStats.getAggregateBatteryConsumer(
                         BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
 
-        BatteryConsumer modeledDeviceBatteryConsumer =
-                modeledBatteryUsageStats.getAggregateBatteryConsumer(
-                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
-        BatteryConsumer modeledAppsBatteryConsumer =
-                modeledBatteryUsageStats.getAggregateBatteryConsumer(
-                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
-
-        if (isPowerProfileModelsOnly(deviceBatteryConsumer)) {
-            addEntry("Consumed", EntryType.DEVICE_TOTAL_POWER,
-                    deviceBatteryConsumer.getConsumedPower(),
-                    appsBatteryConsumer.getConsumedPower());
-        } else {
-            addEntry("Consumed (PowerStats)", EntryType.DEVICE_TOTAL_POWER,
-                    deviceBatteryConsumer.getConsumedPower(),
-                    appsBatteryConsumer.getConsumedPower());
-            addEntry("Consumed (PowerProfile)", EntryType.DEVICE_TOTAL_POWER,
-                    modeledDeviceBatteryConsumer.getConsumedPower(),
-                    modeledAppsBatteryConsumer.getConsumedPower());
-        }
+        addEntry("Consumed", EntryType.DEVICE_TOTAL_POWER,
+                deviceBatteryConsumer.getConsumedPower(),
+                appsBatteryConsumer.getConsumedPower());
 
         mBatteryConsumerInfo = BatteryConsumerInfoHelper.makeBatteryConsumerInfo(batteryUsageStats,
                 AGGREGATE_BATTERY_CONSUMER_ID, context.getPackageManager());
 
-
         for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
             final String metricTitle = getPowerMetricTitle(component);
-            final int powerModel = deviceBatteryConsumer.getPowerModel(component);
-            if (powerModel == BatteryConsumer.POWER_MODEL_POWER_PROFILE
-                    || powerModel == BatteryConsumer.POWER_MODEL_UNDEFINED) {
-                addEntry(metricTitle, EntryType.DEVICE_POWER_MODELED,
-                        deviceBatteryConsumer.getConsumedPower(component),
-                        appsBatteryConsumer.getConsumedPower(component));
-            } else {
-                addEntry(metricTitle + " (PowerStats)", EntryType.DEVICE_POWER_ENERGY_CONSUMPTION,
-                        deviceBatteryConsumer.getConsumedPower(component),
-                        appsBatteryConsumer.getConsumedPower(component));
-                addEntry(metricTitle + " (PowerProfile)", EntryType.DEVICE_POWER_MODELED,
-                        modeledDeviceBatteryConsumer.getConsumedPower(component),
-                        modeledAppsBatteryConsumer.getConsumedPower(component));
-            }
+            addEntry(metricTitle, EntryType.DEVICE_POWER,
+                    deviceBatteryConsumer.getConsumedPower(component),
+                    appsBatteryConsumer.getConsumedPower(component));
         }
 
         final int customComponentCount =
@@ -258,10 +205,10 @@
         for (int component = 0; component < customComponentCount; component++) {
             final String name = deviceBatteryConsumer.getCustomPowerComponentName(
                     BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component);
-            addEntry(name + " (PowerStats)", EntryType.DEVICE_POWER_CUSTOM,
-                    deviceBatteryConsumer.getConsumedPowerForCustomComponent(
+            addEntry(name, EntryType.DEVICE_POWER_CUSTOM,
+                    deviceBatteryConsumer.getConsumedPower(
                             BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component),
-                    appsBatteryConsumer.getConsumedPowerForCustomComponent(
+                    appsBatteryConsumer.getConsumedPower(
                             BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component));
         }
 
@@ -272,17 +219,6 @@
         }
     }
 
-    private boolean isPowerProfileModelsOnly(BatteryConsumer batteryConsumer) {
-        for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
-            final int powerModel = batteryConsumer.getPowerModel(component);
-            if (powerModel != BatteryConsumer.POWER_MODEL_POWER_PROFILE
-                    && powerModel != BatteryConsumer.POWER_MODEL_UNDEFINED) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     private BatteryConsumer getRequestedBatteryConsumer(BatteryUsageStats batteryUsageStats,
             String batteryConsumerId) {
         for (UidBatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
@@ -352,13 +288,14 @@
         }
     }
 
-    private void addEntry(String title, EntryType entryType, double value1, double value2) {
+    private Entry addEntry(String title, EntryType entryType, double value1, double value2) {
         Entry entry = new Entry();
         entry.title = title;
         entry.entryType = entryType;
         entry.value1 = value1;
         entry.value2 = value2;
         mEntries.add(entry);
+        return entry;
     }
 
     public BatteryConsumerInfoHelper.BatteryConsumerInfo getBatteryConsumerInfo() {
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
index c6d71c3..37d6b17 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
@@ -24,6 +24,8 @@
 
 import androidx.annotation.NonNull;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.util.List;
 
 class BatteryConsumerInfoHelper {
@@ -76,6 +78,8 @@
         String packageWithHighestDrain = uidBatteryConsumer.getPackageWithHighestDrain();
         if (uid == Process.ROOT_UID) {
             info.label = "<root>";
+        } else if (uid < Process.FIRST_APPLICATION_UID) {
+            info.label = makeSystemUidLabel(uid);
         } else {
             String[] packages = packageManager.getPackagesForUid(uid);
             String primaryPackageName = null;
@@ -134,6 +138,23 @@
         return info;
     }
 
+    private static CharSequence makeSystemUidLabel(int uid) {
+        for (Field field : Process.class.getDeclaredFields()) {
+            final int modifiers = field.getModifiers();
+            if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)
+                    && field.getType().equals(int.class) && field.getName().endsWith("_UID")) {
+                try {
+                    if (uid == field.getInt(null)) {
+                        String label = field.getName();
+                        return label.substring(0, label.lastIndexOf("_UID"));
+                    }
+                } catch (IllegalAccessException ignored) {
+                }
+            }
+        }
+        return null;
+    }
+
     private static BatteryConsumerInfo makeAggregateBatteryConsumerInfo(
             BatteryUsageStats batteryUsageStats) {
         BatteryConsumerInfo info = new BatteryConsumerInfo();
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
index 4469168..3699690 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
@@ -30,8 +30,8 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import androidx.activity.ComponentActivity;
 import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
 import androidx.loader.app.LoaderManager;
 import androidx.loader.content.Loader;
 import androidx.recyclerview.widget.LinearLayoutManager;
@@ -50,7 +50,7 @@
  * Picker, showing a sorted lists of applications and other types of entities consuming power.
  * Opens BatteryStatsViewerActivity upon item selection.
  */
-public class BatteryConsumerPickerActivity extends ComponentActivity {
+public class BatteryConsumerPickerActivity extends AppCompatActivity {
     private static final String PREF_SELECTED_BATTERY_CONSUMER = "batteryConsumerId";
     private static final int BATTERY_STATS_REFRESH_RATE_MILLIS = 60 * 1000;
     private static final String FORCE_FRESH_STATS = "force_fresh_stats";
@@ -68,6 +68,7 @@
         super.onCreate(icicle);
 
         setContentView(R.layout.battery_consumer_picker_layout);
+        setSupportActionBar(findViewById(R.id.toolbar));
 
         mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
         mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_green_light);
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
index e165c49..35021316 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
@@ -17,14 +17,18 @@
 package com.android.frameworks.core.batterystatsviewer;
 
 import android.content.Context;
+import android.os.BatteryConsumer;
 import android.os.BatteryStatsManager;
 import android.os.BatteryUsageStats;
 import android.os.BatteryUsageStatsQuery;
 import android.os.Bundle;
+import android.util.SparseArray;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
+import android.widget.TableLayout;
+import android.widget.TableRow;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -40,6 +44,7 @@
 
 import com.android.settingslib.utils.AsyncLoaderCompat;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
@@ -63,7 +68,16 @@
     private SwipeRefreshLayout mSwipeRefreshLayout;
     private View mCardView;
     private View mEmptyView;
-    private List<BatteryUsageStats> mBatteryUsageStats;
+    private BatteryUsageStats mBatteryUsageStats;
+
+    private static SparseArray<String> sProcStateNames = new SparseArray<>();
+    static {
+        sProcStateNames.put(BatteryConsumer.PROCESS_STATE_UNSPECIFIED, "-");
+        sProcStateNames.put(BatteryConsumer.PROCESS_STATE_FOREGROUND, "FG");
+        sProcStateNames.put(BatteryConsumer.PROCESS_STATE_BACKGROUND, "BG");
+        sProcStateNames.put(BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE, "FGS");
+        sProcStateNames.put(BatteryConsumer.PROCESS_STATE_CACHED, "Cached");
+    }
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -122,7 +136,7 @@
     }
 
     private static class BatteryUsageStatsLoader extends
-            AsyncLoaderCompat<List<BatteryUsageStats>> {
+            AsyncLoaderCompat<BatteryUsageStats> {
         private final BatteryStatsManager mBatteryStatsManager;
         private final boolean mForceFreshStats;
 
@@ -133,51 +147,44 @@
         }
 
         @Override
-        public List<BatteryUsageStats> loadInBackground() {
+        public BatteryUsageStats loadInBackground() {
             final int maxStatsAgeMs = mForceFreshStats ? 0 : BATTERY_STATS_REFRESH_RATE_MILLIS;
             final BatteryUsageStatsQuery queryDefault =
                     new BatteryUsageStatsQuery.Builder()
-                            .includePowerModels()
                             .includeProcessStateData()
+                            .includeScreenStateData()
+                            .includePowerStateData()
                             .setMaxStatsAgeMs(maxStatsAgeMs)
                             .build();
-            final BatteryUsageStatsQuery queryPowerProfileModeledOnly =
-                    new BatteryUsageStatsQuery.Builder()
-                            .powerProfileModeledOnly()
-                            .includePowerModels()
-                            .includeProcessStateData()
-                            .setMaxStatsAgeMs(maxStatsAgeMs)
-                            .build();
-            return mBatteryStatsManager.getBatteryUsageStats(
-                    List.of(queryDefault, queryPowerProfileModeledOnly));
+            return mBatteryStatsManager.getBatteryUsageStats(queryDefault);
         }
 
         @Override
-        protected void onDiscardResult(List<BatteryUsageStats> result) {
+        protected void onDiscardResult(BatteryUsageStats result) {
         }
     }
 
     private class BatteryUsageStatsLoaderCallbacks
-            implements LoaderCallbacks<List<BatteryUsageStats>> {
+            implements LoaderCallbacks<BatteryUsageStats> {
         @NonNull
         @Override
-        public Loader<List<BatteryUsageStats>> onCreateLoader(int id, Bundle args) {
+        public Loader<BatteryUsageStats> onCreateLoader(int id, Bundle args) {
             return new BatteryUsageStatsLoader(BatteryStatsViewerActivity.this,
                     args.getBoolean(FORCE_FRESH_STATS));
         }
 
         @Override
-        public void onLoadFinished(@NonNull Loader<List<BatteryUsageStats>> loader,
-                List<BatteryUsageStats> batteryUsageStats) {
+        public void onLoadFinished(@NonNull Loader<BatteryUsageStats> loader,
+                BatteryUsageStats batteryUsageStats) {
             onBatteryUsageStatsLoaded(batteryUsageStats);
         }
 
         @Override
-        public void onLoaderReset(@NonNull Loader<List<BatteryUsageStats>> loader) {
+        public void onLoaderReset(@NonNull Loader<BatteryUsageStats> loader) {
         }
     }
 
-    private void onBatteryUsageStatsLoaded(List<BatteryUsageStats> batteryUsageStats) {
+    private void onBatteryUsageStatsLoaded(BatteryUsageStats batteryUsageStats) {
         mBatteryUsageStats = batteryUsageStats;
         onBatteryStatsDataLoaded();
     }
@@ -238,10 +245,21 @@
     private static class BatteryStatsDataAdapter extends
             RecyclerView.Adapter<BatteryStatsDataAdapter.ViewHolder> {
         public static class ViewHolder extends RecyclerView.ViewHolder {
+            public static class SliceViewHolder {
+                public TableRow tableRow;
+                public int procState;
+                public int powerState;
+                public int screenState;
+                public TextView powerTextView;
+                public TextView durationTextView;
+            }
+
             public ImageView iconImageView;
             public TextView titleTextView;
             public TextView value1TextView;
             public TextView value2TextView;
+            public TableLayout table;
+            public List<SliceViewHolder> slices = new ArrayList<>();
 
             ViewHolder(View itemView) {
                 super(itemView);
@@ -250,6 +268,40 @@
                 titleTextView = itemView.findViewById(R.id.title);
                 value1TextView = itemView.findViewById(R.id.value1);
                 value2TextView = itemView.findViewById(R.id.value2);
+                table = itemView.findViewById(R.id.table);
+
+                for (int i = 0; i < sProcStateNames.size(); i++) {
+                    int procState = sProcStateNames.keyAt(i);
+                    slices.add(createSliceViewHolder(procState,
+                            BatteryConsumer.POWER_STATE_BATTERY,
+                            BatteryConsumer.SCREEN_STATE_ON,
+                            R.id.power_b_on, R.id.duration_b_on));
+                    slices.add(createSliceViewHolder(procState,
+                            BatteryConsumer.POWER_STATE_BATTERY,
+                            BatteryConsumer.SCREEN_STATE_OTHER,
+                            R.id.power_b_off, R.id.duration_b_off));
+                    slices.add(createSliceViewHolder(procState,
+                            BatteryConsumer.POWER_STATE_OTHER,
+                            BatteryConsumer.SCREEN_STATE_ON,
+                            R.id.power_c_on, R.id.duration_c_on));
+                    slices.add(createSliceViewHolder(procState,
+                            BatteryConsumer.POWER_STATE_OTHER,
+                            BatteryConsumer.SCREEN_STATE_OTHER,
+                            R.id.power_c_off, R.id.duration_c_off));
+                }
+            }
+
+            private SliceViewHolder createSliceViewHolder(int procState, int powerState,
+                    int screenState, int powerTextViewResId, int durationTextViewResId) {
+                TableRow powerRow = table.findViewWithTag("procstate" + procState);
+                SliceViewHolder svh = new SliceViewHolder();
+                svh.tableRow = powerRow;
+                svh.procState = procState;
+                svh.powerState = powerState;
+                svh.screenState = screenState;
+                svh.powerTextView = powerRow.findViewById(powerTextViewResId);
+                svh.durationTextView = powerRow.findViewById(durationTextViewResId);
+                return svh;
             }
         }
 
@@ -269,62 +321,32 @@
         @Override
         public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {
             LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
-            View itemView = layoutInflater.inflate(R.layout.battery_consumer_entry_layout, parent,
-                    false);
+            ViewGroup itemView = (ViewGroup) layoutInflater.inflate(
+                    R.layout.battery_consumer_entry_layout, parent, false);
+            TableLayout table = itemView.findViewById(R.id.table);
+            int offset = 1;     // Skip header
+            for (int i = 0; i < sProcStateNames.size(); i++) {
+                View powerRow = layoutInflater.inflate(R.layout.battery_consumer_slices_layout,
+                        itemView, false);
+                ((TextView) powerRow.findViewById(R.id.procState))
+                        .setText(sProcStateNames.valueAt(i));
+                powerRow.setTag("procstate" + sProcStateNames.keyAt(i));
+                table.addView(powerRow, offset++);
+            }
+
             return new ViewHolder(itemView);
         }
 
         @Override
         public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
             BatteryConsumerData.Entry entry = mEntries.get(position);
-
             switch (entry.entryType) {
-                case UID_TOTAL_POWER:
+                case UID:
                     setTitleIconAndBackground(viewHolder, entry.title,
-                            R.drawable.gm_sum_24, 0);
+                            R.drawable.gm_energy_24, 0);
                     setPowerText(viewHolder.value1TextView, entry.value1);
                     setProportionText(viewHolder.value2TextView, entry);
-                    break;
-                case UID_POWER_PROFILE:
-                    setTitleIconAndBackground(viewHolder, entry.title,
-                            R.drawable.gm_calculate_24,
-                            R.color.battery_consumer_bg_power_profile);
-                    setPowerText(viewHolder.value1TextView, entry.value1);
-                    setProportionText(viewHolder.value2TextView, entry);
-                    break;
-                case UID_POWER_PROFILE_PROCESS_STATE:
-                    setTitleIconAndBackground(viewHolder, "    " + entry.title,
-                            R.drawable.gm_calculate_24,
-                            R.color.battery_consumer_bg_power_profile);
-                    setPowerText(viewHolder.value1TextView, entry.value1);
-                    viewHolder.value2TextView.setVisibility(View.INVISIBLE);
-                    break;
-                case UID_POWER_ENERGY_CONSUMPTION:
-                    setTitleIconAndBackground(viewHolder, entry.title,
-                            R.drawable.gm_energy_24,
-                            R.color.battery_consumer_bg_energy_consumption);
-                    setPowerText(viewHolder.value1TextView, entry.value1);
-                    setProportionText(viewHolder.value2TextView, entry);
-                    break;
-                case UID_POWER_ENERGY_PROCESS_STATE:
-                    setTitleIconAndBackground(viewHolder, "    " + entry.title,
-                            R.drawable.gm_energy_24,
-                            R.color.battery_consumer_bg_energy_consumption);
-                    setPowerText(viewHolder.value1TextView, entry.value1);
-                    viewHolder.value2TextView.setVisibility(View.INVISIBLE);
-                    break;
-                case UID_POWER_CUSTOM:
-                    setTitleIconAndBackground(viewHolder, entry.title,
-                            R.drawable.gm_energy_24,
-                            R.color.battery_consumer_bg_energy_consumption);
-                    setPowerText(viewHolder.value1TextView, entry.value1);
-                    setProportionText(viewHolder.value2TextView, entry);
-                    break;
-                case UID_DURATION:
-                    setTitleIconAndBackground(viewHolder, entry.title,
-                            R.drawable.gm_timer_24, 0);
-                    setDurationText(viewHolder.value1TextView, (long) entry.value1);
-                    setProportionText(viewHolder.value2TextView, entry);
+                    bindSlices(viewHolder, entry);
                     break;
                 case DEVICE_TOTAL_POWER:
                     setTitleIconAndBackground(viewHolder, entry.title,
@@ -332,27 +354,13 @@
                     setPowerText(viewHolder.value1TextView, entry.value1);
                     setPowerText(viewHolder.value2TextView, entry.value2);
                     break;
-                case DEVICE_POWER_MODELED:
+                case DEVICE_POWER:
                     setTitleIconAndBackground(viewHolder, entry.title,
                             R.drawable.gm_calculate_24,
                             R.color.battery_consumer_bg_power_profile);
                     setPowerText(viewHolder.value1TextView, entry.value1);
                     setPowerText(viewHolder.value2TextView, entry.value2);
                     break;
-                case DEVICE_POWER_ENERGY_CONSUMPTION:
-                    setTitleIconAndBackground(viewHolder, entry.title,
-                            R.drawable.gm_energy_24,
-                            R.color.battery_consumer_bg_energy_consumption);
-                    setPowerText(viewHolder.value1TextView, entry.value1);
-                    setPowerText(viewHolder.value2TextView, entry.value2);
-                    break;
-                case DEVICE_POWER_CUSTOM:
-                    setTitleIconAndBackground(viewHolder, entry.title,
-                            R.drawable.gm_energy_24,
-                            R.color.battery_consumer_bg_energy_consumption);
-                    setPowerText(viewHolder.value1TextView, entry.value1);
-                    setPowerText(viewHolder.value2TextView, entry.value2);
-                    break;
                 case DEVICE_DURATION:
                     setTitleIconAndBackground(viewHolder, entry.title,
                             R.drawable.gm_timer_24, 0);
@@ -362,6 +370,65 @@
             }
         }
 
+        private void bindSlices(ViewHolder viewHolder, BatteryConsumerData.Entry entry) {
+            if (entry.slices == null || entry.slices.isEmpty()) {
+                viewHolder.table.setVisibility(View.GONE);
+                return;
+            }
+            viewHolder.table.setVisibility(View.VISIBLE);
+
+            boolean[] procStateRowPopulated =
+                    new boolean[BatteryConsumer.PROCESS_STATE_COUNT];
+            for (BatteryConsumerData.Slice s : entry.slices) {
+                if (s.powerMah != 0 || s.durationMs != 0) {
+                    procStateRowPopulated[s.processState] = true;
+                }
+            }
+
+            for (ViewHolder.SliceViewHolder sliceViewHolder : viewHolder.slices) {
+                BatteryConsumerData.Slice slice = null;
+                for (BatteryConsumerData.Slice s : entry.slices) {
+                    if (s.powerState == sliceViewHolder.powerState
+                            && s.screenState == sliceViewHolder.screenState
+                            && s.processState == sliceViewHolder.procState) {
+                        slice = s;
+                        break;
+                    }
+                }
+                if (!procStateRowPopulated[sliceViewHolder.procState]) {
+                    sliceViewHolder.tableRow.setVisibility(View.GONE);
+                } else {
+                    sliceViewHolder.tableRow.setVisibility(View.VISIBLE);
+
+                    if (slice != null && (slice.powerMah != 0 || slice.durationMs != 0)) {
+                        sliceViewHolder.powerTextView.setText(
+                                String.format(Locale.getDefault(), "%.1f", slice.powerMah));
+                    } else {
+                        sliceViewHolder.powerTextView.setText(null);
+                    }
+
+                    if (slice != null && slice.durationMs != 0) {
+                        sliceViewHolder.durationTextView.setVisibility(View.VISIBLE);
+                        String timeString;
+                        if (slice.durationMs < MILLIS_IN_MINUTE) {
+                            timeString = String.format(Locale.getDefault(), "%ds",
+                                    slice.durationMs / 1000);
+                        } else if (slice.durationMs < 60 * MILLIS_IN_MINUTE) {
+                            timeString = String.format(Locale.getDefault(), "%dm %ds",
+                                    slice.durationMs / MILLIS_IN_MINUTE,
+                                    (slice.durationMs % MILLIS_IN_MINUTE) / 1000);
+                        } else {
+                            timeString = String.format(Locale.getDefault(), "%dm",
+                                    slice.durationMs / MILLIS_IN_MINUTE);
+                        }
+                        sliceViewHolder.durationTextView.setText(timeString);
+                    } else {
+                        sliceViewHolder.durationTextView.setVisibility(View.GONE);
+                    }
+                }
+            }
+        }
+
         private void setTitleIconAndBackground(ViewHolder viewHolder, String title, int icon,
                 int background) {
             viewHolder.titleTextView.setText(title);
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/TrampolineActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/TrampolineActivity.java
index b016488..412169e 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/TrampolineActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/TrampolineActivity.java
@@ -42,5 +42,6 @@
 
     private void launchMainActivity() {
         startActivity(new Intent(this, BatteryConsumerPickerActivity.class));
+        finish();
     }
 }
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index f39508d..4942557 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -152,6 +152,7 @@
         ":HelloWorldUsingSdkMalformedNegativeVersion",
         ":CtsStaticSharedLibConsumerApp1",
         ":CtsStaticSharedLibConsumerApp3",
+        ":CtsStaticSharedLibProviderApp1",
     ],
 }
 
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index 5d8ff87..bada751 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -43,6 +43,8 @@
             value="/data/local/tmp/tests/coretests/pm/CtsStaticSharedLibConsumerApp1.apk"/>
         <option name="push-file" key="CtsStaticSharedLibConsumerApp3.apk"
             value="/data/local/tmp/tests/coretests/pm/CtsStaticSharedLibConsumerApp3.apk"/>
+        <option name="push-file" key="CtsStaticSharedLibProviderApp1.apk"
+                value="/data/local/tmp/tests/coretests/pm/CtsStaticSharedLibProviderApp1.apk"/>
     </target_preparer>
 
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index 23a0985..63e678d 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -467,7 +467,6 @@
                 .setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG"))
                 .setColor(Color.WHITE)
                 .setColorized(true)
-                .setFlag(FLAG_CAN_COLORIZE, true)
                 .build();
         assertThat(n.hasPromotableCharacteristics()).isTrue();
     }
@@ -481,7 +480,6 @@
                 .setContentTitle("TITLE")
                 .setColor(Color.WHITE)
                 .setColorized(true)
-                .setFlag(FLAG_CAN_COLORIZE, true)
                 .build();
         assertThat(n.hasPromotableCharacteristics()).isFalse();
     }
@@ -505,7 +503,20 @@
                 .setStyle(new Notification.BigTextStyle())
                 .setColor(Color.WHITE)
                 .setColorized(true)
-                .setFlag(FLAG_CAN_COLORIZE, true)
+                .build();
+        assertThat(n.hasPromotableCharacteristics()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_UI_RICH_ONGOING)
+    public void testHasPromotableCharacteristics_groupSummary() {
+        Notification n = new Notification.Builder(mContext, "test")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG"))
+                .setColor(Color.WHITE)
+                .setColorized(true)
+                .setGroup("someGroup")
+                .setGroupSummary(true)
                 .build();
         assertThat(n.hasPromotableCharacteristics()).isFalse();
     }
diff --git a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
index 2fc72e1..177c7f0 100644
--- a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
+++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
@@ -26,6 +26,7 @@
 import static com.android.internal.os.Flags.FLAG_APPLICATION_SHARED_MEMORY_ENABLED;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertSame;
@@ -34,6 +35,8 @@
 
 import android.annotation.SuppressLint;
 import android.app.PropertyInvalidatedCache.Args;
+import android.app.PropertyInvalidatedCache.NonceWatcher;
+import android.app.PropertyInvalidatedCache.NonceStore;
 import android.os.Binder;
 import com.android.internal.os.ApplicationSharedMemory;
 
@@ -45,11 +48,15 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.os.ApplicationSharedMemory;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * Test for verifying the behavior of {@link PropertyInvalidatedCache}.  This test does
  * not use any actual binder calls - it is entirely self-contained.  This test also relies
@@ -490,6 +497,62 @@
         }
     }
 
+    // Verify that NonceWatcher change reporting works properly
+    @Test
+    public void testNonceWatcherChanged() {
+        // Create a cache that will write a system nonce.
+        TestCache sysCache = new TestCache(MODULE_SYSTEM, "watcher1");
+        sysCache.testPropertyName();
+
+        try (NonceWatcher watcher1 = sysCache.getNonceWatcher()) {
+
+            // The property has never been invalidated so it is still unset.
+            assertFalse(watcher1.isChanged());
+
+            // Invalidate the cache.  The first call to isChanged will return true but the second
+            // call will return false;
+            sysCache.invalidateCache();
+            assertTrue(watcher1.isChanged());
+            assertFalse(watcher1.isChanged());
+
+            // Invalidate the cache.  The first call to isChanged will return true but the second
+            // call will return false;
+            sysCache.invalidateCache();
+            sysCache.invalidateCache();
+            assertTrue(watcher1.isChanged());
+            assertFalse(watcher1.isChanged());
+
+            NonceWatcher watcher2 = sysCache.getNonceWatcher();
+            // This watcher return isChanged() immediately because the nonce is not UNSET.
+            assertTrue(watcher2.isChanged());
+        }
+    }
+
+    // Verify that NonceWatcher wait-for-change works properly
+    @Test
+    public void testNonceWatcherWait() throws Exception {
+        // Create a cache that will write a system nonce.
+        TestCache sysCache = new TestCache(MODULE_TEST, "watcher1");
+
+        // Use the watcher outside a try-with-resources block.
+        NonceWatcher watcher1 = sysCache.getNonceWatcher();
+
+        // Invalidate the cache and then "wait".
+        sysCache.invalidateCache();
+        assertEquals(watcher1.waitForChange(), 1);
+
+        // Invalidate the cache three times and then "wait".
+        sysCache.invalidateCache();
+        sysCache.invalidateCache();
+        sysCache.invalidateCache();
+        assertEquals(watcher1.waitForChange(), 3);
+
+        // Wait for a change.  It won't happen, but the code will time out after 10ms.
+        assertEquals(watcher1.waitForChange(10, TimeUnit.MILLISECONDS), 0);
+
+        watcher1.close();
+    }
+
     // Verify the behavior of shared memory nonce storage.  This does not directly test the cache
     // storing nonces in shared memory.
     @RequiresFlagsEnabled(FLAG_APPLICATION_SHARED_MEMORY_ENABLED)
@@ -502,10 +565,8 @@
 
         // Create a server-side store and a client-side store.  The server's store is mutable and
         // the client's store is not mutable.
-        PropertyInvalidatedCache.NonceStore server =
-                new PropertyInvalidatedCache.NonceStore(shmem.getSystemNonceBlock(), true);
-        PropertyInvalidatedCache.NonceStore client =
-                new PropertyInvalidatedCache.NonceStore(shmem.getSystemNonceBlock(), false);
+        NonceStore server = new NonceStore(shmem.getSystemNonceBlock(), true);
+        NonceStore client = new NonceStore(shmem.getSystemNonceBlock(), false);
 
         final String name1 = "name1";
         assertEquals(server.getHandleForName(name1), INVALID_NONCE_INDEX);
diff --git a/core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java b/core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java
index 01c2abf..a22eae3 100644
--- a/core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java
+++ b/core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java
@@ -15,13 +15,20 @@
  */
 package android.app.wallpaper;
 
+import static android.app.WallpaperManager.ORIENTATION_LANDSCAPE;
+import static android.app.WallpaperManager.ORIENTATION_PORTRAIT;
+import static android.app.WallpaperManager.ORIENTATION_SQUARE_LANDSCAPE;
+import static android.app.WallpaperManager.ORIENTATION_SQUARE_PORTRAIT;
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import android.content.ComponentName;
+import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.PersistableBundle;
+import android.util.SparseArray;
 import android.util.Xml;
 
 import com.android.modules.utils.TypedXmlPullParser;
@@ -41,17 +48,20 @@
 
 @RunWith(JUnit4.class)
 public class WallpaperDescriptionTest {
-    private static final String TAG = "WallpaperDescriptionTest";
+    private static final Rect DEFAULT_CROP_PORTRAIT = new Rect(1, 2, 3, 4);
+    private static final Rect DEFAULT_CROP_LANDSCAPE = new Rect(5, 6, 7, 8);
+    private static final Rect DEFAULT_CROP_SQUARE_PORTRAIT = new Rect(9, 10, 11, 12);
+    private static final Rect DEFAULT_CROP_SQUARE_LANDSCAPE = new Rect(13, 14, 15, 16);
 
     private final ComponentName mTestComponent = new ComponentName("fakePackage", "fakeClass");
 
     @Test
     public void equals_ignoresIrrelevantFields() {
         String id = "fakeId";
-        WallpaperDescription desc1 = new WallpaperDescription.Builder().setComponent(
-                mTestComponent).setId(id).setTitle("fake one").build();
-        WallpaperDescription desc2 = new WallpaperDescription.Builder().setComponent(
-                mTestComponent).setId(id).setTitle("fake different").build();
+        WallpaperDescription desc1 = new WallpaperDescription.Builder()
+                .setComponent(mTestComponent).setId(id).setTitle("fake one").build();
+        WallpaperDescription desc2 = new WallpaperDescription.Builder()
+                .setComponent(mTestComponent).setId(id).setTitle("fake different").build();
 
         assertThat(desc1).isEqualTo(desc2);
     }
@@ -72,13 +82,21 @@
         final Uri thumbnail = Uri.parse("http://www.bogus.com/thumbnail");
         final List<CharSequence> description = List.of("line1", "line2");
         final Uri contextUri = Uri.parse("http://www.bogus.com/contextUri");
-        final PersistableBundle content = new PersistableBundle();
-        content.putString("ckey", "cvalue");
+        final PersistableBundle content = makeDefaultContent();
+        final SparseArray<Rect> cropHints = makeDefaultCropHints();
+        final float sampleSize = 0.9f;
         WallpaperDescription source = new WallpaperDescription.Builder()
-                .setComponent(mTestComponent).setId("fakeId").setThumbnail(thumbnail)
-                .setTitle("Fake title").setDescription(description)
-                .setContextUri(contextUri).setContextDescription("Context description")
-                .setContent(content).build();
+                .setComponent(mTestComponent)
+                .setId("fakeId")
+                .setThumbnail(thumbnail)
+                .setTitle("Fake title")
+                .setDescription(description)
+                .setContextUri(contextUri)
+                .setContextDescription("Context description")
+                .setContent(content)
+                .setCropHints(cropHints)
+                .setSampleSize(sampleSize)
+                .build();
 
         ByteArrayOutputStream ostream = new ByteArrayOutputStream();
         TypedXmlSerializer serializer = Xml.newBinarySerializer();
@@ -122,6 +140,57 @@
         assertThat(destination.getContent()).isNotNull();
         assertThat(destination.getContent().getString("ckey")).isEqualTo(
                 source.getContent().getString("ckey"));
+        assertThat(destination.getCropHints()).isNotNull();
+        assertThat(destination.getCropHints().get(ORIENTATION_PORTRAIT)).isEqualTo(
+                DEFAULT_CROP_PORTRAIT);
+        assertThat(destination.getCropHints().get(ORIENTATION_LANDSCAPE)).isEqualTo(
+                DEFAULT_CROP_LANDSCAPE);
+        assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_PORTRAIT)).isEqualTo(
+                DEFAULT_CROP_SQUARE_PORTRAIT);
+        assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_LANDSCAPE)).isEqualTo(
+                DEFAULT_CROP_SQUARE_LANDSCAPE);
+        assertThat(destination.getSampleSize()).isEqualTo(sampleSize);
+    }
+
+    @Test
+    public void xml_roundTripSucceeds_withNulls() throws IOException, XmlPullParserException {
+        WallpaperDescription source = new WallpaperDescription.Builder().build();
+
+        ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+        TypedXmlSerializer serializer = Xml.newBinarySerializer();
+        serializer.setOutput(ostream, StandardCharsets.UTF_8.name());
+        serializer.startDocument(null, true);
+        serializer.startTag(null, "test");
+        source.saveToXml(serializer);
+        serializer.endTag(null, "test");
+        serializer.endDocument();
+        ostream.close();
+
+        WallpaperDescription destination = null;
+        ByteArrayInputStream istream = new ByteArrayInputStream(ostream.toByteArray());
+        TypedXmlPullParser parser = Xml.newBinaryPullParser();
+        parser.setInput(istream, StandardCharsets.UTF_8.name());
+        int type;
+        do {
+            type = parser.next();
+            if (type == XmlPullParser.START_TAG && "test".equals(parser.getName())) {
+                destination = WallpaperDescription.restoreFromXml(parser);
+            }
+        } while (type != XmlPullParser.END_DOCUMENT);
+
+        assertThat(destination).isNotNull();
+        assertThat(destination.getComponent()).isEqualTo(source.getComponent());
+        assertThat(destination.getId()).isEqualTo(source.getId());
+        assertThat(destination.getThumbnail()).isEqualTo(source.getThumbnail());
+        assertThat(destination.getTitle()).isNull();
+        assertThat(destination.getDescription()).hasSize(0);
+        assertThat(destination.getContextUri()).isEqualTo(source.getContextUri());
+        assertThat(destination.getContextDescription()).isNull();
+        assertThat(destination.getContent()).isNotNull();
+        assertThat(destination.getContent().keySet()).isEmpty();
+        assertThat(destination.getCropHints()).isNotNull();
+        assertThat(destination.getCropHints().size()).isEqualTo(0);
+        assertThat(destination.getSampleSize()).isEqualTo(source.getSampleSize());
     }
 
     @Test
@@ -129,13 +198,21 @@
         final Uri thumbnail = Uri.parse("http://www.bogus.com/thumbnail");
         final List<CharSequence> description = List.of("line1", "line2");
         final Uri contextUri = Uri.parse("http://www.bogus.com/contextUri");
-        final PersistableBundle content = new PersistableBundle();
-        content.putString("ckey", "cvalue");
-        WallpaperDescription source = new WallpaperDescription.Builder().setComponent(
-                mTestComponent).setId("fakeId").setThumbnail(thumbnail).setTitle(
-                "Fake title").setDescription(description).setContextUri(
-                contextUri).setContextDescription("Context description").setContent(
-                content).build();
+        final PersistableBundle content = makeDefaultContent();
+        final SparseArray<Rect> cropHints = makeDefaultCropHints();
+        final float sampleSize = 0.9f;
+        WallpaperDescription source = new WallpaperDescription.Builder()
+                .setComponent(mTestComponent)
+                .setId("fakeId")
+                .setThumbnail(thumbnail)
+                .setTitle("Fake title")
+                .setDescription(description)
+                .setContextUri(contextUri)
+                .setContextDescription("Context description")
+                .setContent(content)
+                .setCropHints(cropHints)
+                .setSampleSize(sampleSize)
+                .build();
 
         Parcel parcel = Parcel.obtain();
         source.writeToParcel(parcel, 0);
@@ -162,6 +239,16 @@
         assertThat(destination.getContent()).isNotNull();
         assertThat(destination.getContent().getString("ckey")).isEqualTo(
                 source.getContent().getString("ckey"));
+        assertThat(destination.getCropHints()).isNotNull();
+        assertThat(destination.getCropHints().get(ORIENTATION_PORTRAIT)).isEqualTo(
+                DEFAULT_CROP_PORTRAIT);
+        assertThat(destination.getCropHints().get(ORIENTATION_LANDSCAPE)).isEqualTo(
+                DEFAULT_CROP_LANDSCAPE);
+        assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_PORTRAIT)).isEqualTo(
+                DEFAULT_CROP_SQUARE_PORTRAIT);
+        assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_LANDSCAPE)).isEqualTo(
+                DEFAULT_CROP_SQUARE_LANDSCAPE);
+        assertThat(destination.getSampleSize()).isEqualTo(sampleSize);
     }
 
     @Test
@@ -178,17 +265,14 @@
         assertThat(destination.getId()).isEqualTo(source.getId());
         assertThat(destination.getThumbnail()).isEqualTo(source.getThumbnail());
         assertThat(destination.getTitle()).isNull();
-        assertThat(destination.getDescription()).hasSize(source.getDescription().size());
-        for (int i = 0; i < destination.getDescription().size(); i++) {
-            CharSequence strDest = destination.getDescription().get(i);
-            CharSequence strSrc = source.getDescription().get(i);
-            assertWithMessage("description string mismatch")
-                    .that(CharSequence.compare(strDest, strSrc)).isEqualTo(0);
-        }
+        assertThat(destination.getDescription()).hasSize(0);
         assertThat(destination.getContextUri()).isEqualTo(source.getContextUri());
         assertThat(destination.getContextDescription()).isNull();
         assertThat(destination.getContent()).isNotNull();
         assertThat(destination.getContent().keySet()).isEmpty();
+        assertThat(destination.getCropHints()).isNotNull();
+        assertThat(destination.getCropHints().size()).isEqualTo(0);
+        assertThat(destination.getSampleSize()).isEqualTo(source.getSampleSize());
     }
 
     @Test
@@ -197,14 +281,22 @@
         final Uri thumbnail = Uri.parse("http://www.bogus.com/thumbnail");
         final List<CharSequence> description = List.of("line1", "line2");
         final Uri contextUri = Uri.parse("http://www.bogus.com/contextUri");
-        final PersistableBundle content = new PersistableBundle();
-        content.putString("ckey", "cvalue");
+        final PersistableBundle content = makeDefaultContent();
+        final SparseArray<Rect> cropHints = makeDefaultCropHints();
+        final float sampleSize = 1.1f;
         final String destinationId = "destinationId";
-        WallpaperDescription source = new WallpaperDescription.Builder().setComponent(
-                mTestComponent).setId(sourceId).setThumbnail(thumbnail).setTitle(
-                "Fake title").setDescription(description).setContextUri(
-                contextUri).setContextDescription("Context description").setContent(
-                content).build();
+        WallpaperDescription source = new WallpaperDescription.Builder()
+                .setComponent(mTestComponent)
+                .setId(sourceId)
+                .setThumbnail(thumbnail)
+                .setTitle("Fake title")
+                .setDescription(description)
+                .setContextUri(contextUri)
+                .setContextDescription("Context description")
+                .setContent(content)
+                .setCropHints(cropHints)
+                .setSampleSize(sampleSize)
+                .build();
 
         WallpaperDescription destination = source.toBuilder().setId(destinationId).build();
 
@@ -227,5 +319,29 @@
         assertThat(destination.getContent()).isNotNull();
         assertThat(destination.getContent().getString("ckey")).isEqualTo(
                 source.getContent().getString("ckey"));
+        assertThat(destination.getCropHints().get(ORIENTATION_PORTRAIT)).isEqualTo(
+                DEFAULT_CROP_PORTRAIT);
+        assertThat(destination.getCropHints().get(ORIENTATION_LANDSCAPE)).isEqualTo(
+                DEFAULT_CROP_LANDSCAPE);
+        assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_PORTRAIT)).isEqualTo(
+                DEFAULT_CROP_SQUARE_PORTRAIT);
+        assertThat(destination.getCropHints().get(ORIENTATION_SQUARE_LANDSCAPE)).isEqualTo(
+                DEFAULT_CROP_SQUARE_LANDSCAPE);
+        assertThat(destination.getSampleSize()).isEqualTo(sampleSize);
+    }
+
+    private static PersistableBundle makeDefaultContent() {
+        final PersistableBundle content = new PersistableBundle();
+        content.putString("ckey", "cvalue");
+        return content;
+    }
+
+    private static SparseArray<Rect> makeDefaultCropHints() {
+        final SparseArray<Rect> cropHints = new SparseArray<>();
+        cropHints.put(ORIENTATION_PORTRAIT, DEFAULT_CROP_PORTRAIT);
+        cropHints.put(ORIENTATION_LANDSCAPE, DEFAULT_CROP_LANDSCAPE);
+        cropHints.put(ORIENTATION_SQUARE_PORTRAIT, DEFAULT_CROP_SQUARE_PORTRAIT);
+        cropHints.put(ORIENTATION_SQUARE_LANDSCAPE, DEFAULT_CROP_SQUARE_LANDSCAPE);
+        return cropHints;
     }
 }
diff --git a/core/tests/coretests/src/android/appwidget/AppWidgetEventsTest.kt b/core/tests/coretests/src/android/appwidget/AppWidgetEventsTest.kt
new file mode 100644
index 0000000..ea1158c
--- /dev/null
+++ b/core/tests/coretests/src/android/appwidget/AppWidgetEventsTest.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.appwidget
+
+import android.graphics.Rect
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class AppWidgetEventsTest {
+    @Test
+    fun createWidgetInteractionEvent() {
+        val appWidgetId = 1
+        val durationMs = 1000L
+        val position = Rect(1, 2, 3, 4)
+        val clicked = intArrayOf(1, 2, 3)
+        val scrolled = intArrayOf(4, 5, 6)
+        val bundle = AppWidgetManager.createWidgetInteractionEvent(
+            appWidgetId,
+            durationMs,
+            position,
+            clicked,
+            scrolled
+        )
+
+        assertThat(bundle.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID)).isEqualTo(appWidgetId)
+        assertThat(bundle.getLong(AppWidgetManager.EXTRA_EVENT_DURATION_MS)).isEqualTo(durationMs)
+        assertThat(bundle.getIntArray(AppWidgetManager.EXTRA_EVENT_POSITION_RECT))
+            .asList().containsExactly(position.left, position.top, position.right, position.bottom)
+        assertThat(bundle.getIntArray(AppWidgetManager.EXTRA_EVENT_CLICKED_VIEWS))
+            .asList().containsExactly(clicked[0], clicked[1], clicked[2])
+        assertThat(bundle.getIntArray(AppWidgetManager.EXTRA_EVENT_SCROLLED_VIEWS))
+            .asList().containsExactly(scrolled[0], scrolled[1], scrolled[2])
+    }
+}
diff --git a/core/tests/coretests/src/android/appwidget/OWNERS b/core/tests/coretests/src/android/appwidget/OWNERS
new file mode 100644
index 0000000..d724cac
--- /dev/null
+++ b/core/tests/coretests/src/android/appwidget/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/appwidget/OWNERS
diff --git a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
index ecacdb2..6d2dd53 100644
--- a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
+++ b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
@@ -73,6 +73,7 @@
     private static final String TEST_APP_USING_SDK1_AND_SDK1 = "HelloWorldUsingSdk1AndSdk1.apk";
     private static final String TEST_APP_USING_SDK_MALFORMED_VERSION =
             "HelloWorldUsingSdkMalformedNegativeVersion.apk";
+    private static final String TEST_STATIC_LIB_APP = "CtsStaticSharedLibProviderApp1.apk";
     private static final String TEST_APP_USING_STATIC_LIB = "CtsStaticSharedLibConsumerApp1.apk";
     private static final String TEST_APP_USING_STATIC_LIB_TWO_CERTS =
             "CtsStaticSharedLibConsumerApp3.apk";
@@ -207,6 +208,17 @@
         assertThat(liteCerts).isEqualTo(pkgCerts);
     }
 
+    @Test
+    public void testParseApkLite_isIsStaticLibrary() throws Exception {
+        File apkFile = copyApkToTmpDir(TEST_STATIC_LIB_APP);
+        ParseResult<ApkLite> result = ApkLiteParseUtils
+                .parseApkLite(ParseTypeImpl.forDefaultParsing().reset(), apkFile, 0);
+        assertThat(result.isError()).isFalse();
+        ApkLite baseApk = result.getResult();
+
+        assertThat(baseApk.isIsStaticLibrary()).isTrue();
+    }
+
     @SuppressLint("CheckResult")
     @Test
     public void testParseApkLite_malformedUsesSdkLibrary_duplicate() throws Exception {
diff --git a/core/tests/coretests/src/android/content/pm/verify/VerificationSessionTest.java b/core/tests/coretests/src/android/content/pm/verify/VerificationSessionTest.java
deleted file mode 100644
index f1e1df5..0000000
--- a/core/tests/coretests/src/android/content/pm/verify/VerificationSessionTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify;
-
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_WARN;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningInfo;
-import android.content.pm.VersionedPackage;
-import android.content.pm.verify.pkg.IVerificationSessionInterface;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.PersistableBundle;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerificationSessionTest {
-    private static final int TEST_ID = 100;
-    private static final int TEST_INSTALL_SESSION_ID = 33;
-    private static final String TEST_PACKAGE_NAME = "com.foo";
-    private static final Uri TEST_PACKAGE_URI = Uri.parse("test://test");
-    private static final SigningInfo TEST_SIGNING_INFO = new SigningInfo();
-    private static final SharedLibraryInfo TEST_SHARED_LIBRARY_INFO1 =
-            new SharedLibraryInfo("sharedLibPath1", TEST_PACKAGE_NAME,
-                    Collections.singletonList("path1"), "sharedLib1", 101,
-                    SharedLibraryInfo.TYPE_DYNAMIC, new VersionedPackage(TEST_PACKAGE_NAME, 1),
-                    null, null, false);
-    private static final SharedLibraryInfo TEST_SHARED_LIBRARY_INFO2 =
-            new SharedLibraryInfo("sharedLibPath2", TEST_PACKAGE_NAME,
-                    Collections.singletonList("path2"), "sharedLib2", 102,
-                    SharedLibraryInfo.TYPE_DYNAMIC,
-                    new VersionedPackage(TEST_PACKAGE_NAME, 2), null, null, false);
-    private static final long TEST_TIMEOUT_TIME = System.currentTimeMillis();
-    private static final long TEST_EXTEND_TIME = 2000L;
-    private static final String TEST_KEY = "test key";
-    private static final String TEST_VALUE = "test value";
-    private static final int TEST_POLICY = VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-
-    private final ArrayList<SharedLibraryInfo> mTestDeclaredLibraries = new ArrayList<>();
-    private final PersistableBundle mTestExtensionParams = new PersistableBundle();
-    @Mock
-    private IVerificationSessionInterface mTestSessionInterface;
-    private VerificationSession mTestSession;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mTestDeclaredLibraries.add(TEST_SHARED_LIBRARY_INFO1);
-        mTestDeclaredLibraries.add(TEST_SHARED_LIBRARY_INFO2);
-        mTestExtensionParams.putString(TEST_KEY, TEST_VALUE);
-        mTestSession = new VerificationSession(TEST_ID, TEST_INSTALL_SESSION_ID,
-                TEST_PACKAGE_NAME, TEST_PACKAGE_URI, TEST_SIGNING_INFO, mTestDeclaredLibraries,
-                mTestExtensionParams, TEST_POLICY, mTestSessionInterface);
-    }
-
-    @Test
-    public void testParcel() {
-        Parcel parcel = Parcel.obtain();
-        mTestSession.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        VerificationSession sessionFromParcel =
-                VerificationSession.CREATOR.createFromParcel(parcel);
-        assertThat(sessionFromParcel.getId()).isEqualTo(TEST_ID);
-        assertThat(sessionFromParcel.getInstallSessionId()).isEqualTo(TEST_INSTALL_SESSION_ID);
-        assertThat(sessionFromParcel.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
-        assertThat(sessionFromParcel.getStagedPackageUri()).isEqualTo(TEST_PACKAGE_URI);
-        assertThat(sessionFromParcel.getSigningInfo().getSigningDetails())
-                .isEqualTo(TEST_SIGNING_INFO.getSigningDetails());
-        List<SharedLibraryInfo> declaredLibrariesFromParcel =
-                sessionFromParcel.getDeclaredLibraries();
-        assertThat(declaredLibrariesFromParcel).hasSize(2);
-        // SharedLibraryInfo doesn't have a "equals" method, so we have to check it indirectly
-        assertThat(declaredLibrariesFromParcel.getFirst().toString())
-                .isEqualTo(TEST_SHARED_LIBRARY_INFO1.toString());
-        assertThat(declaredLibrariesFromParcel.get(1).toString())
-                .isEqualTo(TEST_SHARED_LIBRARY_INFO2.toString());
-        // We can't directly test with PersistableBundle.equals() because the parceled bundle's
-        // structure is different, but all the key/value pairs should be preserved as before.
-        assertThat(sessionFromParcel.getExtensionParams().getString(TEST_KEY))
-                .isEqualTo(mTestExtensionParams.getString(TEST_KEY));
-        assertThat(sessionFromParcel.getVerificationPolicy()).isEqualTo(TEST_POLICY);
-    }
-
-    @Test
-    public void testInterface() throws Exception {
-        when(mTestSessionInterface.getTimeoutTime(anyInt())).thenAnswer(i -> TEST_TIMEOUT_TIME);
-        when(mTestSessionInterface.extendTimeRemaining(anyInt(), anyLong())).thenAnswer(
-                i -> i.getArguments()[1]);
-
-        assertThat(mTestSession.getTimeoutTime()).isEqualTo(TEST_TIMEOUT_TIME);
-        verify(mTestSessionInterface, times(1)).getTimeoutTime(eq(TEST_ID));
-        assertThat(mTestSession.extendTimeRemaining(TEST_EXTEND_TIME)).isEqualTo(TEST_EXTEND_TIME);
-        verify(mTestSessionInterface, times(1)).extendTimeRemaining(
-                eq(TEST_ID), eq(TEST_EXTEND_TIME));
-
-        PersistableBundle response = new PersistableBundle();
-        response.putString("test key", "test value");
-        final VerificationStatus status =
-                new VerificationStatus.Builder().setVerified(true).build();
-        mTestSession.reportVerificationComplete(status);
-        verify(mTestSessionInterface, times(1)).reportVerificationComplete(
-                eq(TEST_ID), eq(status), eq(null));
-        mTestSession.reportVerificationComplete(status, response);
-        verify(mTestSessionInterface, times(1))
-                .reportVerificationComplete(
-                        eq(TEST_ID), eq(status), eq(response));
-
-        final int reason = VerificationSession.VERIFICATION_INCOMPLETE_UNKNOWN;
-        mTestSession.reportVerificationIncomplete(reason);
-        verify(mTestSessionInterface, times(1)).reportVerificationIncomplete(
-                eq(TEST_ID), eq(reason));
-    }
-
-    @Test
-    public void testPolicyNoOverride() {
-        assertThat(mTestSession.getVerificationPolicy()).isEqualTo(TEST_POLICY);
-        // This "set" is a no-op
-        assertThat(mTestSession.setVerificationPolicy(TEST_POLICY)).isTrue();
-        assertThat(mTestSession.getVerificationPolicy()).isEqualTo(TEST_POLICY);
-        verifyZeroInteractions(mTestSessionInterface);
-    }
-
-    @Test
-    public void testPolicyOverrideFail() throws Exception {
-        final int newPolicy = VERIFICATION_POLICY_BLOCK_FAIL_WARN;
-        when(mTestSessionInterface.setVerificationPolicy(anyInt(), anyInt())).thenReturn(false);
-        assertThat(mTestSession.setVerificationPolicy(newPolicy)).isFalse();
-        verify(mTestSessionInterface, times(1))
-                .setVerificationPolicy(eq(TEST_ID), eq(newPolicy));
-        // Next "get" should not trigger binder call because the previous "set" has failed
-        assertThat(mTestSession.getVerificationPolicy()).isEqualTo(TEST_POLICY);
-        verifyNoMoreInteractions(mTestSessionInterface);
-    }
-
-    @Test
-    public void testPolicyOverrideSuccess() throws Exception {
-        final int newPolicy = VERIFICATION_POLICY_BLOCK_FAIL_WARN;
-        when(mTestSessionInterface.setVerificationPolicy(anyInt(), anyInt())).thenReturn(true);
-        assertThat(mTestSession.setVerificationPolicy(newPolicy)).isTrue();
-        verify(mTestSessionInterface, times(1))
-                .setVerificationPolicy(eq(TEST_ID), eq(newPolicy));
-        assertThat(mTestSession.getVerificationPolicy()).isEqualTo(newPolicy);
-        assertThat(mTestSession.getVerificationPolicy()).isEqualTo(newPolicy);
-
-        // Setting back to the original policy should still trigger binder calls
-        assertThat(mTestSession.setVerificationPolicy(TEST_POLICY)).isTrue();
-        verify(mTestSessionInterface, times(1))
-                .setVerificationPolicy(eq(TEST_ID), eq(TEST_POLICY));
-        assertThat(mTestSession.getVerificationPolicy()).isEqualTo(TEST_POLICY);
-    }
-}
diff --git a/core/tests/coretests/src/android/content/pm/verify/VerificationStatusTest.java b/core/tests/coretests/src/android/content/pm/verify/VerificationStatusTest.java
deleted file mode 100644
index 67d407a..0000000
--- a/core/tests/coretests/src/android/content/pm/verify/VerificationStatusTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.os.Parcel;
-import android.os.PersistableBundle;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerificationStatusTest {
-    private static final boolean TEST_VERIFIED = true;
-    private static final int TEST_ASL_STATUS = VerificationStatus.VERIFIER_STATUS_ASL_GOOD;
-    private static final String TEST_FAILURE_MESSAGE = "test test";
-    private static final String TEST_KEY = "test key";
-    private static final String TEST_VALUE = "test value";
-    private final PersistableBundle mTestExtras = new PersistableBundle();
-    private VerificationStatus mStatus;
-
-    @Before
-    public void setUpWithBuilder() {
-        mTestExtras.putString(TEST_KEY, TEST_VALUE);
-        mStatus = new VerificationStatus.Builder()
-                .setAslStatus(TEST_ASL_STATUS)
-                .setFailureMessage(TEST_FAILURE_MESSAGE)
-                .setVerified(TEST_VERIFIED)
-                .build();
-    }
-
-    @Test
-    public void testGetters() {
-        assertThat(mStatus.isVerified()).isEqualTo(TEST_VERIFIED);
-        assertThat(mStatus.getAslStatus()).isEqualTo(TEST_ASL_STATUS);
-        assertThat(mStatus.getFailureMessage()).isEqualTo(TEST_FAILURE_MESSAGE);
-    }
-
-    @Test
-    public void testParcel() {
-        Parcel parcel = Parcel.obtain();
-        mStatus.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        VerificationStatus statusFromParcel = VerificationStatus.CREATOR.createFromParcel(parcel);
-        assertThat(statusFromParcel.isVerified()).isEqualTo(TEST_VERIFIED);
-        assertThat(statusFromParcel.getAslStatus()).isEqualTo(TEST_ASL_STATUS);
-        assertThat(statusFromParcel.getFailureMessage()).isEqualTo(TEST_FAILURE_MESSAGE);
-    }
-}
diff --git a/core/tests/coretests/src/android/content/pm/verify/VerifierServiceTest.java b/core/tests/coretests/src/android/content/pm/verify/VerifierServiceTest.java
deleted file mode 100644
index 56fc66a..0000000
--- a/core/tests/coretests/src/android/content/pm/verify/VerifierServiceTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify;
-
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.SigningInfo;
-import android.content.pm.verify.pkg.IVerificationSessionInterface;
-import android.content.pm.verify.pkg.IVerifierService;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerifierService;
-import android.net.Uri;
-import android.os.PersistableBundle;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mockito;
-
-import java.util.ArrayList;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerifierServiceTest {
-    private static final int TEST_ID = 100;
-    private static final int TEST_INSTALL_SESSION_ID = 33;
-    private static final String TEST_PACKAGE_NAME = "com.foo";
-    private static final Uri TEST_PACKAGE_URI = Uri.parse("test://test");
-    private static final SigningInfo TEST_SIGNING_INFO = new SigningInfo();
-    private static final int TEST_POLICY = VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-    private VerifierService mService;
-    private VerificationSession mSession;
-
-    @Before
-    public void setUp() {
-        mService = Mockito.mock(VerifierService.class, Answers.CALLS_REAL_METHODS);
-        mSession = new VerificationSession(TEST_ID, TEST_INSTALL_SESSION_ID,
-                TEST_PACKAGE_NAME, TEST_PACKAGE_URI, TEST_SIGNING_INFO,
-                new ArrayList<>(), new PersistableBundle(), TEST_POLICY, Mockito.mock(
-                IVerificationSessionInterface.class));
-    }
-
-    @Test
-    public void testBind() throws Exception {
-        Intent intent = Mockito.mock(Intent.class);
-        when(intent.getAction()).thenReturn(PackageManager.ACTION_VERIFY_PACKAGE);
-        IVerifierService binder =
-                (IVerifierService) mService.onBind(intent);
-        assertThat(binder).isNotNull();
-        binder.onPackageNameAvailable(TEST_PACKAGE_NAME);
-        verify(mService).onPackageNameAvailable(eq(TEST_PACKAGE_NAME));
-        binder.onVerificationCancelled(TEST_PACKAGE_NAME);
-        verify(mService).onVerificationCancelled(eq(TEST_PACKAGE_NAME));
-        binder.onVerificationRequired(mSession);
-        verify(mService).onVerificationRequired(eq(mSession));
-        binder.onVerificationRetry(mSession);
-        verify(mService).onVerificationRetry(eq(mSession));
-        binder.onVerificationTimeout(TEST_ID);
-        verify(mService).onVerificationTimeout(eq(TEST_ID));
-    }
-
-    @Test
-    public void testBindFailsWithWrongIntent() {
-        Intent intent = Mockito.mock(Intent.class);
-        when(intent.getAction()).thenReturn(Intent.ACTION_SEND);
-        assertThat(mService.onBind(intent)).isNull();
-    }
-}
diff --git a/core/tests/coretests/src/android/os/OWNERS b/core/tests/coretests/src/android/os/OWNERS
index 4620cb8..c45080f 100644
--- a/core/tests/coretests/src/android/os/OWNERS
+++ b/core/tests/coretests/src/android/os/OWNERS
@@ -15,3 +15,6 @@
 
 # RemoteCallbackList
 per-file RemoteCallbackListTest.java = shayba@google.com
+
+# MessageQueue
+per-file MessageQueueTest.java = mfasheh@google.com, shayba@google.com
diff --git a/core/tests/coretests/src/android/view/ScrollCaptureSearchResultsTest.java b/core/tests/coretests/src/android/view/ScrollCaptureSearchResultsTest.java
index 726ee85..915ace0 100644
--- a/core/tests/coretests/src/android/view/ScrollCaptureSearchResultsTest.java
+++ b/core/tests/coretests/src/android/view/ScrollCaptureSearchResultsTest.java
@@ -16,9 +16,9 @@
 
 package android.view;
 
-import static androidx.test.InstrumentationRegistry.getTargetContext;
+import static android.view.flags.Flags.FLAG_SCROLL_CAPTURE_TARGET_Z_ORDER_FIX;
 
-import static com.google.common.truth.Truth.assertThat;
+import static androidx.test.InstrumentationRegistry.getTargetContext;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -32,13 +32,16 @@
 import android.graphics.Rect;
 import android.os.CancellationSignal;
 import android.os.SystemClock;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
 
 import androidx.annotation.NonNull;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -56,6 +59,8 @@
 @RunWith(AndroidJUnit4.class)
 public class ScrollCaptureSearchResultsTest {
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     private static final Rect EMPTY_RECT = new Rect();
     private static final String TAG = "Test";
@@ -98,6 +103,45 @@
         assertNull("Expected null due to no valid targets", results.getTopResult());
     }
 
+    /**
+     * A scrolling target should be excluded even when larger if it will be drawn over by another
+     * scrolling target.
+     */
+    @EnableFlags(FLAG_SCROLL_CAPTURE_TARGET_Z_ORDER_FIX)
+    @Test
+    public void testCoveredTargetsAreExcluded() {
+        ScrollCaptureSearchResults results = new ScrollCaptureSearchResults(mDirectExec);
+
+        FakeScrollCaptureCallback callback1 = new FakeScrollCaptureCallback(mDirectExec);
+        callback1.setScrollBounds(new Rect(0, 0, 200, 200)); // 200 tall
+        View view1 = new FakeView(getTargetContext(), 0, 0, 200, 200, 1);
+        ScrollCaptureTarget target1 = createTargetWithView(view1, callback1,
+                new Rect(0, 0, 200, 200), new Point(0, 0), View.SCROLL_CAPTURE_HINT_AUTO);
+
+        FakeScrollCaptureCallback callback2 = new FakeScrollCaptureCallback(mDirectExec);
+        callback2.setScrollBounds(new Rect(0, 0, 200, 180)); // 180 tall
+        View view2 = new FakeView(getTargetContext(), 0, 20, 200, 200, 2);
+        ScrollCaptureTarget target2 = createTargetWithView(view2, callback2,
+                new Rect(0, 0, 200, 180), new Point(0, 20), View.SCROLL_CAPTURE_HINT_AUTO);
+
+        // Top z-order but smaller, and non-intersecting. (positioned further Y than the first two)
+        FakeScrollCaptureCallback callback3 = new FakeScrollCaptureCallback(mDirectExec);
+        callback3.setScrollBounds(new Rect(0, 0, 50, 50));
+        View view3 = new FakeView(getTargetContext(), 75, 250, 125, 300, 3);
+        ScrollCaptureTarget target3 = createTargetWithView(view3, callback3,
+                new Rect(0, 0, 50, 50), new Point(75, 250), View.SCROLL_CAPTURE_HINT_AUTO);
+
+        results.addTarget(target1);
+        results.addTarget(target2);
+        results.addTarget(target3);
+
+        assertTrue(results.isComplete());
+        ScrollCaptureTarget result = results.getTopResult();
+        assertSame("Expected the second target because of higher z-Index", target2, result);
+        assertEquals("result has wrong scroll bounds",
+                new Rect(0, 0, 200, 180), result.getScrollBounds());
+    }
+
     @Test
     public void testSingleTarget() {
         ScrollCaptureSearchResults results = new ScrollCaptureSearchResults(mDirectExec);
@@ -152,29 +196,29 @@
 
         // 2 - 10x10 + HINT_INCLUDE
         FakeScrollCaptureCallback callback2 = new FakeScrollCaptureCallback(mDirectExec);
-        callback2.setScrollBounds(new Rect(0, 0, 10, 10));
-        ViewGroup targetView2 = new FakeView(getTargetContext(), 0, 0, 60, 60, 2);
+        callback2.setScrollBounds(new Rect(25, 25, 35, 35)); // 10x10
+        ViewGroup targetView2 = new FakeView(getTargetContext(), 0, 60, 60, 120, 2);
         ScrollCaptureTarget target2 = createTargetWithView(targetView2, callback2,
                  new Rect(0, 0, 60, 60), new Point(0, 0), View.SCROLL_CAPTURE_HINT_INCLUDE);
 
         // 3 - 20x20 + AUTO
         FakeScrollCaptureCallback callback3 = new FakeScrollCaptureCallback(mDirectExec);
         callback3.setScrollBounds(new Rect(0, 0, 20, 20));
-        ViewGroup targetView3 = new FakeView(getTargetContext(), 0, 0, 60, 60, 3);
+        ViewGroup targetView3 = new FakeView(getTargetContext(), 0, 120, 60, 180, 3);
         ScrollCaptureTarget target3 = createTargetWithView(targetView3, callback3,
                 new Rect(0, 0, 60, 60), new Point(0, 0), View.SCROLL_CAPTURE_HINT_AUTO);
 
         // 4 - 30x30 + AUTO
         FakeScrollCaptureCallback callback4 = new FakeScrollCaptureCallback(mDirectExec);
         callback4.setScrollBounds(new Rect(0, 0, 10, 10));
-        ViewGroup targetView4 = new FakeView(getTargetContext(), 0, 0, 60, 60, 4);
+        ViewGroup targetView4 = new FakeView(getTargetContext(), 0, 180, 60, 240, 4);
         ScrollCaptureTarget target4 = createTargetWithView(targetView4, callback4,
                 new Rect(0, 0, 60, 60), new Point(0, 0), View.SCROLL_CAPTURE_HINT_AUTO);
 
         // 5 - 10x10 + child of #4
         FakeScrollCaptureCallback callback5 = new FakeScrollCaptureCallback(mDirectExec);
         callback5.setScrollBounds(new Rect(0, 0, 10, 10));
-        ViewGroup targetView5 = new FakeView(getTargetContext(), 0, 0, 60, 60, 5);
+        ViewGroup targetView5 = new FakeView(getTargetContext(), 0, 0, 60, 30, 5);
         ScrollCaptureTarget target5 = createTargetWithView(targetView5, callback5,
                 new Rect(0, 0, 60, 60), new Point(0, 0), View.SCROLL_CAPTURE_HINT_AUTO);
         targetView4.addView(targetView5);
@@ -182,7 +226,7 @@
         // 6 - 20x20 + child of #4
         FakeScrollCaptureCallback callback6 = new FakeScrollCaptureCallback(mDirectExec);
         callback6.setScrollBounds(new Rect(0, 0, 20, 20));
-        ViewGroup targetView6 = new FakeView(getTargetContext(), 0, 0, 60, 60, 6);
+        ViewGroup targetView6 = new FakeView(getTargetContext(), 0, 30, 30, 60, 6);
         ScrollCaptureTarget target6 = createTargetWithView(targetView6, callback6,
                 new Rect(0, 0, 60, 60), new Point(0, 0), View.SCROLL_CAPTURE_HINT_AUTO);
         targetView4.addView(targetView6);
@@ -194,20 +238,10 @@
         results.addTarget(target4);
         results.addTarget(target5);
         results.addTarget(target6);
-        assertTrue(results.isComplete());
+        assertTrue("results.isComplete()", results.isComplete());
 
         // Verify "top" result
-        assertEquals(target2, results.getTopResult());
-
-        // Verify priority ("best" first)
-        assertThat(results.getTargets())
-                .containsExactly(
-                        target2,
-                        target6,
-                        target5,
-                        target4,
-                        target3,
-                        target1);
+        assertEquals("top result", target2, results.getTopResult());
     }
 
     /**
@@ -291,27 +325,22 @@
                 new Rect(1, 2, 3, 4), result.getScrollBounds());
     }
 
-    private void setupTargetView(View view, Rect localVisibleRect, int scrollCaptureHint) {
-        view.setScrollCaptureHint(scrollCaptureHint);
-        view.onVisibilityAggregated(true);
-        // Treat any offset as padding, outset localVisibleRect on all sides and use this as
-        // child bounds
-        Rect bounds = new Rect(localVisibleRect);
-        bounds.inset(-bounds.left, -bounds.top, bounds.left, bounds.top);
-        view.layout(bounds.left, bounds.top, bounds.right, bounds.bottom);
-        view.onVisibilityAggregated(true);
-    }
-
     private ScrollCaptureTarget createTarget(ScrollCaptureCallback callback, Rect localVisibleRect,
             Point positionInWindow, int scrollCaptureHint) {
-        View mockView = new View(getTargetContext());
+        Rect bounds = new Rect(localVisibleRect);
+        // Use localVisibleRect as position, treat left/top offset as padding
+        bounds.left = 0;
+        bounds.top = 0;
+        View mockView = new FakeView(getTargetContext(), bounds.left, bounds.top, bounds.right,
+                bounds.bottom, View.NO_ID);
         return createTargetWithView(mockView, callback, localVisibleRect, positionInWindow,
                 scrollCaptureHint);
     }
 
     private ScrollCaptureTarget createTargetWithView(View view, ScrollCaptureCallback callback,
             Rect localVisibleRect, Point positionInWindow, int scrollCaptureHint) {
-        setupTargetView(view, localVisibleRect, scrollCaptureHint);
+        view.setScrollCaptureHint(scrollCaptureHint);
+        view.onVisibilityAggregated(true);
         return new ScrollCaptureTarget(view, localVisibleRect, positionInWindow, callback);
     }
 
@@ -326,6 +355,32 @@
         @Override
         protected void onLayout(boolean changed, int l, int t, int r, int b) {
         }
+
+        /** Ignores window attachment state. The standard impl always returns [0,0] if the view is
+         *  not attached. This override allows testing without dealing with AttachInfo.
+         */
+        @Override
+        public void getLocationInWindow(int[] outLocation) {
+            outLocation[0] = mLeft;
+            outLocation[1] = mTop;
+            ViewParent viewParent = getParent();
+            while (viewParent instanceof View) {
+                final View view = (View) viewParent;
+
+                outLocation[0] -= view.mScrollX;
+                outLocation[1] -= view.mScrollY;
+
+                // Explicitly do not handle matrix/transforms, not needed for testing
+                if (!view.hasIdentityMatrix()) {
+                    throw new IllegalStateException("This mock does not handle transforms!");
+                }
+
+                outLocation[0] += view.mLeft;
+                outLocation[1] += view.mTop;
+
+                viewParent = view.mParent;
+            }
+        }
     }
 
     static class FakeScrollCaptureCallback implements ScrollCaptureCallback {
diff --git a/core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java b/core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java
index 25608c3..adf7a72 100644
--- a/core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java
+++ b/core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import static android.view.flags.Flags.FLAG_SCROLL_CAPTURE_TARGET_Z_ORDER_FIX;
+
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertEquals;
@@ -30,16 +32,20 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.CancellationSignal;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
 
 import androidx.annotation.NonNull;
 import androidx.test.filters.MediumTest;
 import androidx.test.filters.SmallTest;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.junit.MockitoJUnitRunner;
 
+import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
@@ -51,6 +57,9 @@
 @RunWith(MockitoJUnitRunner.class)
 public class ViewGroupScrollCaptureTest {
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private static final Executor DIRECT_EXECUTOR = Runnable::run;
 
     /** Make sure the hint flags are saved and loaded correctly. */
@@ -239,6 +248,56 @@
         assertNull(results.getTopResult());
     }
 
+    @EnableFlags(FLAG_SCROLL_CAPTURE_TARGET_Z_ORDER_FIX)
+    @MediumTest
+    @Test
+    public void testDispatchScrollCaptureSearch_traversesInDrawingOrder() throws Exception {
+        final Context context = getInstrumentation().getContext();
+        // Uses childDrawingOrder to reverse drawing order of children.
+        final MockViewGroup viewGroup = new MockViewGroup(context, 0, 0, 200, 200);
+
+        // w=200, h=180, z=10, drawn on top
+        final MockView view1 = new MockView(context, 0, 20, 200, 200);
+        TestScrollCaptureCallback callback1 = new TestScrollCaptureCallback();
+        view1.setScrollCaptureCallback(callback1);
+        view1.setZ(10f);
+
+        // w=200, h=200, z=0, drawn first, under view1
+        final MockView view2 = new MockView(context, 0, 0, 200, 200);
+        TestScrollCaptureCallback callback2 = new TestScrollCaptureCallback();
+        view2.setScrollCaptureCallback(callback2);
+
+        viewGroup.addView(view1); // test order is dependent on draw order by adding z=10 first
+        viewGroup.addView(view2);
+
+        Rect localVisibleRect = new Rect(0, 0, 200, 200);
+        Point windowOffset = new Point(0, 0);
+
+        // Where targets are added
+        final ScrollCaptureSearchResults results = new ScrollCaptureSearchResults(DIRECT_EXECUTOR);
+
+        viewGroup.dispatchScrollCaptureSearch(localVisibleRect, windowOffset, results::addTarget);
+        callback1.completeSearchRequest(new Rect(0, 0, 200, 180));
+        callback2.completeSearchRequest(new Rect(0, 0, 200, 200));
+        assertTrue(results.isComplete());
+
+        List<ScrollCaptureTarget> targets = results.getTargets();
+        List<View> targetViews =
+                targets.stream().map(ScrollCaptureTarget::getContainingView).toList();
+        assertEquals(List.of(view2,  view1), targetViews);
+    }
+
+    static final class ReverseDrawingViewGroup extends MockViewGroup {
+        ReverseDrawingViewGroup(Context context, int left, int top, int right, int bottom) {
+            super(context, left, top, right, bottom, View.SCROLL_CAPTURE_HINT_AUTO);
+        }
+
+        @Override
+        protected int getChildDrawingOrder(int childCount, int drawingPosition) {
+            return childCount == 0 ? 0 : childCount - (drawingPosition + 1);
+        }
+    }
+
     /**
      * Test scroll capture search dispatch to child views.
      * <p>
@@ -511,7 +570,7 @@
         }
     };
 
-    public static final class MockViewGroup extends ViewGroup {
+    public static class MockViewGroup extends ViewGroup {
         private ScrollCaptureCallback mInternalCallback;
         private Rect mOnScrollCaptureSearchLastLocalVisibleRect;
         private Point mOnScrollCaptureSearchLastWindowOffset;
diff --git a/core/tests/coretests/src/android/widget/ProgressBarTest.java b/core/tests/coretests/src/android/widget/ProgressBarTest.java
index fa6dd31..0cbfaa9 100644
--- a/core/tests/coretests/src/android/widget/ProgressBarTest.java
+++ b/core/tests/coretests/src/android/widget/ProgressBarTest.java
@@ -23,8 +23,12 @@
 
 import android.app.Instrumentation;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.Flags;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -32,6 +36,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -40,6 +45,10 @@
 @Presubmit
 public class ProgressBarTest {
     private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
     private ProgressBar mBar;
     private AccessibilityNodeInfo mInfo;
 
@@ -181,4 +190,16 @@
         mBar.onInitializeAccessibilityNodeInfo(mInfo);
         assertEquals("custom state", mInfo.getStateDescription().toString());
     }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_INDETERMINATE_RANGE_INFO)
+    public void testRangeInfo_indeterminateProgressBar_usesTypeIndeterminate() {
+        mBar.setIndeterminate(true);
+        assertTrue(mBar.isIndeterminate());
+
+        mBar.onInitializeAccessibilityNodeInfo(mInfo);
+
+        assertEquals(mInfo.getRangeInfo().getType(),
+                AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_INDETERMINATE);
+    }
 }
diff --git a/core/tests/coretests/src/android/window/OWNERS b/core/tests/coretests/src/android/window/OWNERS
index 6c80cf9..b3fcea2 100644
--- a/core/tests/coretests/src/android/window/OWNERS
+++ b/core/tests/coretests/src/android/window/OWNERS
@@ -1,2 +1,3 @@
 include /services/core/java/com/android/server/wm/OWNERS
-charlesccchen@google.com
+
+# Bug component: 1519745 = per-file WindowContext*,WindowMetrics*,WindowProvider*,WindowTokenClient*
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/window/WindowContextTest.java b/core/tests/coretests/src/android/window/WindowContextTest.java
index f1fbd55..21930d1 100644
--- a/core/tests/coretests/src/android/window/WindowContextTest.java
+++ b/core/tests/coretests/src/android/window/WindowContextTest.java
@@ -29,6 +29,11 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+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.verify;
 
 import android.app.Activity;
 import android.app.EmptyActivity;
@@ -60,6 +65,8 @@
 
 import com.android.frameworks.coretests.R;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -88,9 +95,21 @@
     private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
     private final WindowContext mWindowContext = createWindowContext();
     private final IWindowManager mWms = WindowManagerGlobal.getWindowManagerService();
+    private WindowTokenClientController mOriginalWindowTokenClientController;
 
     private static final int TIMEOUT_IN_SECONDS = 4;
 
+    @Before
+    public void setUp() {
+        // Keeping the original to set it back after each test, in case they applied any override.
+        mOriginalWindowTokenClientController = WindowTokenClientController.getInstance();
+    }
+
+    @After
+    public void tearDown() {
+        WindowTokenClientController.overrideForTesting(mOriginalWindowTokenClientController);
+    }
+
     @Test
     public void testCreateWindowContextWindowManagerAttachClientToken() {
         final WindowManager windowContextWm = WindowManagerImpl
@@ -320,6 +339,20 @@
         }
     }
 
+    @Test
+    public void updateDisplay_wasAttached_detachThenAttachedPropagatedToTokenController() {
+        final WindowTokenClientController mockWindowTokenClientController =
+                mock(WindowTokenClientController.class);
+        WindowTokenClientController.overrideForTesting(mockWindowTokenClientController);
+
+        mWindowContext.updateDisplay(DEFAULT_DISPLAY + 1);
+
+        verify(mockWindowTokenClientController).detachIfNeeded(any());
+        verify(mockWindowTokenClientController).attachToDisplayArea(any(),
+                anyInt(), /* displayId= */ eq(DEFAULT_DISPLAY + 1),
+                any());
+    }
+
     private WindowContext createWindowContext() {
         return createWindowContext(TYPE_APPLICATION_OVERLAY);
     }
diff --git a/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java b/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java
index a3725af..bb2fe1b 100644
--- a/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java
+++ b/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java
@@ -162,6 +162,22 @@
     }
 
     @Test
+    public void testAttachToDisplayContent_keepTrackWithoutWMS() {
+        // WMS is not initialized
+        doReturn(null).when(mController).getWindowManagerService();
+
+        assertFalse(mController.attachToDisplayContent(mWindowTokenClient, DEFAULT_DISPLAY));
+
+        // Can report config change
+        mController.onWindowContextInfoChanged(mWindowTokenClient, mWindowContextInfo);
+
+        verify(mWindowTokenClient).onConfigurationChanged(mConfiguration, DEFAULT_DISPLAY);
+
+        // No crash to detach even if WMS is not initialized.
+        mController.detachIfNeeded(mWindowTokenClient);
+    }
+
+    @Test
     public void testAttachToWindowToken() throws RemoteException {
         doReturn(null).when(mWindowManagerService).attachWindowContextToWindowToken(
                 any(), any(), any());
diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
index e640ce5..17fe15c 100644
--- a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
+++ b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
@@ -16,13 +16,17 @@
 
 package android.hardware.devicestate;
 
+import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 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.verifyZeroInteractions;
 
@@ -40,7 +44,6 @@
 import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.util.ConcurrentUtils;
 import com.android.window.flags.Flags;
 
 import org.junit.Before;
@@ -52,6 +55,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.Executor;
 
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
 import platform.test.runner.parameterized.Parameters;
@@ -103,7 +107,7 @@
                 permissionEnforcer, true /* simulatePostCallback */);
         final DeviceStateManagerGlobal dsmGlobal = new DeviceStateManagerGlobal(service);
         final DeviceStateCallback callback = mock(DeviceStateCallback.class);
-        dsmGlobal.registerDeviceStateCallback(callback, ConcurrentUtils.DIRECT_EXECUTOR);
+        dsmGlobal.registerDeviceStateCallback(callback, DIRECT_EXECUTOR);
 
         verify(callback, never()).onDeviceStateChanged(any());
 
@@ -120,49 +124,68 @@
         final IDeviceStateManager service = new TestDeviceStateManagerService(permissionEnforcer);
         final DeviceStateManagerGlobal dsmGlobal = new DeviceStateManagerGlobal(service);
         final DeviceStateCallback callback = mock(DeviceStateCallback.class);
-        dsmGlobal.registerDeviceStateCallback(callback, ConcurrentUtils.DIRECT_EXECUTOR);
+        dsmGlobal.registerDeviceStateCallback(callback, DIRECT_EXECUTOR);
 
         verify(callback).onDeviceStateChanged(eq(DEFAULT_DEVICE_STATE));
     }
 
     @Test
-    public void registerCallback() {
+    public void registerCallback_usesExecutorForCallbacks() {
+        final DeviceStateCallback callback = mock(DeviceStateCallback.class);
+        final Executor executor = mock(Executor.class);
+        doAnswer(invocation -> {
+            Runnable runnable = (Runnable) invocation.getArguments()[0];
+            runnable.run();
+            return null;
+        }).when(executor).execute(any(Runnable.class));
+
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback, executor);
+        mService.setBaseState(OTHER_DEVICE_STATE);
+        mService.setSupportedStates(List.of(OTHER_DEVICE_STATE));
+
+        // Verify that the given executor is used for both initial and subsequent callbacks.
+        verify(executor, times(4)).execute(any(Runnable.class));
+    }
+
+    @Test
+    public void registerCallback_supportedStatesChanged() {
         final DeviceStateCallback callback1 = mock(DeviceStateCallback.class);
         final DeviceStateCallback callback2 = mock(DeviceStateCallback.class);
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback1, DIRECT_EXECUTOR);
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback2, DIRECT_EXECUTOR);
 
-        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback1,
-                ConcurrentUtils.DIRECT_EXECUTOR);
-        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback2,
-                ConcurrentUtils.DIRECT_EXECUTOR);
-
-        // Verify initial callbacks
-        verify(callback1).onSupportedStatesChanged(eq(mService.getSupportedDeviceStates()));
-        verify(callback1).onDeviceStateChanged(eq(mService.getMergedState()));
-        verify(callback2).onDeviceStateChanged(eq(mService.getMergedState()));
-
-        reset(callback1);
-        reset(callback2);
-
-        // Change the supported states and verify callback
+        // Change the supported states and verify callback.
         mService.setSupportedStates(List.of(DEFAULT_DEVICE_STATE));
+
         verify(callback1).onSupportedStatesChanged(eq(mService.getSupportedDeviceStates()));
         verify(callback2).onSupportedStatesChanged(eq(mService.getSupportedDeviceStates()));
+    }
+
+    @Test
+    public void registerCallback_baseStateChanged() {
+        final DeviceStateCallback callback1 = mock(DeviceStateCallback.class);
+        final DeviceStateCallback callback2 = mock(DeviceStateCallback.class);
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback1, DIRECT_EXECUTOR);
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback2, DIRECT_EXECUTOR);
         mService.setSupportedStates(List.of(DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE));
 
-        reset(callback1);
-        reset(callback2);
-
-        // Change the base state and verify callback
+        // Change the base state and verify callback.
         mService.setBaseState(OTHER_DEVICE_STATE);
+
         verify(callback1).onDeviceStateChanged(eq(mService.getMergedState()));
         verify(callback2).onDeviceStateChanged(eq(mService.getMergedState()));
+    }
 
-        reset(callback1);
-        reset(callback2);
-
-        // Change the requested state and verify callback
+    @Test
+    public void registerCallback_requestedStateChanged() {
+        final DeviceStateCallback callback1 = mock(DeviceStateCallback.class);
+        final DeviceStateCallback callback2 = mock(DeviceStateCallback.class);
         final DeviceStateRequest request =
                 DeviceStateRequest.newBuilder(DEFAULT_DEVICE_STATE.getIdentifier()).build();
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback1, DIRECT_EXECUTOR);
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback2, DIRECT_EXECUTOR);
+
+        // Change the requested state and verify callback.
         mDeviceStateManagerGlobal.requestState(request, null /* executor */, null /* callback */);
 
         verify(callback1).onDeviceStateChanged(eq(mService.getMergedState()));
@@ -173,8 +196,7 @@
     public void unregisterCallback() {
         final DeviceStateCallback callback = mock(DeviceStateCallback.class);
 
-        mDeviceStateManagerGlobal
-                .registerDeviceStateCallback(callback, ConcurrentUtils.DIRECT_EXECUTOR);
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback, DIRECT_EXECUTOR);
 
         // Verify initial callbacks
         verify(callback).onSupportedStatesChanged(eq(mService.getSupportedDeviceStates()));
@@ -191,8 +213,7 @@
     @Test
     public void submitRequest() {
         final DeviceStateCallback callback = mock(DeviceStateCallback.class);
-        mDeviceStateManagerGlobal
-                .registerDeviceStateCallback(callback, ConcurrentUtils.DIRECT_EXECUTOR);
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback, DIRECT_EXECUTOR);
 
         verify(callback).onDeviceStateChanged(eq(mService.getBaseState()));
         reset(callback);
@@ -212,8 +233,7 @@
     @Test
     public void submitBaseStateOverrideRequest() {
         final DeviceStateCallback callback = mock(DeviceStateCallback.class);
-        mDeviceStateManagerGlobal
-                .registerDeviceStateCallback(callback, ConcurrentUtils.DIRECT_EXECUTOR);
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback, DIRECT_EXECUTOR);
 
         verify(callback).onDeviceStateChanged(eq(mService.getBaseState()));
         reset(callback);
@@ -234,8 +254,7 @@
     @Test
     public void submitBaseAndEmulatedStateOverride() {
         final DeviceStateCallback callback = mock(DeviceStateCallback.class);
-        mDeviceStateManagerGlobal
-                .registerDeviceStateCallback(callback, ConcurrentUtils.DIRECT_EXECUTOR);
+        mDeviceStateManagerGlobal.registerDeviceStateCallback(callback, DIRECT_EXECUTOR);
 
         verify(callback).onDeviceStateChanged(eq(mService.getBaseState()));
         reset(callback);
@@ -275,7 +294,7 @@
         final DeviceStateRequest request =
                 DeviceStateRequest.newBuilder(OTHER_DEVICE_STATE.getIdentifier()).build();
         mDeviceStateManagerGlobal.requestState(request,
-                ConcurrentUtils.DIRECT_EXECUTOR /* executor */,
+                DIRECT_EXECUTOR /* executor */,
                 callback /* callback */);
 
         verify(callback).onRequestActivated(eq(request));
diff --git a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
index 40d0bef..28d6545 100644
--- a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
+++ b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
@@ -210,21 +210,6 @@
     }
 
     @Test
-    public void registerOverlay_forAndroidPackage_shouldFail() {
-        FabricatedOverlayInternal overlayInternal =
-                createOverlayWithName(
-                        mOverlayName,
-                        SYSTEM_APP_OVERLAYABLE,
-                        "android",
-                        List.of(Pair.create("color/white", Pair.create(null, Color.BLACK))));
-
-        assertThrows(
-                "Wrong target package name",
-                IllegalArgumentException.class,
-                () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
-    }
-
-    @Test
     public void getOverlayInfosForTarget_defaultShouldBeZero() {
         List<OverlayInfo> overlayInfos =
                 mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName());
diff --git a/core/tests/vibrator/src/android/os/VibrationEffectTest.java b/core/tests/vibrator/src/android/os/VibrationEffectTest.java
index ccc5108..5f3754b 100644
--- a/core/tests/vibrator/src/android/os/VibrationEffectTest.java
+++ b/core/tests/vibrator/src/android/os/VibrationEffectTest.java
@@ -418,20 +418,45 @@
         // Effects created via waveformEnvelopeBuilder are not expected to be converted to long[]
         // patterns, as they are not configured to always play with the default amplitude.
         VibrationEffect effect = new VibrationEffect.WaveformEnvelopeBuilder()
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 50)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 80)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 40)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 50)
+                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 80)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 40)
                 .build();
 
         assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
 
         effect = new VibrationEffect.WaveformEnvelopeBuilder()
                 .setInitialFrequencyHz(/*initialFrequencyHz=*/ 60)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 50)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 80)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 40)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 50)
+                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 80)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 40)
+                .build();
+
+        assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+    public void computeLegacyPattern_effectsViaBasicEnvelopeBuilder() {
+        // Effects created via BasicEnvelopeBuilder are not expected to be converted to long[]
+        // patterns, as they are not configured to always play with the default amplitude.
+        VibrationEffect effect = new VibrationEffect.BasicEnvelopeBuilder()
+                .addControlPoint(/*intensity=*/ 0.1f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 20)
+                .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 50)
+                .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 80)
+                .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 40)
+                .build();
+
+        assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
+
+        effect = new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.1f)
+                .addControlPoint(/*intensity=*/ 0.2f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 20)
+                .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 50)
+                .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 80)
+                .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 40)
                 .build();
 
         assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
@@ -646,43 +671,43 @@
     @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
     public void testValidateWaveformEnvelopeBuilder() {
         new VibrationEffect.WaveformEnvelopeBuilder()
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 50)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 80)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 40)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 50)
+                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 80)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 40)
                 .build()
                 .validate();
 
         new VibrationEffect.WaveformEnvelopeBuilder()
                 .setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 50)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 80)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 40)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 50)
+                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 80)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 40)
                 .build()
                 .validate();
 
         VibrationEffect.createRepeatingEffect(
                 /*preamble=*/ new VibrationEffect.WaveformEnvelopeBuilder()
                         .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f,
-                                /*timeMillis=*/ 50)
+                                /*durationMillis=*/ 50)
                         .build(),
                 /*repeatingEffect=*/ new VibrationEffect.WaveformEnvelopeBuilder()
                         .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .addControlPoint(/*amplitude=*/ 0.5f, /*frequencyHz=*/ 150f,
-                                /*timeMillis=*/ 100)
+                                /*durationMillis=*/ 100)
                         .build()
         ).validate();
 
         VibrationEffect.createRepeatingEffect(
                 /*effect=*/ new VibrationEffect.WaveformEnvelopeBuilder()
                         .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .addControlPoint(/*amplitude=*/ 0.5f, /*frequencyHz=*/ 150f,
-                                /*timeMillis=*/ 100)
+                                /*durationMillis=*/ 100)
                         .build()
         ).validate();
 
@@ -691,25 +716,25 @@
         assertThrows(IllegalArgumentException.class,
                 () -> new VibrationEffect.WaveformEnvelopeBuilder()
                         .addControlPoint(/*amplitude=*/ -1.0f, /*frequencyHz=*/ 60f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .build()
                         .validate());
         assertThrows(IllegalArgumentException.class,
                 () -> new VibrationEffect.WaveformEnvelopeBuilder()
                         .addControlPoint(/*amplitude=*/ 1.1f, /*frequencyHz=*/ 60f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .build()
                         .validate());
         assertThrows(IllegalArgumentException.class,
                 () -> new VibrationEffect.WaveformEnvelopeBuilder()
                         .addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 0f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .build()
                         .validate());
         assertThrows(IllegalArgumentException.class,
                 () -> new VibrationEffect.WaveformEnvelopeBuilder()
                         .addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f,
-                                /*timeMillis=*/ 0)
+                                /*durationMillis=*/ 0)
                         .build()
                         .validate());
 
@@ -721,39 +746,156 @@
                 () -> new VibrationEffect.WaveformEnvelopeBuilder()
                         .setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
                         .addControlPoint(/*amplitude=*/ -1.0f, /*frequencyHz=*/ 60f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .build()
                         .validate());
         assertThrows(IllegalArgumentException.class,
                 () -> new VibrationEffect.WaveformEnvelopeBuilder()
                         .setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
                         .addControlPoint(/*amplitude=*/ 1.1f, /*frequencyHz=*/ 60f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .build()
                         .validate());
         assertThrows(IllegalArgumentException.class,
                 () -> new VibrationEffect.WaveformEnvelopeBuilder()
                         .setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
                         .addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 0f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .build()
                         .validate());
         assertThrows(IllegalArgumentException.class,
                 () -> new VibrationEffect.WaveformEnvelopeBuilder()
                         .setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
                         .addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f,
-                                /*timeMillis=*/ 0)
+                                /*durationMillis=*/ 0)
                         .build()
                         .validate());
         assertThrows(IllegalArgumentException.class,
                 () -> new VibrationEffect.WaveformEnvelopeBuilder()
                         .setInitialFrequencyHz(/*initialFrequencyHz=*/ 0)
                         .addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f,
-                                /*timeMillis=*/ 20)
+                                /*durationMillis=*/ 20)
                         .build().validate());
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+    public void testValidateBasicEnvelopeBuilder() {
+        new VibrationEffect.BasicEnvelopeBuilder()
+                .addControlPoint(/*intensity=*/ 0.1f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 20)
+                .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 50)
+                .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 80)
+                .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 40)
+                .build()
+                .validate();
+
+        new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.1f)
+                .addControlPoint(/*intensity=*/ 0.2f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 20)
+                .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 50)
+                .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 80)
+                .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 40)
+                .build()
+                .validate();
+
+        VibrationEffect.createRepeatingEffect(
+                /*preamble=*/ new VibrationEffect.BasicEnvelopeBuilder()
+                        // intensity, sharpness, durationMillis
+                        .addControlPoint(0.3f, 0.5f, 60)
+                        .addControlPoint(0.0f, 0.5f, 100)
+                        .build(),
+                /*repeatingEffect=*/ new VibrationEffect.BasicEnvelopeBuilder()
+                        // intensity, sharpness, durationMillis
+                        .addControlPoint(0.5f, 0.8f, 60)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+        ).validate();
+
+        VibrationEffect.createRepeatingEffect(
+                new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+                        // intensity, sharpness, durationMillis
+                        .addControlPoint(0.5f, 0.8f, 60)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+        ).validate();
+
+        assertThrows(IllegalStateException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder().build().validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                        .addControlPoint(-1.0f, 0.5f, 20)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                        .addControlPoint(1.1f, 0.5f, 20)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                        .addControlPoint(0.8f, -0.1f, 20)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                        .addControlPoint(0.8f, 0.5f, 0)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+                        .validate());
+        // Waveform effects created using the basic builder must end with a zero intensity
+        // control point.
+        assertThrows(IllegalStateException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                        .addControlPoint(0.8f, 0.5f, 100)
+                        .build()
+                        .validate());
+
+        assertThrows(IllegalStateException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/0.2f).build().validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+                        .addControlPoint(-1.0f, 0.5f, 20)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+                        .addControlPoint(1.1f, 0.5f, 20)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+                        .addControlPoint(0.8f, -0.1f, 20)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+                        .validate());
+        assertThrows(IllegalArgumentException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+                        .addControlPoint(0.8f, 0.5f, 0)
+                        .addControlPoint(0.0f, 0.3f, 100)
+                        .build()
+                        .validate());
+        // Waveform effects created using the basic builder must end with a zero intensity
+        // control point.
+        assertThrows(IllegalStateException.class,
+                () -> new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+                        .addControlPoint(0.8f, 0.5f, 100)
+                        .build()
+                        .validate());
+    }
+
+    @Test
     public void testValidateWaveformBuilder() {
         // Cover builder methods
         VibrationEffect.startWaveform(targetAmplitude(1))
@@ -1395,18 +1537,36 @@
     @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
     public void testIsHapticFeedbackCandidate_longEnvelopeEffects_notCandidates() {
         assertFalse(new VibrationEffect.WaveformEnvelopeBuilder()
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 200)
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 500)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 800)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 400)
+                //amplitude, frequencyHz, durationMillis
+                .addControlPoint(0.0f, 60f, 200)
+                .addControlPoint(0.3f, 100f, 500)
+                .addControlPoint(0.4f, 120f, 800)
+                .addControlPoint(0.0f, 120f, 400)
                 .build()
                 .isHapticFeedbackCandidate());
         assertFalse(new VibrationEffect.WaveformEnvelopeBuilder()
                 .setInitialFrequencyHz(/*initialFrequencyHz=*/ 40)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 200)
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 500)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 800)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 400)
+                //amplitude, frequencyHz, durationMillis
+                .addControlPoint(0.0f, 60f, 200)
+                .addControlPoint(0.3f, 100f, 500)
+                .addControlPoint(0.4f, 120f, 800)
+                .addControlPoint(0.0f, 120f, 400)
+                .build()
+                .isHapticFeedbackCandidate());
+
+        assertFalse(new VibrationEffect.BasicEnvelopeBuilder()
+                .addControlPoint(/*intensity=*/ 0.1f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 200)
+                .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 500)
+                .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 800)
+                .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 400)
+                .build()
+                .isHapticFeedbackCandidate());
+        assertFalse(new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+                .addControlPoint(/*intensity=*/ 0.1f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 200)
+                .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 500)
+                .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 800)
+                .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 400)
                 .build()
                 .isHapticFeedbackCandidate());
     }
@@ -1428,16 +1588,31 @@
     @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
     public void testIsHapticFeedbackCandidate_shortEnvelopeEffects_areCandidates() {
         assertTrue(new VibrationEffect.WaveformEnvelopeBuilder()
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 500)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 400)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 100)
+                //amplitude, frequencyHz, durationMillis
+                .addControlPoint(0.3f, 100f, 500)
+                .addControlPoint(0.4f, 120f, 400)
+                .addControlPoint(0.0f, 120f, 100)
                 .build()
                 .isHapticFeedbackCandidate());
         assertTrue(new VibrationEffect.WaveformEnvelopeBuilder()
                 .setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 500)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 400)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 100)
+                .addControlPoint(0.3f, 100f, 500)
+                .addControlPoint(0.4f, 120f, 400)
+                .addControlPoint(0.0f, 120f, 100)
+                .build()
+                .isHapticFeedbackCandidate());
+
+        assertTrue(new VibrationEffect.BasicEnvelopeBuilder()
+                .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 500)
+                .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 400)
+                .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 100)
+                .build()
+                .isHapticFeedbackCandidate());
+        assertTrue(new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+                .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 500)
+                .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 400)
+                .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 100)
                 .build()
                 .isHapticFeedbackCandidate());
     }
diff --git a/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java b/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java
index 1cc38de..4071057 100644
--- a/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java
+++ b/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java
@@ -16,6 +16,8 @@
 
 package android.os.vibrator.persistence;
 
+import static android.os.VibrationEffect.Composition.DELAY_TYPE_PAUSE;
+import static android.os.VibrationEffect.Composition.DELAY_TYPE_RELATIVE_START_OFFSET;
 import static android.os.VibrationEffect.Composition.PRIMITIVE_CLICK;
 import static android.os.VibrationEffect.Composition.PRIMITIVE_LOW_TICK;
 import static android.os.VibrationEffect.Composition.PRIMITIVE_SPIN;
@@ -31,6 +33,7 @@
 import android.os.VibrationEffect;
 import android.os.vibrator.Flags;
 import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.SetFlagsRule;
@@ -437,7 +440,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
-    public void testVendorEffect_featureFlagEnabled_allSucceed() throws Exception {
+    public void testVendorEffect_allSucceed() throws Exception {
         PersistableBundle vendorData = new PersistableBundle();
         vendorData.putInt("id", 1);
         vendorData.putDouble("scale", 0.5);
@@ -476,7 +479,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
-    public void testInvalidVendorEffect_featureFlagEnabled_allFail() throws IOException {
+    public void testInvalidVendorEffect_allFail() throws IOException {
         String emptyTag = "<vibration-effect><vendor-effect/></vibration-effect>";
         assertPublicApisParserFails(emptyTag);
         assertHiddenApisParserFails(emptyTag);
@@ -526,6 +529,81 @@
         assertHiddenApisSerializerFails(vendorEffect);
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY)
+    public void testPrimitiveDelayType_allSucceed() throws Exception {
+        VibrationEffect effect = VibrationEffect.startComposition()
+                .addPrimitive(PRIMITIVE_TICK, 1.0f, 0, DELAY_TYPE_RELATIVE_START_OFFSET)
+                .addPrimitive(PRIMITIVE_CLICK, 0.123f, 10, DELAY_TYPE_PAUSE)
+                .compose();
+        String xml = """
+                <vibration-effect>
+                    <primitive-effect name="tick" delayType="relative_start_offset"/>
+                    <primitive-effect name="click" scale="0.123" delayMs="10"/>
+                </vibration-effect>
+                """;
+
+        assertPublicApisParserSucceeds(xml, effect);
+        assertPublicApisSerializerSucceeds(effect, "tick", "click");
+        // Delay type pause is not serialized, as it's the default one
+        assertPublicApisSerializerSucceeds(effect, "relative_start_offset", "click");
+        assertPublicApisRoundTrip(effect);
+
+        assertHiddenApisParserSucceeds(xml, effect);
+        assertHiddenApisSerializerSucceeds(effect, "tick", "click");
+        assertHiddenApisRoundTrip(effect);
+
+        // Check PersistableBundle from round-trip
+        VibrationEffect.Composed parsedEffect = ((VibrationEffect.Composed) parseVibrationEffect(
+                serialize(effect), /* flags= */ 0));
+        assertThat(parsedEffect.getRepeatIndex()).isEqualTo(-1);
+        assertThat(parsedEffect.getSegments()).containsExactly(
+                new PrimitiveSegment(PRIMITIVE_TICK, 1.0f, 0, DELAY_TYPE_RELATIVE_START_OFFSET),
+                new PrimitiveSegment(PRIMITIVE_CLICK, 0.123f, 10, DELAY_TYPE_PAUSE))
+                .inOrder();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY)
+    public void testPrimitiveInvalidDelayType_allFail() {
+        String emptyAttribute = """
+                <vibration-effect>
+                    <primitive-effect name="tick" delayType=""/>
+                </vibration-effect>
+                """;
+        assertPublicApisParserFails(emptyAttribute);
+        assertHiddenApisParserFails(emptyAttribute);
+
+        String invalidString = """
+                <vibration-effect>
+                    <primitive-effect name="tick" delayType="invalid"/>
+                </vibration-effect>
+                """;
+        assertPublicApisParserFails(invalidString);
+        assertHiddenApisParserFails(invalidString);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY)
+    public void testPrimitiveDelayType_featureFlagDisabled_allFail() {
+        VibrationEffect effect = VibrationEffect.startComposition()
+                .addPrimitive(PRIMITIVE_TICK, 1.0f, 0, DELAY_TYPE_RELATIVE_START_OFFSET)
+                .addPrimitive(PRIMITIVE_CLICK, 0.123f, 10, DELAY_TYPE_PAUSE)
+                .compose();
+        String xml = """
+                <vibration-effect>
+                    <primitive-effect name="tick" delayType="relative_start_offset"/>
+                    <primitive-effect name="click" scale="0.123" delayMs="10" delayType="pause"/>
+                </vibration-effect>
+                """;
+
+        assertPublicApisParserFails(xml);
+        assertPublicApisSerializerFails(effect);
+
+        assertHiddenApisParserFails(xml);
+        assertHiddenApisSerializerFails(effect);
+    }
+
     private void assertPublicApisParserFails(String xml) {
         assertThrows("Expected parseVibrationEffect to fail for " + xml,
                 VibrationXmlParser.ParseFailedException.class,
diff --git a/core/xsd/permission.xsd b/core/xsd/permission.xsd
index 0ec8f7d..0a0ca7c 100644
--- a/core/xsd/permission.xsd
+++ b/core/xsd/permission.xsd
@@ -43,6 +43,7 @@
                 <xs:element name="disabled-until-used-preinstalled-carrier-app" type="disabled-until-used-preinstalled-carrier-app"/>
                 <xs:element name="privapp-permissions" type="privapp-permissions"/>
                 <xs:element name="oem-permissions" type="oem-permissions"/>
+                <xs:element name="signature-permissions" type="signature-permissions"/>
                 <xs:element name="hidden-api-whitelisted-app" type="hidden-api-whitelisted-app"/>
                 <xs:element name="allow-association" type="allow-association"/>
                 <xs:element name="bugreport-whitelisted" type="bugreport-whitelisted"/>
@@ -156,6 +157,21 @@
         </xs:sequence>
         <xs:attribute name="package" type="xs:string"/>
     </xs:complexType>
+    <xs:complexType name="signature-permissions">
+        <xs:sequence>
+            <xs:element name="permission" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:string"/>
+                </xs:complexType>
+            </xs:element>
+            <xs:element name="deny-permission" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:string"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+        <xs:attribute name="package" type="xs:string"/>
+    </xs:complexType>
     <xs:complexType name="hidden-api-whitelisted-app">
         <xs:attribute name="package" type="xs:string"/>
     </xs:complexType>
diff --git a/core/xsd/schema/current.txt b/core/xsd/schema/current.txt
index f3beea1..cdec6ab 100644
--- a/core/xsd/schema/current.txt
+++ b/core/xsd/schema/current.txt
@@ -183,6 +183,7 @@
     method public java.util.List<com.android.xml.permission.configfile.OemPermissions> getOemPermissions_optional();
     method public java.util.List<com.android.xml.permission.configfile.Permission> getPermission_optional();
     method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions> getPrivappPermissions_optional();
+    method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions> getSignaturePermissions_optional();
     method public java.util.List<com.android.xml.permission.configfile.SplitPermission> getSplitPermission_optional();
     method public java.util.List<com.android.xml.permission.configfile.SystemUserBlacklistedApp> getSystemUserBlacklistedApp_optional();
     method public java.util.List<com.android.xml.permission.configfile.SystemUserWhitelistedApp> getSystemUserWhitelistedApp_optional();
@@ -209,6 +210,26 @@
     method public void setName(String);
   }
 
+  public class SignaturePermissions {
+    ctor public SignaturePermissions();
+    method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions.DenyPermission> getDenyPermission();
+    method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions.Permission> getPermission();
+    method public String get_package();
+    method public void set_package(String);
+  }
+
+  public static class SignaturePermissions.DenyPermission {
+    ctor public SignaturePermissions.DenyPermission();
+    method public String getName();
+    method public void setName(String);
+  }
+
+  public static class SignaturePermissions.Permission {
+    ctor public SignaturePermissions.Permission();
+    method public String getName();
+    method public void setName(String);
+  }
+
   public class SplitPermission {
     ctor public SplitPermission();
     method public java.util.List<com.android.xml.permission.configfile.SplitPermission.Library> getLibrary();
diff --git a/core/xsd/vibrator/vibration/schema/current.txt b/core/xsd/vibrator/vibration/schema/current.txt
index 280b405..b4148d6 100644
--- a/core/xsd/vibrator/vibration/schema/current.txt
+++ b/core/xsd/vibrator/vibration/schema/current.txt
@@ -15,12 +15,20 @@
     enum_constant public static final com.android.internal.vibrator.persistence.PredefinedEffectName tick;
   }
 
+  public enum PrimitiveDelayType {
+    method public String getRawName();
+    enum_constant public static final com.android.internal.vibrator.persistence.PrimitiveDelayType pause;
+    enum_constant public static final com.android.internal.vibrator.persistence.PrimitiveDelayType relative_start_offset;
+  }
+
   public class PrimitiveEffect {
     ctor public PrimitiveEffect();
     method public java.math.BigInteger getDelayMs();
+    method public com.android.internal.vibrator.persistence.PrimitiveDelayType getDelayType();
     method public com.android.internal.vibrator.persistence.PrimitiveEffectName getName();
     method public float getScale();
     method public void setDelayMs(java.math.BigInteger);
+    method public void setDelayType(com.android.internal.vibrator.persistence.PrimitiveDelayType);
     method public void setName(com.android.internal.vibrator.persistence.PrimitiveEffectName);
     method public void setScale(float);
   }
diff --git a/core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd b/core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd
index 21a6fac..910a9b7 100644
--- a/core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd
+++ b/core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd
@@ -147,6 +147,7 @@
         <xs:attribute name="name" type="PrimitiveEffectName" use="required"/>
         <xs:attribute name="scale" type="PrimitiveScale"/>
         <xs:attribute name="delayMs" type="xs:nonNegativeInteger"/>
+        <xs:attribute name="delayType" type="PrimitiveDelayType"/>
     </xs:complexType>
 
     <!-- Primitive names as defined by VibrationEffect.Composition.PRIMITIVE_* -->
@@ -171,4 +172,12 @@
         </xs:restriction>
     </xs:simpleType>
 
+    <!-- Primitive delay types VibrationEffect.Composition.DELAY_TYPE_* -->
+    <xs:simpleType  name="PrimitiveDelayType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="pause"/>
+            <xs:enumeration value="relative_start_offset"/>
+        </xs:restriction>
+    </xs:simpleType>
+
 </xs:schema>
diff --git a/core/xsd/vibrator/vibration/vibration.xsd b/core/xsd/vibrator/vibration/vibration.xsd
index d35d777..3c8e016 100644
--- a/core/xsd/vibrator/vibration/vibration.xsd
+++ b/core/xsd/vibrator/vibration/vibration.xsd
@@ -124,6 +124,7 @@
         <xs:attribute name="name" type="PrimitiveEffectName" use="required"/>
         <xs:attribute name="scale" type="PrimitiveScale"/>
         <xs:attribute name="delayMs" type="xs:nonNegativeInteger"/>
+        <xs:attribute name="delayType" type="PrimitiveDelayType"/>
     </xs:complexType>
 
     <!-- Primitive names as defined by VibrationEffect.Composition.PRIMITIVE_* -->
@@ -148,4 +149,12 @@
         </xs:restriction>
     </xs:simpleType>
 
+    <!-- Primitive delay types VibrationEffect.Composition.DELAY_TYPE_* -->
+    <xs:simpleType  name="PrimitiveDelayType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="pause"/>
+            <xs:enumeration value="relative_start_offset"/>
+        </xs:restriction>
+    </xs:simpleType>
+
 </xs:schema>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 836870e..897fc54 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -583,7 +583,6 @@
         <permission name="android.permission.READ_BLOCKED_NUMBERS" />
         <!-- Permission required for CTS test - PackageManagerTest -->
         <permission name="android.permission.DOMAIN_VERIFICATION_AGENT"/>
-        <permission name="android.permission.VERIFICATION_AGENT"/>
         <!-- Permission required for CTS test CtsInputTestCases -->
         <permission name="android.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW" />
         <!-- Permission required for CTS test - PackageManagerShellCommandInstallTest -->
@@ -600,7 +599,7 @@
         <!-- Permission required for CTS test - CtsAppTestCases -->
         <permission name="android.permission.KILL_UID" />
         <!-- Permission required for CTS test - AdvancedProtectionManagerTest -->
-        <permission name="android.permission.SET_ADVANCED_PROTECTION_MODE" />
+        <permission name="android.permission.MANAGE_ADVANCED_PROTECTION_MODE" />
         <permission name="android.permission.QUERY_ADVANCED_PROTECTION_MODE" />
         <!-- Permissions required for CTS test - SettingsPreferenceServiceClientTest -->
         <permission name="android.permission.READ_SYSTEM_PREFERENCES" />
@@ -678,8 +677,4 @@
         <permission name="android.permission.BATTERY_STATS"/>
         <permission name="android.permission.ENTER_TRADE_IN_MODE"/>
     </privapp-permissions>
-
-    <privapp-permissions package="com.android.multiuser">
-        <permission name="android.permission.MANAGE_USERS"/>
-    </privapp-permissions>
 </permissions>
diff --git a/errorprone/Android.bp b/errorprone/Android.bp
index b559a15..1428b89 100644
--- a/errorprone/Android.bp
+++ b/errorprone/Android.bp
@@ -31,6 +31,14 @@
         "//external/auto:auto_service_annotations",
     ],
 
+    javacflags: [
+        // These exports are needed because this errorprone plugin access some private classes
+        // of the java compiler.
+        "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+        "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
+        "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
+    ],
+
     plugins: [
         "//external/auto:auto_service_plugin",
     ],
diff --git a/graphics/java/android/graphics/RuntimeColorFilter.java b/graphics/java/android/graphics/RuntimeColorFilter.java
index d112f71..a64acfe 100644
--- a/graphics/java/android/graphics/RuntimeColorFilter.java
+++ b/graphics/java/android/graphics/RuntimeColorFilter.java
@@ -280,7 +280,8 @@
         if (colorFilter == null) {
             throw new NullPointerException("The colorFilter parameter must not be null");
         }
-        nativeUpdateChild(getNativeInstance(), filterName, colorFilter.getNativeInstance());
+        nativeUpdateInputColorFilter(getNativeInstance(), filterName,
+                colorFilter.getNativeInstance());
     }
 
     /**
@@ -318,5 +319,6 @@
             long colorFilter, String uniformName, int value1, int value2, int value3,
             int value4, int count);
     private static native void nativeUpdateChild(long colorFilter, String childName, long child);
-
+    private static native void nativeUpdateInputColorFilter(long colorFilter, String childName,
+            long inputFilter);
 }
diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java
index 6316c1f..3543e99 100644
--- a/graphics/java/android/graphics/RuntimeShader.java
+++ b/graphics/java/android/graphics/RuntimeShader.java
@@ -264,6 +264,9 @@
      * enable better heap tracking & tooling support
      */
     private ArrayMap<String, Shader> mShaderUniforms = new ArrayMap<>();
+    private ArrayMap<String, ColorFilter> mColorFilterUniforms = new ArrayMap<>();
+    private ArrayMap<String, RuntimeXfermode> mXfermodeUniforms = new ArrayMap<>();
+
 
     /**
      * Creates a new RuntimeShader.
@@ -544,8 +547,10 @@
         if (colorFilter == null) {
             throw new NullPointerException("The colorFilter parameter must not be null");
         }
-        nativeUpdateChild(mNativeInstanceRuntimeShaderBuilder, filterName,
+        mColorFilterUniforms.put(filterName, colorFilter);
+        nativeUpdateColorFilter(mNativeInstanceRuntimeShaderBuilder, filterName,
                 colorFilter.getNativeInstance());
+        discardNativeInstance();
     }
 
     /**
@@ -563,8 +568,10 @@
         if (xfermode == null) {
             throw new NullPointerException("The xfermode parameter must not be null");
         }
+        mXfermodeUniforms.put(xfermodeName, xfermode);
         nativeUpdateChild(mNativeInstanceRuntimeShaderBuilder, xfermodeName,
                 xfermode.createNativeInstance());
+        discardNativeInstance();
     }
 
 
@@ -594,6 +601,8 @@
             int value4, int count);
     private static native void nativeUpdateShader(
             long shaderBuilder, String shaderName, long shader);
+    private static native void nativeUpdateColorFilter(
+            long shaderBuilder, String colorFilterName, long colorFilter);
     private static native void nativeUpdateChild(
             long shaderBuilder, String childName, long child);
 }
diff --git a/graphics/java/android/graphics/RuntimeXfermode.java b/graphics/java/android/graphics/RuntimeXfermode.java
index 51d97a4..c8a0b1a 100644
--- a/graphics/java/android/graphics/RuntimeXfermode.java
+++ b/graphics/java/android/graphics/RuntimeXfermode.java
@@ -285,7 +285,8 @@
         if (colorFilter == null) {
             throw new NullPointerException("The colorFilter parameter must not be null");
         }
-        nativeUpdateChild(mBuilderNativeInstance, filterName, colorFilter.getNativeInstance());
+        nativeUpdateColorFilter(mBuilderNativeInstance, filterName,
+                colorFilter.getNativeInstance());
     }
 
     /**
@@ -325,5 +326,6 @@
             long builder, String uniformName, int value1, int value2, int value3,
             int value4, int count);
     private static native void nativeUpdateChild(long builder, String childName, long child);
+    private static native void nativeUpdateColorFilter(long builder, String childName, long filter);
 
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index 0896138..223f9f6 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -26,12 +26,12 @@
 import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback;
 import android.hardware.devicestate.DeviceStateUtil;
+import android.os.Looper;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseIntArray;
 
 import androidx.annotation.BinderThread;
-import androidx.annotation.GuardedBy;
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
@@ -39,7 +39,6 @@
 import androidx.window.common.layout.DisplayFoldFeatureCommon;
 
 import com.android.internal.R;
-import com.android.window.flags.Flags;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -70,19 +69,10 @@
      * "rear display". Concurrent mode for example is activated via public API and can be active in
      * both the "open" and "half folded" device states.
      */
-    // TODO: b/337820752 - Add @GuardedBy("mCurrentDeviceStateLock") after flag cleanup.
     private DeviceState mCurrentDeviceState = INVALID_DEVICE_STATE;
 
-    /**
-     * Lock to synchronize access to {@link #mCurrentDeviceState}.
-     *
-     * <p>This lock is used to ensure thread-safety when accessing and modifying the
-     * {@link #mCurrentDeviceState} field. It is acquired by both the binder thread (if
-     * {@link Flags#wlinfoOncreate()} is enabled) and the main thread (if
-     * {@link Flags#wlinfoOncreate()} is disabled) to prevent race conditions and
-     * ensure data consistency.
-     */
-    private final Object mCurrentDeviceStateLock = new Object();
+    @NonNull
+    private final Context mContext;
 
     @NonNull
     private final RawFoldingFeatureProducer mRawFoldSupplier;
@@ -90,38 +80,40 @@
     @NonNull
     private final DeviceStateMapper mDeviceStateMapper;
 
-    @VisibleForTesting
-    final DeviceStateCallback mDeviceStateCallback = new DeviceStateCallback() {
-        // The GuardedBy analysis is intra-procedural, meaning it doesn’t consider the getData()
-        // implementation. See https://errorprone.info/bugpattern/GuardedBy for limitations.
-        @SuppressWarnings("GuardedBy")
-        @BinderThread // When Flags.wlinfoOncreate() is enabled.
-        @MainThread // When Flags.wlinfoOncreate() is disabled.
+    private final DeviceStateCallback mDeviceStateCallback = new DeviceStateCallback() {
+        @BinderThread // Subsequent callback after registered.
+        @MainThread // Initial callback if registration is on the main thread.
         @Override
         public void onDeviceStateChanged(@NonNull DeviceState state) {
-            synchronized (mCurrentDeviceStateLock) {
-                mCurrentDeviceState = state;
-                mRawFoldSupplier.getData(DeviceStateManagerFoldingFeatureProducer.this
-                        ::notifyFoldingFeatureChangeLocked);
-            }
+            final boolean isMainThread = Looper.myLooper() == Looper.getMainLooper();
+            final Executor executor = isMainThread ? Runnable::run : mContext.getMainExecutor();
+            executor.execute(() -> {
+                DeviceStateManagerFoldingFeatureProducer.this.onDeviceStateChanged(state);
+            });
         }
     };
 
     public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context,
             @NonNull RawFoldingFeatureProducer rawFoldSupplier,
             @NonNull DeviceStateManager deviceStateManager) {
+        mContext = context;
         mRawFoldSupplier = rawFoldSupplier;
         mDeviceStateMapper =
                 new DeviceStateMapper(context, deviceStateManager.getSupportedDeviceStates());
 
         if (!mDeviceStateMapper.isDeviceStateToPostureMapEmpty()) {
-            final Executor executor =
-                    Flags.wlinfoOncreate() ? Runnable::run : context.getMainExecutor();
             Objects.requireNonNull(deviceStateManager)
-                    .registerCallback(executor, mDeviceStateCallback);
+                    .registerCallback(Runnable::run, mDeviceStateCallback);
         }
     }
 
+    @MainThread
+    @VisibleForTesting
+    void onDeviceStateChanged(@NonNull DeviceState state) {
+        mCurrentDeviceState = state;
+        mRawFoldSupplier.getData(this::notifyFoldingFeatureChangeLocked);
+    }
+
     /**
      * Add a callback to mCallbacks if there is no device state. This callback will be run
      * once a device state is set. Otherwise,run the callback immediately.
@@ -139,27 +131,20 @@
         }
     }
 
-    // The GuardedBy analysis is intra-procedural, meaning it doesn’t consider the implementation of
-    // addDataChangedCallback(). See https://errorprone.info/bugpattern/GuardedBy for limitations.
-    @SuppressWarnings("GuardedBy")
     @Override
     protected void onListenersChanged() {
         super.onListenersChanged();
-        synchronized (mCurrentDeviceStateLock) {
-            if (hasListeners()) {
-                mRawFoldSupplier.addDataChangedCallback(this::notifyFoldingFeatureChangeLocked);
-            } else {
-                mCurrentDeviceState = INVALID_DEVICE_STATE;
-                mRawFoldSupplier.removeDataChangedCallback(this::notifyFoldingFeatureChangeLocked);
-            }
+        if (hasListeners()) {
+            mRawFoldSupplier.addDataChangedCallback(this::notifyFoldingFeatureChangeLocked);
+        } else {
+            mCurrentDeviceState = INVALID_DEVICE_STATE;
+            mRawFoldSupplier.removeDataChangedCallback(this::notifyFoldingFeatureChangeLocked);
         }
     }
 
     @NonNull
     private DeviceState getCurrentDeviceState() {
-        synchronized (mCurrentDeviceStateLock) {
-            return mCurrentDeviceState;
-        }
+        return mCurrentDeviceState;
     }
 
     @NonNull
@@ -231,7 +216,6 @@
         });
     }
 
-    @GuardedBy("mCurrentDeviceStateLock")
     private void notifyFoldingFeatureChangeLocked(String displayFeaturesString) {
         final DeviceState state = mCurrentDeviceState;
         if (!mDeviceStateMapper.isDeviceStateValid(state)) {
@@ -252,29 +236,16 @@
         return parseListFromString(displayFeaturesString, hingeState);
     }
 
-    /**
-     * Internal class to map device states to corresponding postures.
-     *
-     * <p>This class encapsulates the logic for mapping device states to postures. The mapping is
-     * immutable after initialization to ensure thread safety.
-     */
+    /** Internal class to map device states to corresponding postures. */
     private static class DeviceStateMapper {
         /**
          * Emulated device state
          * {@link DeviceStateManager.DeviceStateCallback#onDeviceStateChanged(DeviceState)} to
          * {@link CommonFoldingFeature.State} map.
-         *
-         * <p>This map must be immutable after initialization to ensure thread safety, as it may be
-         * accessed from multiple threads. Modifications should only occur during object
-         * construction.
          */
         private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
 
-        /**
-         * The list of device states that are supported.
-         *
-         * <p>This list must be immutable after initialization to ensure thread safety.
-         */
+        /** The list of device states that are supported. */
         @NonNull
         private final List<DeviceState> mSupportedStates;
 
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
index 6928409..a5a84db 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
@@ -182,8 +182,15 @@
 
     @NonNull
     List<ParcelableSplitContainerData> getParcelableSplitContainerDataList() {
-        final List<ParcelableSplitContainerData> data = new ArrayList<>(mSplitContainers.size());
+        final int size =
+                mSplitPinContainer != null ? mSplitContainers.size() - 1 : mSplitContainers.size();
+        final List<ParcelableSplitContainerData> data = new ArrayList<>(size);
         for (SplitContainer splitContainer : mSplitContainers) {
+            if (splitContainer == mSplitPinContainer) {
+                // Skip SplitPinContainer as it cannot be restored because the SplitPinRule is
+                // set while pinning the container in runtime.
+                continue;
+            }
             data.add(splitContainer.getParcelableData());
         }
         return data;
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducerTest.kt b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducerTest.kt
index 90887a7..ad29bf6 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducerTest.kt
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducerTest.kt
@@ -20,10 +20,8 @@
 import android.content.res.Resources
 import android.hardware.devicestate.DeviceState
 import android.hardware.devicestate.DeviceStateManager
-import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
-import android.platform.test.flag.junit.SetFlagsRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
 import androidx.window.common.layout.CommonFoldingFeature
 import androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_FLAT
 import androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_HALF_OPENED
@@ -34,19 +32,16 @@
 import androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED
 import androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN
 import com.android.internal.R
-import com.android.window.flags.Flags
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
 import java.util.concurrent.Executor
 import java.util.function.Consumer
-import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
 import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.doAnswer
 import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
 import org.mockito.kotlin.stub
@@ -60,9 +55,6 @@
  */
 @RunWith(AndroidJUnit4::class)
 class DeviceStateManagerFoldingFeatureProducerTest {
-    @get:Rule
-    val setFlagsRule: SetFlagsRule = SetFlagsRule()
-
     private val mMockDeviceStateManager = mock<DeviceStateManager>()
     private val mMockResources = mock<Resources> {
         on { getStringArray(R.array.config_device_state_postures) } doReturn DEVICE_STATE_POSTURES
@@ -79,32 +71,39 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_WLINFO_ONCREATE)
-    fun testRegisterCallback_whenWlinfoOncreateIsDisabled_usesMainExecutor() {
+    fun testRegisterCallback_initialCallbackOnMainThread_executesDirectly() {
         DeviceStateManagerFoldingFeatureProducer(
             mMockContext,
             mRawFoldSupplier,
             mMockDeviceStateManager,
         )
+        val callbackCaptor = argumentCaptor<DeviceStateManager.DeviceStateCallback>()
+        verify(mMockDeviceStateManager).registerCallback(any(), callbackCaptor.capture())
 
-        verify(mMockDeviceStateManager).registerCallback(eq(mMockContext.mainExecutor), any())
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
+            callbackCaptor.firstValue.onDeviceStateChanged(DEVICE_STATE_HALF_OPENED)
+        }
+
+        verify(mMockContext, never()).getMainExecutor()
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_WLINFO_ONCREATE)
-    fun testRegisterCallback_whenWlinfoOncreateIsEnabled_usesRunnableRun() {
-        val executorCaptor = ArgumentCaptor.forClass(Executor::class.java)
-        val runnable = mock<Runnable>()
-
+    fun testRegisterCallback_subsequentCallbacks_postsToMainThread() {
+        val mockMainExecutor = mock<Executor>()
+        mMockContext.stub {
+            on { getMainExecutor() } doReturn mockMainExecutor
+        }
         DeviceStateManagerFoldingFeatureProducer(
             mMockContext,
             mRawFoldSupplier,
             mMockDeviceStateManager,
         )
+        val callbackCaptor = argumentCaptor<DeviceStateManager.DeviceStateCallback>()
+        verify(mMockDeviceStateManager).registerCallback(any(), callbackCaptor.capture())
 
-        verify(mMockDeviceStateManager).registerCallback(executorCaptor.capture(), any())
-        executorCaptor.value.execute(runnable)
-        verify(runnable).run()
+        callbackCaptor.firstValue.onDeviceStateChanged(DEVICE_STATE_HALF_OPENED)
+
+        verify(mockMainExecutor).execute(any())
     }
 
     @Test
@@ -114,7 +113,7 @@
             mRawFoldSupplier,
             mMockDeviceStateManager,
         )
-        ffp.mDeviceStateCallback.onDeviceStateChanged(DEVICE_STATE_HALF_OPENED)
+        ffp.onDeviceStateChanged(DEVICE_STATE_HALF_OPENED)
 
         val currentData = ffp.getCurrentData()
 
@@ -237,7 +236,7 @@
             mRawFoldSupplier,
             mMockDeviceStateManager,
         )
-        ffp.mDeviceStateCallback.onDeviceStateChanged(DEVICE_STATE_HALF_OPENED)
+        ffp.onDeviceStateChanged(DEVICE_STATE_HALF_OPENED)
         val storeFeaturesConsumer = mock<Consumer<List<CommonFoldingFeature>>>()
 
         ffp.getData(storeFeaturesConsumer)
@@ -257,8 +256,8 @@
         ffp.getData(storeFeaturesConsumer)
 
         verify(storeFeaturesConsumer, never()).accept(any())
-        ffp.mDeviceStateCallback.onDeviceStateChanged(DEVICE_STATE_HALF_OPENED)
-        ffp.mDeviceStateCallback.onDeviceStateChanged(DEVICE_STATE_OPENED)
+        ffp.onDeviceStateChanged(DEVICE_STATE_HALF_OPENED)
+        ffp.onDeviceStateChanged(DEVICE_STATE_OPENED)
         verify(storeFeaturesConsumer).accept(HALF_OPENED_FOLDING_FEATURES)
     }
 
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 42188de..4c75ea4 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -156,51 +156,6 @@
     },
 }
 
-filegroup {
-    name: "wm_shell-shared-utils",
-    srcs: [
-        "shared/src/com/android/wm/shell/shared/TransitionUtil.java",
-    ],
-}
-
-filegroup {
-    name: "wm_shell-shared-aidls",
-
-    srcs: [
-        "shared/**/*.aidl",
-    ],
-
-    path: "shared/src",
-}
-
-java_library {
-    name: "WindowManager-Shell-shared",
-
-    srcs: [
-        "shared/**/*.java",
-        "shared/**/*.kt",
-        ":wm_shell-shared-aidls",
-    ],
-    static_libs: [
-        "androidx.core_core-animation",
-        "androidx.dynamicanimation_dynamicanimation",
-        "jsr330",
-    ],
-    kotlincflags: ["-Xjvm-default=all"],
-}
-
-java_library {
-    name: "WindowManager-Shell-shared-desktopMode",
-
-    srcs: [
-        "shared/**/desktopmode/*.java",
-        "shared/**/desktopmode/*.kt",
-    ],
-    static_libs: [
-        "com.android.window.flags.window-aconfig-java",
-    ],
-}
-
 android_library {
     name: "WindowManager-Shell",
     srcs: [
@@ -227,6 +182,7 @@
         "kotlinx-coroutines-core",
         "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
         "//frameworks/libs/systemui:iconloader_base",
+        "com_android_launcher3_flags_lib",
         "com_android_wm_shell_flags_lib",
         "PlatformAnimationLib",
         "WindowManager-Shell-proto",
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt
new file mode 100644
index 0000000..f535fbd
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles
+
+import android.content.Context
+import android.content.pm.LauncherApps
+import android.graphics.Insets
+import android.graphics.Rect
+import android.os.Handler
+import android.os.UserManager
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.view.IWindowManager
+import android.view.WindowManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.internal.protolog.ProtoLog
+import com.android.internal.statusbar.IStatusBarService
+import com.android.wm.shell.Flags
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.WindowManagerShellWrapper
+import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
+import com.android.wm.shell.bubbles.properties.ProdBubbleProperties
+import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayInsetsController
+import com.android.wm.shell.common.FloatingContentCoordinator
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.common.TaskStackListenerImpl
+import com.android.wm.shell.draganddrop.DragAndDropController
+import com.android.wm.shell.shared.TransactionPool
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
+import com.android.wm.shell.shared.bubbles.BubbleBarUpdate
+import com.android.wm.shell.sysui.ShellCommandHandler
+import com.android.wm.shell.sysui.ShellController
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.taskview.TaskViewTransitions
+import com.android.wm.shell.transition.Transitions
+import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.MoreExecutors.directExecutor
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+import java.util.Optional
+
+/** Tests for [BubbleController] when using bubble bar */
+@SmallTest
+@EnableFlags(Flags.FLAG_ENABLE_BUBBLE_BAR)
+@RunWith(AndroidJUnit4::class)
+class BubbleControllerBubbleBarTest {
+
+    companion object {
+        private const val SCREEN_WIDTH = 2000
+        private const val SCREEN_HEIGHT = 1000
+    }
+
+    @get:Rule val setFlagsRule = SetFlagsRule()
+
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+
+    private lateinit var bubbleController: BubbleController
+    private lateinit var uiEventLoggerFake: UiEventLoggerFake
+    private lateinit var bubblePositioner: BubblePositioner
+    private lateinit var bubbleData: BubbleData
+    private lateinit var mainExecutor: TestExecutor
+    private lateinit var bgExecutor: TestExecutor
+
+    @Before
+    fun setUp() {
+        ProtoLog.REQUIRE_PROTOLOGTOOL = false
+        ProtoLog.init()
+
+        mainExecutor = TestExecutor()
+        bgExecutor = TestExecutor()
+
+        uiEventLoggerFake = UiEventLoggerFake()
+        val bubbleLogger = BubbleLogger(uiEventLoggerFake)
+
+        val deviceConfig =
+            DeviceConfig(
+                windowBounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
+                isLargeScreen = true,
+                isSmallTablet = false,
+                isLandscape = true,
+                isRtl = false,
+                insets = Insets.of(10, 20, 30, 40),
+            )
+
+        bubblePositioner = BubblePositioner(context, deviceConfig)
+        bubblePositioner.isShowingInBubbleBar = true
+
+        bubbleData =
+            BubbleData(
+                context,
+                bubbleLogger,
+                bubblePositioner,
+                BubbleEducationController(context),
+                mainExecutor,
+                bgExecutor,
+            )
+
+        val shellInit = ShellInit(mainExecutor)
+
+        bubbleController =
+            createBubbleController(
+                shellInit,
+                bubbleData,
+                bubbleLogger,
+                bubblePositioner,
+                mainExecutor,
+                bgExecutor,
+            )
+        bubbleController.asBubbles().setSysuiProxy(Mockito.mock(SysuiProxy::class.java))
+
+        shellInit.init()
+
+        mainExecutor.flushAll()
+        bgExecutor.flushAll()
+
+        bubbleController.registerBubbleStateListener(FakeBubblesStateListener())
+    }
+
+    @After
+    fun tearDown() {
+        mainExecutor.flushAll()
+        bgExecutor.flushAll()
+    }
+
+    @Test
+    fun testEventLogging_bubbleBar_dragBarLeft() {
+        addBubble()
+
+        bubblePositioner.bubbleBarLocation = BubbleBarLocation.RIGHT
+
+        bubbleController.setBubbleBarLocation(
+            BubbleBarLocation.LEFT,
+            BubbleBarLocation.UpdateSource.DRAG_BAR,
+        )
+
+        // 2 events: add bubble + drag event
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+        assertThat(uiEventLoggerFake.eventId(1))
+            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_BAR.id)
+    }
+
+    @Test
+    fun testEventLogging_bubbleBar_dragBarRight() {
+        addBubble()
+
+        bubblePositioner.bubbleBarLocation = BubbleBarLocation.LEFT
+
+        bubbleController.setBubbleBarLocation(
+            BubbleBarLocation.RIGHT,
+            BubbleBarLocation.UpdateSource.DRAG_BAR,
+        )
+
+        // 2 events: add bubble + drag event
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+        assertThat(uiEventLoggerFake.eventId(1))
+            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_BAR.id)
+    }
+
+    @Test
+    fun testEventLogging_bubbleBar_dragBubbleLeft() {
+        addBubble()
+
+        bubblePositioner.bubbleBarLocation = BubbleBarLocation.RIGHT
+
+        bubbleController.setBubbleBarLocation(
+            BubbleBarLocation.LEFT,
+            BubbleBarLocation.UpdateSource.DRAG_BUBBLE,
+        )
+
+        // 2 events: add bubble + drag event
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+        assertThat(uiEventLoggerFake.eventId(1))
+            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_BUBBLE.id)
+    }
+
+    @Test
+    fun testEventLogging_bubbleBar_dragBubbleRight() {
+        addBubble()
+
+        bubblePositioner.bubbleBarLocation = BubbleBarLocation.LEFT
+
+        bubbleController.setBubbleBarLocation(
+            BubbleBarLocation.RIGHT,
+            BubbleBarLocation.UpdateSource.DRAG_BUBBLE,
+        )
+
+        // 2 events: add bubble + drag event
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+        assertThat(uiEventLoggerFake.eventId(1))
+            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_BUBBLE.id)
+    }
+
+    private fun addBubble(): Bubble {
+        val bubble = FakeBubbleFactory.createChatBubble(context)
+        bubble.setInflateSynchronously(true)
+        bubbleData.notificationEntryUpdated(
+            bubble,
+            /* suppressFlyout= */ true,
+            /* showInShade= */ true,
+        )
+        return bubble
+    }
+
+    private fun createBubbleController(
+        shellInit: ShellInit,
+        bubbleData: BubbleData,
+        bubbleLogger: BubbleLogger,
+        bubblePositioner: BubblePositioner,
+        mainExecutor: TestExecutor,
+        bgExecutor: TestExecutor,
+    ): BubbleController {
+        val shellCommandHandler = ShellCommandHandler()
+        val shellController =
+            ShellController(
+                context,
+                shellInit,
+                shellCommandHandler,
+                mock<DisplayInsetsController>(),
+                mainExecutor,
+            )
+        val surfaceSynchronizer = { obj: Runnable -> obj.run() }
+
+        val bubbleDataRepository =
+            BubbleDataRepository(
+                mock<LauncherApps>(),
+                mainExecutor,
+                bgExecutor,
+                BubblePersistentRepository(context),
+            )
+
+        val shellTaskOrganizer = mock<ShellTaskOrganizer>()
+        whenever(shellTaskOrganizer.executor).thenReturn(directExecutor())
+
+        return BubbleController(
+            context,
+            shellInit,
+            shellCommandHandler,
+            shellController,
+            bubbleData,
+            surfaceSynchronizer,
+            FloatingContentCoordinator(),
+            bubbleDataRepository,
+            mock<IStatusBarService>(),
+            mock<WindowManager>(),
+            WindowManagerShellWrapper(mainExecutor),
+            mock<UserManager>(),
+            mock<LauncherApps>(),
+            bubbleLogger,
+            mock<TaskStackListenerImpl>(),
+            shellTaskOrganizer,
+            bubblePositioner,
+            mock<DisplayController>(),
+            /* oneHandedOptional= */ Optional.empty(),
+            mock<DragAndDropController>(),
+            mainExecutor,
+            mock<Handler>(),
+            bgExecutor,
+            mock<TaskViewTransitions>(),
+            mock<Transitions>(),
+            SyncTransactionQueue(TransactionPool(), mainExecutor),
+            mock<IWindowManager>(),
+            ProdBubbleProperties,
+        )
+    }
+
+    private class TestExecutor : ShellExecutor {
+
+        private val runnables: MutableList<Runnable> = mutableListOf()
+
+        override fun execute(runnable: Runnable) {
+            runnables.add(runnable)
+        }
+
+        override fun executeDelayed(runnable: Runnable, delayMillis: Long) {
+            execute(runnable)
+        }
+
+        override fun removeCallbacks(runnable: Runnable?) {}
+
+        override fun hasCallback(runnable: Runnable?): Boolean = false
+
+        fun flushAll() {
+            while (runnables.isNotEmpty()) {
+                runnables.removeAt(0).run()
+            }
+        }
+    }
+
+    private class FakeBubblesStateListener : Bubbles.BubbleStateListener {
+        override fun onBubbleStateChange(update: BubbleBarUpdate?) {}
+
+        override fun animateBubbleBarLocation(location: BubbleBarLocation?) {}
+    }
+}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt
index cb6fb62..3279d56 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt
@@ -32,10 +32,10 @@
             return BubbleViewInfo().apply { bubbleBarExpandedView = bubbleExpandedView }
         }
 
-        fun createChatBubbleWithViewInfo(
+        fun createChatBubble(
             context: Context,
             key: String = "key",
-            viewInfo: BubbleViewInfo,
+            viewInfo: BubbleViewInfo? = null,
         ): Bubble {
             val bubble =
                 Bubble(
@@ -50,7 +50,9 @@
                     directExecutor(),
                     directExecutor(),
                 ) {}
-            bubble.setViewInfo(viewInfo)
+            if (viewInfo != null) {
+                bubble.setViewInfo(viewInfo)
+            }
             return bubble
         }
     }
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
index 6ac36a3..1bf6af8 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.bubbles.bar
 
 import android.app.ActivityManager
+import android.content.ComponentName
 import android.content.Context
 import android.content.pm.ShortcutInfo
 import android.graphics.Insets
@@ -24,6 +25,7 @@
 import android.view.LayoutInflater
 import android.view.View
 import android.view.WindowManager
+import android.widget.FrameLayout
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -110,9 +112,9 @@
 
         regionSamplingProvider = TestRegionSamplingProvider()
 
-        bubbleExpandedView = (inflater.inflate(
+        bubbleExpandedView = inflater.inflate(
             R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */
-        ) as BubbleBarExpandedView)
+        ) as BubbleBarExpandedView
         bubbleExpandedView.initialize(
             expandedViewManager,
             positioner,
@@ -124,11 +126,11 @@
             regionSamplingProvider,
         )
 
-        getInstrumentation().runOnMainSync(Runnable {
+        getInstrumentation().runOnMainSync {
             bubbleExpandedView.onAttachedToWindow()
             // Helper should be created once attached to window
             testableRegionSamplingHelper = regionSamplingProvider!!.helper
-        })
+        }
 
         bubble = Bubble(
             "key",
@@ -254,6 +256,93 @@
         assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
     }
 
+    @Test
+    fun animateExpansion_waitsUntilTaskCreated() {
+        var animated = false
+        bubbleExpandedView.animateExpansionWhenTaskViewVisible { animated = true }
+        assertThat(animated).isFalse()
+        bubbleExpandedView.onTaskCreated()
+        assertThat(animated).isTrue()
+    }
+
+    @Test
+    fun animateExpansion_taskViewAttachedAndVisible() {
+        val inflater = LayoutInflater.from(context)
+        val expandedView = inflater.inflate(
+            R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */
+        ) as BubbleBarExpandedView
+        val taskView = FakeBubbleTaskViewFactory().create()
+        val taskViewParent = FrameLayout(context)
+        taskViewParent.addView(taskView.taskView)
+        taskView.listener.onTaskCreated(666, ComponentName(context, "BubbleBarExpandedViewTest"))
+        assertThat(taskView.isVisible).isTrue()
+
+        expandedView.initialize(
+            expandedViewManager,
+            positioner,
+            BubbleLogger(uiEventLoggerFake),
+            false /* isOverflow */,
+            taskView,
+            mainExecutor,
+            bgExecutor,
+            regionSamplingProvider,
+        )
+
+        // the task view should be removed from its parent
+        assertThat(taskView.taskView.parent).isNull()
+
+        var animated = false
+        expandedView.animateExpansionWhenTaskViewVisible { animated = true }
+        assertThat(animated).isFalse()
+
+        // send an invisible signal to simulate the surface getting destroyed
+        expandedView.onContentVisibilityChanged(false)
+
+        // send a visible signal to simulate a new surface getting created
+        expandedView.onContentVisibilityChanged(true)
+
+        assertThat(taskView.taskView.parent).isEqualTo(expandedView)
+        assertThat(animated).isTrue()
+    }
+
+    @Test
+    fun animateExpansion_taskViewAttachedAndInvisible() {
+        val inflater = LayoutInflater.from(context)
+        val expandedView = inflater.inflate(
+            R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */
+        ) as BubbleBarExpandedView
+        val taskView = FakeBubbleTaskViewFactory().create()
+        val taskViewParent = FrameLayout(context)
+        taskViewParent.addView(taskView.taskView)
+        taskView.listener.onTaskCreated(666, ComponentName(context, "BubbleBarExpandedViewTest"))
+        assertThat(taskView.isVisible).isTrue()
+        taskView.listener.onTaskVisibilityChanged(666, false)
+        assertThat(taskView.isVisible).isFalse()
+
+        expandedView.initialize(
+            expandedViewManager,
+            positioner,
+            BubbleLogger(uiEventLoggerFake),
+            false /* isOverflow */,
+            taskView,
+            mainExecutor,
+            bgExecutor,
+            regionSamplingProvider,
+        )
+
+        // the task view should be added to the expanded view
+        assertThat(taskView.taskView.parent).isEqualTo(expandedView)
+
+        var animated = false
+        expandedView.animateExpansionWhenTaskViewVisible { animated = true }
+        assertThat(animated).isFalse()
+
+        // send a visible signal to simulate a new surface getting created
+        expandedView.onContentVisibilityChanged(true)
+
+        assertThat(animated).isTrue()
+    }
+
     private fun BubbleBarExpandedView.menuView(): BubbleBarMenuView {
         return findViewByPredicate { it is BubbleBarMenuView }
     }
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
index 0044593..7280f8a 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
@@ -165,7 +165,7 @@
                 }
 
         val viewInfo = FakeBubbleFactory.createViewInfo(bubbleBarExpandedView)
-        bubble = FakeBubbleFactory.createChatBubbleWithViewInfo(context, viewInfo = viewInfo)
+        bubble = FakeBubbleFactory.createChatBubble(context, viewInfo = viewInfo)
     }
 
     @After
@@ -253,6 +253,7 @@
 
         getInstrumentation().runOnMainSync {
             bubbleBarLayerView.showExpandedView(bubble)
+            bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true)
         }
         waitForExpandedViewAnimation()
 
@@ -276,6 +277,7 @@
 
         getInstrumentation().runOnMainSync {
             bubbleBarLayerView.showExpandedView(bubble)
+            bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true)
         }
         waitForExpandedViewAnimation()
 
diff --git a/libs/WindowManager/Shell/res/layout/compat_ui_layout.xml b/libs/WindowManager/Shell/res/layout/compat_ui_layout.xml
index e7ead63..62782a7 100644
--- a/libs/WindowManager/Shell/res/layout/compat_ui_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/compat_ui_layout.xml
@@ -22,14 +22,14 @@
     android:gravity="bottom|end">
 
     <include android:id="@+id/size_compat_hint"
-        android:visibility="invisible"
+        android:visibility="gone"
         android:layout_width="@dimen/compat_hint_width"
         android:layout_height="wrap_content"
         layout="@layout/compat_mode_hint"/>
 
     <ImageButton
         android:id="@+id/size_compat_restart_button"
-        android:visibility="invisible"
+        android:visibility="gone"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/compat_button_margin"
diff --git a/libs/WindowManager/Shell/res/layout/user_aspect_ratio_settings_layout.xml b/libs/WindowManager/Shell/res/layout/user_aspect_ratio_settings_layout.xml
index b5f04c3..433d854 100644
--- a/libs/WindowManager/Shell/res/layout/user_aspect_ratio_settings_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/user_aspect_ratio_settings_layout.xml
@@ -22,14 +22,14 @@
     android:gravity="bottom|end">
 
     <include android:id="@+id/user_aspect_ratio_settings_hint"
-        android:visibility="invisible"
+        android:visibility="gone"
         android:layout_width="@dimen/compat_hint_width"
         android:layout_height="wrap_content"
         layout="@layout/compat_mode_hint"/>
 
     <ImageButton
         android:id="@+id/user_aspect_ratio_settings_button"
-        android:visibility="invisible"
+        android:visibility="gone"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/compat_button_margin"
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index a4aa348..9a1a3da 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Kies"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Skermskoot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Maak in blaaier oop"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Maak in app oop"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nuwe venster"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Bestuur vensters"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Verander aspekverhouding"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Maak kieslys oop"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimeer skerm"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gryp skerm vas"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App kan nie hierheen geskuif word nie"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Meesleurend"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Stel terug"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 1cd9804..9d22fef 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"ምረጥ"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"ቅጽበታዊ ገፅ ዕይታ"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"በአሳሽ ውስጥ ክፈት"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"መተግበሪያ ውስጥ ክፈት"</string>
     <string name="new_window_text" msgid="6318648868380652280">"አዲስ መስኮት"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"መስኮቶችን አስተዳድር"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ምጥጥነ ገፅታ ለውጥ"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ምናሌን ክፈት"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"የማያ ገጹ መጠን አሳድግ"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ማያ ገጹን አሳድግ"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"መተግበሪያ ወደዚህ መንቀሳቀስ አይችልም"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"አስማጭ"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ወደነበረበት መልስ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 41ebfcd..46ab090 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"اختيار"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"لقطة شاشة"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"فتح في المتصفِّح"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"فتح في التطبيق"</string>
     <string name="new_window_text" msgid="6318648868380652280">"نافذة جديدة"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"إدارة النوافذ"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغيير نسبة العرض إلى الارتفاع"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"إغلاق القائمة"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"فتح القائمة"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"تكبير الشاشة إلى أقصى حدّ"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"التقاط صورة للشاشة"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"لا يمكن نقل التطبيق إلى هنا"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"مجسَّم"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"استعادة"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 203fed0..1e35d6e 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"বাছনি কৰক"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"স্ক্ৰীনশ্বট"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ব্ৰাউজাৰত খোলক"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"এপত খোলক"</string>
     <string name="new_window_text" msgid="6318648868380652280">"নতুন ৱিণ্ড’"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"ৱিণ্ড’ পৰিচালনা কৰক"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"আকাৰৰ অনুপাত সলনি কৰক"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"মেনু খোলক"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্ৰীন মেক্সিমাইজ কৰক"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্ৰীন স্নেপ কৰক"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ইয়ালৈ এপ্‌টো আনিব নোৱাৰি"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ইমাৰ্ছিভ"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"পুনঃস্থাপন কৰক"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 31ddc9b..136d4c1 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Seçin"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Skrinşot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Brauzerdə açın"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Tətbiqdə açın"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Yeni pəncərə"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Pəncərələri idarə edin"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tərəflər nisbətini dəyişin"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menyunu açın"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı maksimum böyüdün"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranı çəkin"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"İmmersiv"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Bərpa edin"</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 486b3cf..10a33bb 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Izaberite"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Snimak ekrana"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Otvorite u pregledaču"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Otvorite u aplikaciji"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Upravljajte prozorima"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promenite razmeru"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvorite meni"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Povećaj ekran"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Uklopi ekran"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"Imerzivne"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vrati"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index cc42da9..163fbdd 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Выбраць"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Здымак экрана"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Адкрыць у браўзеры"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Адкрыць у праграме"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Новае акно"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Кіраваць вокнамі"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змяніць суадносіны бакоў"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Адкрыць меню"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Разгарнуць на ўвесь экран"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Размясціць на палавіне экрана"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Нельга перамясціць сюды праграму"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"З эфектам прысутнасці"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Аднавіць"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index c12b37b..d7da3ae 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Избиране"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Екранна снимка"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Отваряне в браузър"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Отваряне в приложение"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Нов прозорец"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Управление на прозорците"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промяна на съотношението"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отваряне на менюто"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Увеличаване на екрана"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Прилепване на екрана"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложението не може да бъде преместено тук"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалистично"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Възстановяване"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index aca5b34..9c2fc6e 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"বেছে নিন"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"স্ক্রিনশট"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ব্রাউজারে খুলুন"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"অ্যাপে খুলুন"</string>
     <string name="new_window_text" msgid="6318648868380652280">"নতুন উইন্ডো"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"উইন্ডো ম্যানেজ করুন"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"অ্যাস্পেক্ট রেশিও পরিবর্তন করুন"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"\'মেনু\' বন্ধ করুন"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"মেনু খুলুন"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্রিন বড় করুন"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্রিনে অ্যাপ মানানসই হিসেবে ছোট বড় করুন"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"অ্যাপটি এখানে সরানো যাবে না"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ইমারসিভ"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ফিরিয়ে আনুন"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 6bd6473..911285d 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Odabir"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Snimak ekrana"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Otvaranje u pregledniku"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Otvaranje u aplikaciji"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje prozorima"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promjena formata slike"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvaranje menija"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiziraj ekran"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snimi ekran"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ne možete premjestiti aplikaciju ovdje"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Uvjerljivo"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vraćanje"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index d9ad5a6..4249373 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Selecciona"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Obre al navegador"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Obre a l\'aplicació"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Finestra nova"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Gestiona les finestres"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Canvia la relació d\'aspecte"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Obre el menú"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximitza la pantalla"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajusta la pantalla"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"L\'aplicació no es pot moure aquí"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiu"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaura"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index ab51b66..a125343 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Vybrat"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Snímek obrazovky"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Otevřít v prohlížeči"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Otevřít v aplikaci"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nové okno"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Spravovat okna"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Změnit poměr stran"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otevřít nabídku"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovat obrazovku"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Rozpůlit obrazovku"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikaci sem nelze přesunout"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Pohlcující"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnovit"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 4436208..5b657f4 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Vælg"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Åbn i browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Åbn i app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nyt vindue"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Administrer vinduer"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Skift billedformat"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Åbn menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimér skærm"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tilpas skærm"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apps kan ikke flyttes hertil"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Opslugende"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Gendan"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index b6e89c0..6d360e8 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Auswählen"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Im Browser öffnen"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"In der App öffnen"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Neues Fenster"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Fenster verwalten"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Seitenverhältnis ändern"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menü öffnen"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Bildschirm maximieren"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Bildschirm teilen"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Die App kann nicht hierher verschoben werden"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiv"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Wiederherstellen"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 601c0ce..85a44f6 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Επιλογή"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Στιγμιότυπο οθόνης"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Άνοιγμα σε πρόγραμμα περιήγησης"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Άνοιγμα στην εφαρμογή"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Νέο παράθυρο"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Διαχείριση παραθύρων"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Αλλαγή λόγου διαστάσεων"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Άνοιγμα μενού"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Μεγιστοποίηση οθόνης"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Προβολή στο μισό της οθόνης"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Δεν είναι δυνατή η μετακίνηση της εφαρμογής εδώ"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Καθηλωτικό"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Επαναφορά"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index fd63175..3e30ff0 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Select"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Open in app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"New window"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index dac1b9a..0d7189b 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Select"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Open in App"</string>
     <string name="new_window_text" msgid="6318648868380652280">"New Window"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Manage Windows"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open Menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximize Screen"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap Screen"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index fd63175..3e30ff0 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Select"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Open in app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"New window"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index fd63175..3e30ff0 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Select"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Open in app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"New window"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index e67fc8e..6a1a2e5 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir en el navegador"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Abrir en la app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nueva ventana"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Administrar ventanas"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar relación de aspecto"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir el menú"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"No se puede mover la app aquí"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Inmersivo"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restablecer"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 2f5ec64..f93cf5a 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir en el navegador"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Abrir en la aplicación"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Ventana nueva"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Gestionar ventanas"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar relación de aspecto"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir menú"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"Inmersivo"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index dd78628..f0d1d4e 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Vali"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Ekraanipilt"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Avamine brauseris"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Ava rakenduses"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Uus aken"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Akende haldamine"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Kuvasuhte muutmine"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ava menüü"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Kuva täisekraanil"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Kuva poolel ekraanil"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Rakendust ei saa siia teisaldada"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Kaasahaarav"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Taasta"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 1cfc694..c6a7f2e 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Hautatu"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Pantaila-argazkia"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Ireki arakatzailean"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Ireki aplikazioan"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Leiho berria"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Kudeatu leihoak"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Aldatu aspektu-erlazioa"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Itxi menua"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ireki menua"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Handitu pantaila"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zatitu pantaila"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikazioa ezin da hona ekarri"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Murgiltzailea"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Leheneratu"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index f76f67d..d10a02d 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"انتخاب"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"نماگرفت"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"باز کردن در مرورگر"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"باز کردن در برنامه"</string>
     <string name="new_window_text" msgid="6318648868380652280">"پنجره جدید"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"مدیریت کردن پنجره‌ها"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغییر نسبت ابعادی"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"باز کردن منو"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"بزرگ کردن صفحه"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"بزرگ کردن صفحه"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"برنامه را نمی‌توان به اینجا منتقل کرد"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"فراگیر"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"بازیابی"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index a1ec015..0655f9a 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Valitse"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Kuvakaappaus"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Avaa selaimessa"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Avaa sovelluksessa"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Uusi ikkuna"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Hallinnoi ikkunoita"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Vaihda kuvasuhdetta"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Avaa valikko"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Suurenna näyttö"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Jaa näyttö"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Sovellusta ei voi siirtää tänne"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiivinen"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Palauta"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 1b9b74a..b9bdbd7 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Sélectionner"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Capture d\'écran"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Ouvrir dans le navigateur"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Ouvrir dans l\'appli"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nouvelle fenêtre"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Gérer les fenêtres"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier les proportions"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ouvrir le menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Agrandir l\'écran"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aligner l\'écran"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersif"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurer"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 7e0a0b1..a1eb028 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Sélectionner"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Capture d\'écran"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Ouvrir dans un navigateur"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Ouvrir dans l\'appli"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nouvelle fenêtre"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Gérer les fenêtres"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier le format"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ouvrir le menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mettre en plein écran"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fractionner l\'écran"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersif"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurer"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index bdd0747..22a7f7f 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Abrir na aplicación"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Ventá nova"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Xestionar as ventás"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar a proporción"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menú"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar pantalla"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"Envolvente"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index d23c4fd..06c21b4 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"પસંદ કરો"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"સ્ક્રીનશૉટ"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"બ્રાઉઝરમાં ખોલો"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"ઍપમાં ખોલો"</string>
     <string name="new_window_text" msgid="6318648868380652280">"નવી વિન્ડો"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"વિન્ડો મેનેજ કરો"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"સાપેક્ષ ગુણોત્તર બદલો"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"મેનૂ ખોલો"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"સ્ક્રીન કરો મોટી કરો"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"સ્ક્રીન સ્નૅપ કરો"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ઍપ અહીં ખસેડી શકાતી નથી"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ઇમર્સિવ"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"રિસ્ટોર કરો"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 4eec6f8..0eab10c 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"चुनें"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"स्क्रीनशॉट"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउज़र में खोलें"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"ऐप्लिकेशन में खोलें"</string>
     <string name="new_window_text" msgid="6318648868380652280">"नई विंडो"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"विंडो मैनेज करें"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेन्यू खोलें"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन को बड़ा करें"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्नैप स्क्रीन"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ऐप्लिकेशन को यहां मूव नहीं किया जा सकता"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिव"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"वापस लाएं"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index a119d9e..bf756f63 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Odaberite"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Snimka zaslona"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Otvori u pregledniku"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Otvori u aplikaciji"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje prozorima"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promijeni omjer slike"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvaranje izbornika"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimalno povećaj zaslon"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Izradi snimku zaslona"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija se ne može premjestiti ovdje"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Interaktivno"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vrati"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index c07b6c3..b02be18 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Kiválasztás"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Képernyőkép"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Megnyitás böngészőben"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Megnyitás alkalmazásban"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Új ablak"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Ablakok kezelése"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Méretarány módosítása"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menü megnyitása"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Képernyő méretének maximalizálása"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Igazodás a képernyő adott részéhez"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Az alkalmazás nem helyezhető át ide"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Magával ragadó"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Visszaállítás"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 52eb185..59a95f0 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Ընտրել"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Սքրինշոթ"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Բացել դիտարկիչում"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Բացել հավելվածում"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Նոր պատուհան"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Կառավարել պատուհանները"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Փոխել կողմերի հարաբերակցությունը"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Բացել ընտրացանկը"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ծավալել էկրանը"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ծալել էկրանը"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Հավելվածը հնարավոր չէ տեղափոխել այստեղ"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Ներկայության էֆեկտով"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Վերականգնել"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index f8f9d5e..baa1d0e 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Pilih"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Buka di browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Buka di Aplikasi"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Jendela Baru"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Kelola Jendela"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ubah rasio aspek"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buka Menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Perbesar Layar"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gabungkan Layar"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikasi tidak dapat dipindahkan ke sini"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imersif"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Pulihkan"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 8a9e3c0..c3ad5d6 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Velja"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Skjámynd"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Opna í vafra"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Opna í forriti"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nýr gluggi"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Stjórna gluggum"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Breyta myndhlutfalli"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Opna valmynd"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Stækka skjá"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Smelluskjár"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"Umlykjandi"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Endurheimta"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 138adef..b75c041 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Seleziona"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Apri nel browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Apri nell\'app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nuova finestra"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Gestisci finestre"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambia proporzioni"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Apri il menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Massimizza schermo"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aggancia schermo"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossibile spostare l\'app qui"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersivo"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Ripristina"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 917738dc..5f37590 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"בחירה"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"צילום מסך"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"פתיחה בדפדפן"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"פתיחה באפליקציה"</string>
     <string name="new_window_text" msgid="6318648868380652280">"חלון חדש"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"ניהול החלונות"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"שינוי של יחס גובה-רוחב"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"סגירת התפריט"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"פתיחת התפריט"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"הגדלת המסך"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"כיווץ המסך"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"לא ניתן להעביר את האפליקציה לכאן"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"סוחף"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"שחזור"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 35c4821..2960a19 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"選択"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"スクリーンショット"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ブラウザで開く"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"アプリで開く"</string>
     <string name="new_window_text" msgid="6318648868380652280">"新しいウィンドウ"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"ウィンドウを管理する"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"アスペクト比を変更"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"メニューを開く"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"画面の最大化"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"画面のスナップ"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"アプリはここに移動できません"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"没入モード"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"復元"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 9b9966f..6420bf5 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"არჩევა"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"ეკრანის ანაბეჭდი"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ბრაუზერში გახსნა"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"აპში გახსნა"</string>
     <string name="new_window_text" msgid="6318648868380652280">"ახალი ფანჯარა"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"ფანჯრების მართვა"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"თანაფარდობის შეცვლა"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"მენიუს გახსნა"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"აპლიკაციის გაშლა სრულ ეკრანზე"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"აპლიკაციის დაპატარავება ეკრანზე"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"აპის აქ გადატანა შეუძლებელია"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"იმერსიული"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"აღდგენა"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 8618ba9..ef16953 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Таңдау"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Браузерден ашу"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Қолданбада ашу"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Жаңа терезе"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Терезелерді басқару"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Арақатынасты өзгерту"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Мәзірді ашу"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды ұлғайту"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды бөлу"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Қолданба бұл жерге қойылмайды."</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Әсерлі"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Қалпына келтіру"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 7f853f3..a625201 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"ជ្រើសរើស"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"រូបថតអេក្រង់"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"បើកក្នុងកម្មវិធីរុករកតាមអ៊ីនធឺណិត"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"បើក​នៅ​ក្នុង​កម្មវិធី"</string>
     <string name="new_window_text" msgid="6318648868380652280">"វិនដូ​ថ្មី"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"គ្រប់គ្រង​វិនដូ"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ប្ដូរ​​សមាមាត្រ"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"បិទ​ម៉ឺនុយ"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"បើកម៉ឺនុយ"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ពង្រីកអេក្រង់"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ថតអេក្រង់"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"មិនអាចផ្លាស់ទីកម្មវិធីមកទីនេះបានទេ"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ជក់ចិត្ត"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ស្ដារ"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 456dea2..b2bf3a5 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ಬ್ರೌಸರ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"ಆ್ಯಪ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ"</string>
     <string name="new_window_text" msgid="6318648868380652280">"ಹೊಸ ವಿಂಡೋ"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"ವಿಂಡೋಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ಮೆನು ತೆರೆಯಿರಿ"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ಸ್ನ್ಯಾಪ್ ಸ್ಕ್ರೀನ್"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ಆ್ಯಪ್ ಅನ್ನು ಇಲ್ಲಿಗೆ ಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ಇಮ್ಮರ್ಸಿವ್"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ಮರುಸ್ಥಾಪಿಸಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 763cda7..ad0368a 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"선택"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"스크린샷"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"브라우저에서 열기"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"앱에서 열기"</string>
     <string name="new_window_text" msgid="6318648868380652280">"새 창"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"창 관리"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"가로세로 비율 변경"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"메뉴 열기"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"화면 최대화"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"화면 분할"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"앱을 여기로 이동할 수 없음"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"몰입형"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"복원"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index bffc3b1..0b4eb93 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Тандоо"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Серепчиден ачуу"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Колдонмодо ачуу"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Жаңы терезе"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Терезелерди тескөө"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Тараптардын катнашын өзгөртүү"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Менюну ачуу"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды чоңойтуу"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды сүрөткө тартып алуу"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Колдонмону бул жерге жылдырууга болбойт"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Сүңгүтүүчү"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Калыбына келтирүү"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index b48b070..9710e69 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"ເລືອກ"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"ຮູບໜ້າຈໍ"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ເປີດໃນໂປຣແກຣມທ່ອງເວັບ"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"ເປີດຢູ່ໃນແອັບ"</string>
     <string name="new_window_text" msgid="6318648868380652280">"ໜ້າຈໍໃໝ່"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"ຈັດການໜ້າຈໍ"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ປ່ຽນອັດຕາສ່ວນຮູບ"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ເປີດເມນູ"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ປັບຈໍໃຫຍ່ສຸດ"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ສະແນັບໜ້າຈໍ"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ບໍ່ສາມາດຍ້າຍແອັບມາບ່ອນນີ້ໄດ້"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ສົມຈິງ"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ກູ້ຄືນ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index d7a907c..5bfb8e3 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Pasirinkti"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Ekrano kopija"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Atidaryti naršyklėje"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Atidaryti programoje"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Naujas langas"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Tvarkyti langus"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Keisti kraštinių santykį"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Atidaryti meniu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Išskleisti ekraną"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Sutraukti ekraną"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Programos negalima perkelti čia"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Įtraukiantis"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Atkurti"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 4ba7c23..0734200 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Atlasīt"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Ekrānuzņēmums"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Atvērt pārlūkā"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Atvērt lietotnē"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Jauns logs"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Pārvaldīt logus"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mainīt malu attiecību"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Atvērt izvēlni"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizēt ekrānu"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fiksēt ekrānu"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Lietotni nevar pārvietot šeit."</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Iekļaujoši"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Atjaunot"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index d20eba5..2c4503c 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Изберете"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Слика од екранот"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Отвори во прелистувач"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Отвори во апликацијата"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Нов прозорец"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Управувајте со прозорци"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени го соодносот"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отвори го менито"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Максимизирај го екранот"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Подели го екранот на половина"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликацијата не може да се премести овде"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалистично"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Врати"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 81c5094..7e20ee1 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"തിരഞ്ഞെടുക്കുക"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"സ്ക്രീൻഷോട്ട്"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ബ്രൗസറിൽ തുറക്കുക"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"ആപ്പിൽ തുറക്കുക"</string>
     <string name="new_window_text" msgid="6318648868380652280">"പുതിയ വിന്‍ഡോ"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"വിൻഡോകൾ മാനേജ് ചെയ്യുക"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"വീക്ഷണ അനുപാതം മാറ്റുക"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"മെനു തുറക്കുക"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"സ്‌ക്രീൻ വലുതാക്കുക"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"സ്‌ക്രീൻ സ്‌നാപ്പ് ചെയ്യുക"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ആപ്പ് ഇവിടേക്ക് നീക്കാനാകില്ല"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ഇമേഴ്‌സീവ്"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"പുനഃസ്ഥാപിക്കുക"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 35da93e..ef24222c 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Сонгох"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Дэлгэцийн агшин"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Хөтчид нээх"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Аппад нээх"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Шинэ цонх"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Windows-г удирдах"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Харьцааг өөрчлөх"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Цэсийг нээх"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Дэлгэцийг томруулах"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Дэлгэцийг таллах"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Аппыг ийш зөөх боломжгүй"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Бодит мэт"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Сэргээх"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index c6b874a..e665639 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"निवडा"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"स्क्रीनशॉट"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउझरमध्ये उघडा"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"अ‍ॅपमध्ये उघडा"</string>
     <string name="new_window_text" msgid="6318648868380652280">"नवीन विंडो"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"विंडो व्यवस्थापित करा"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"आस्पेक्ट रेशो बदला"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेनू उघडा"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन मोठी करा"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रीन स्नॅप करा"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"अ‍ॅप इथे हलवू शकत नाही"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिव्ह"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"रिस्टोअर करा"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 0fce0e9..5de79c2 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Pilih"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Tangkapan skrin"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Buka dalam penyemak imbas"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Buka pada Apl"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Tetingkap Baharu"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Urus Tetingkap"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tukar nisbah bidang"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buka Menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimumkan Skrin"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tangkap Skrin"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apl tidak boleh dialihkan ke sini"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Mengasyikkan"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Pulihkan"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index abc2a19..e6d3553 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"ရွေးရန်"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ဘရောင်ဇာတွင် ဖွင့်ရန်"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"အက်ပ်တွင် ဖွင့်ရန်"</string>
     <string name="new_window_text" msgid="6318648868380652280">"ဝင်းဒိုးအသစ်"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"ဝင်းဒိုးများ စီမံရန်"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"အချိုးအစား ပြောင်းရန်"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"မီနူး ဖွင့်ရန်"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"စခရင်ကို ချဲ့မည်"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"စခရင်ကို ချုံ့မည်"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"အက်ပ်ကို ဤနေရာသို့ ရွှေ့၍မရပါ"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"သုံးဘက်မြင်"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ပြန်ပြောင်းရန်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index ed6fb90..bde7ec6 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Velg"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Skjermbilde"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Åpne i nettleseren"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Åpne i appen"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nytt vindu"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Administrer vinduene"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Endre høyde/bredde-forholdet"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Åpne menyen"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimer skjermen"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fest skjermen"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Appen kan ikke flyttes hit"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Oppslukende"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Gjenopprett"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index aff7129..a40e3ad 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"चयन गर्नुहोस्"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"स्क्रिनसट"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउजरमा खोल्नुहोस्"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"एपमा खोल्नुहोस्"</string>
     <string name="new_window_text" msgid="6318648868380652280">"नयाँ विन्डो"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"विन्डोहरू व्यवस्थापन गर्नुहोस्"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेनु खोल्नुहोस्"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रिन ठुलो बनाउनुहोस्"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रिन स्न्याप गर्नुहोस्"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"एप सारेर यहाँ ल्याउन सकिएन"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिभ"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"रिस्टोर गर्नुहोस्"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 8db3a0e..b28b690 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Selecteren"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Openen in browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Openen in app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nieuw venster"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Vensters beheren"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Beeldverhouding wijzigen"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menu openen"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Scherm maximaliseren"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Scherm halveren"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Kan de app niet hierheen verplaatsen"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersief"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Herstellen"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 6954089..842e3de 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"ଚୟନ କରନ୍ତୁ"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"ସ୍କ୍ରିନସଟ"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ବ୍ରାଉଜରରେ ଖୋଲନ୍ତୁ"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"ଆପରେ ଖୋଲନ୍ତୁ"</string>
     <string name="new_window_text" msgid="6318648868380652280">"ନୂଆ ୱିଣ୍ଡୋ"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ଚଉଡ଼ା ଓ ଉଚ୍ଚତାର ଅନୁପାତ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"ମେନୁ ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ମେନୁ ଖୋଲନ୍ତୁ"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ସ୍କ୍ରିନକୁ ବଡ଼ କରନ୍ତୁ"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ସ୍କ୍ରିନକୁ ସ୍ନାପ କରନ୍ତୁ"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ଆପକୁ ଏଠାକୁ ମୁଭ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ଇମର୍ସିଭ"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index c627d7f..e1c804a 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"ਚੁਣੋ"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"ਬ੍ਰਾਊਜ਼ਰ ਵਿੱਚ ਖੋਲ੍ਹੋ"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"ਐਪ ਵਿੱਚ ਖੋਲ੍ਹੋ"</string>
     <string name="new_window_text" msgid="6318648868380652280">"ਨਵੀਂ ਵਿੰਡੋ"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"ਵਿੰਡੋਆਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ਆਕਾਰ ਅਨੁਪਾਤ ਬਦਲੋ"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ਮੀਨੂ ਖੋਲ੍ਹੋ"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ਸਕ੍ਰੀਨ ਦਾ ਆਕਾਰ ਵਧਾਓ"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ਸਕ੍ਰੀਨ ਨੂੰ ਸਨੈਪ ਕਰੋ"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ਐਪ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਲਿਜਾਇਆ ਜਾ ਸਕਦਾ"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ਇਮਰਸਿਵ"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index a138c08..e82916b 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Wybierz"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Zrzut ekranu"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Otwórz w przeglądarce"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Otwórz w aplikacji"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nowe okno"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Zarządzaj oknami"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmień format obrazu"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zamknij menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otwórz menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksymalizuj ekran"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Przyciągnij ekran"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Nie można przenieść aplikacji tutaj"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Tryb immersyjny"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Przywróć"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 9942f69..6d8c9ce 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Captura de tela"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Abrir no app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Gerenciar janelas"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mudar a proporção"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"Imersivo"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 559eea2..e0e91e7 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Captura de ecrã"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Abrir na app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Faça a gestão das janelas"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Alterar formato"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar ecrã"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar ecrã"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"Envolvente"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 9942f69..6d8c9ce 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Captura de tela"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Abrir no app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Gerenciar janelas"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mudar a proporção"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"Imersivo"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index df0ee45..5a38155 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Selectează"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Captură de ecran"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Deschide în browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Deschide în aplicație"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Fereastră nouă"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Gestionează ferestrele"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Schimbă raportul de dimensiuni"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Deschide meniul"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizează fereastra"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Micșorează fereastra și fixeaz-o"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplicația nu poate fi mutată aici"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Captivant"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restabilește"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 430f1b1..d26eb53 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Выбрать"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Открыть в браузере"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Открыть в приложении"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Новое окно"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Управление окнами"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Изменить соотношение сторон"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Открыть меню"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Развернуть на весь экран"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Свернуть"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложение нельзя сюда переместить"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Погружение"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Восстановить"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 3e37667..5bfa4c9 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"තෝරන්න"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"තිර රුව"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"බ්‍රව්සරයේ විවෘත කරන්න"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"යෙදුම තුළ විවෘත කරන්න"</string>
     <string name="new_window_text" msgid="6318648868380652280">"නව කවුළුව"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"කවුළු කළමනාකරණය කරන්න"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"දර්ශන අනුපාතය වෙනස් කරන්න"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"මෙනුව විවෘත කරන්න"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"තිරය උපරිම කරන්න"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ස්නැප් තිරය"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"යෙදුම මෙතැනට ගෙන යා නොහැක"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ගිලෙන සුළු"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ප්‍රතිසාධනය කරන්න"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 56a7edd..cd20df5 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Vybrať"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Snímka obrazovky"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Otvoriť v prehliadači"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Otvoriť v aplikácii"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nové okno"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Správa okien"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmeniť pomer strán"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvoriť ponuku"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovať obrazovku"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zobraziť polovicu obrazovky"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikácia sa sem nedá presunúť"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Pútavé"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnoviť"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index b6344c9..063e47c 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Izberi"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Posnetek zaslona"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Odpri v brskalniku"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Odpiranje v aplikaciji"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Novo okno"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje oken"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Sprememba razmerja stranic"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Odpri meni"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiraj zaslon"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Pripni zaslon"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacije ni mogoče premakniti sem"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Poglobljeno"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnovi"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index ab7499d..f2fb7da 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Zgjidh"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Pamja e ekranit"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Hape në shfletues"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Hap në aplikacion"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Dritare e re"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Menaxho dritaret"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ndrysho raportin e pamjes"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Hap menynë"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizo ekranin"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Regjistro ekranin"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacioni nuk mund të zhvendoset këtu"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Përfshirës"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restauro"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 773ed16..f74e460 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Изаберите"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Снимак екрана"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Отворите у прегледачу"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Отворите у апликацији"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Нови прозор"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Управљајте прозорима"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промените размеру"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отворите мени"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Повећај екран"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Уклопи екран"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликација не може да се премести овде"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Имерзивне"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Врати"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 6f6a97b..7a5549e 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Välj"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Skärmbild"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Öppna i webbläsaren"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Öppna i appen"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Nytt fönster"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Hantera fönster"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ändra bildformat"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Öppna menyn"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximera skärmen"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fäst skärmen"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"Uppslukande"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Återställ"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 72b7384..128ba74 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Chagua"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Picha ya skrini"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Fungua katika kivinjari"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Fungua kwenye Programu"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Dirisha Jipya"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Dhibiti Windows"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Badilisha uwiano"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Fungua Menyu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Panua Dirisha kwenye Skrini"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Panga Madirisha kwenye Skrini"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Imeshindwa kuhamishia programu hapa"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Shirikishi"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Rejesha"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 9d90291..668efd5 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"தேர்ந்தெடுக்கும்"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"ஸ்கிரீன்ஷாட்"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"உலாவியில் திறக்கும்"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"ஆப்ஸில் திறக்கும்"</string>
     <string name="new_window_text" msgid="6318648868380652280">"புதிய சாளரம்"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"சாளரங்களை நிர்வகிக்கலாம்"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"தோற்ற விகிதத்தை மாற்று"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"மெனுவைத் திறக்கும்"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"திரையைப் பெரிதாக்கு"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"திரையை ஸ்னாப் செய்"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ஆப்ஸை இங்கே நகர்த்த முடியாது"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ஈடுபட வைக்கும்"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"மீட்டெடுக்கும்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 3c7c06a..a3827bb 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -102,7 +102,7 @@
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"యాప్ మెనూ నుండి ఏ సమయంలోనైనా ఫుల్ స్క్రీన్‌కు తిరిగి రండి"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"చూసి, మరిన్ని చేయండి"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"స్ప్లిట్ స్క్రీన్ కోసం మరొక యాప్‌లోకి లాగండి"</string>
-    <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"యాప్ స్థానాన్ని మార్చడానికి దాని వెలుపల డబుల్-ట్యాప్ చేయండి"</string>
+    <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"యాప్ లొకేషన్‌ను మార్చడానికి దాని వెలుపల డబుల్-ట్యాప్ చేయండి"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"అర్థమైంది"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"మరింత సమాచారం కోసం విస్తరించండి."</string>
     <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"మెరుగైన వీక్షణ కోసం రీస్టార్ట్ చేయాలా?"</string>
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"ఎంచుకోండి"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"స్క్రీన్‌షాట్"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"బ్రౌజర్‌లో తెరవండి"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"యాప్‌లో తెరవండి"</string>
     <string name="new_window_text" msgid="6318648868380652280">"కొత్త విండో"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"విండోలను మేనేజ్ చేయండి"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ఆకార నిష్పత్తిని మార్చండి"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"మెనూను తెరవండి"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"స్క్రీన్ సైజ్‌ను పెంచండి"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"స్క్రీన్‌ను స్నాప్ చేయండి"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"యాప్‌ను ఇక్కడకి తరలించడం సాధ్యం కాదు"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"లీనమయ్యే"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"రీస్టోర్ చేయండి"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 9071bfb..fe75561 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"เลือก"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"ภาพหน้าจอ"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"เปิดในเบราว์เซอร์"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"เปิดในแอป"</string>
     <string name="new_window_text" msgid="6318648868380652280">"หน้าต่างใหม่"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"จัดการหน้าต่าง"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"เปลี่ยนสัดส่วนการแสดงผล"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"ปิดเมนู"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"เปิดเมนู"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ขยายหน้าจอให้ใหญ่สุด"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"สแนปหน้าจอ"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ย้ายแอปมาที่นี่ไม่ได้"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"สมจริง"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"คืนค่า"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index a00f783..d9fb13b 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Piliin"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Buksan sa browser"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Buksan sa App"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Bagong Window"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Pamahalaan ang Mga Window"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Baguhin ang aspect ratio"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buksan ang Menu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"I-maximize ang Screen"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"I-snap ang Screen"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Hindi mailipat dito ang app"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"I-restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 8310a66..e6d900a 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Seç"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Ekran görüntüsü"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Tarayıcıda aç"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Uygulamada Aç"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Yeni Pencere"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Pencereleri yönet"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"En boy oranını değiştir"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menüyü aç"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı Büyüt"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranın Yarısına Tuttur"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Uygulama buraya taşınamıyor"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Etkileyici"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Geri yükle"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 624a19e..ea59995 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Вибрати"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Знімок екрана"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Відкрити у вебпереглядачі"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Відкрити в додатку"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Нове вікно"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Керувати вікнами"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змінити формат"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Закрити меню"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Відкрити меню"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Розгорнути екран"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Зафіксувати екран"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Сюди не можна перемістити додаток"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалістичність"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Відновити"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 2ccaf50..6749629f 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"منتخب کریں"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"اسکرین شاٹ"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"براؤزر میں کھولیں"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"ایپ میں کھولیں"</string>
     <string name="new_window_text" msgid="6318648868380652280">"نئی ونڈو"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"‏‫Windows کا نظم کریں"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"تناسبی شرح کو تبدیل کریں"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"مینیو بند کریں"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"مینو کھولیں"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"اسکرین کو بڑا کریں"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"اسکرین کا اسناپ شاٹ لیں"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ایپ کو یہاں منتقل نہیں کیا جا سکتا"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"عمیق"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"بحال کریں"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 88edc92..3417fef 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Tanlash"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Skrinshot"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Brauzerda ochish"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Ilovada ochish"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Yangi oyna"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Oynalarni boshqarish"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tomonlar nisbatini oʻzgartirish"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menyuni ochish"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranni yoyish"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranni biriktirish"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ilova bu yerga surilmaydi"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiv"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Tiklash"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index c1c7653..559bff8 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Chọn"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Ảnh chụp màn hình"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Mở trong trình duyệt"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Mở trong Ứng dụng"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Cửa sổ mới"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Quản lý cửa sổ"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Thay đổi tỷ lệ khung hình"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Mở Trình đơn"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mở rộng màn hình"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Điều chỉnh kích thước màn hình"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <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_immersive_button_text" msgid="559492223133829481">"Hiển thị tối đa"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Khôi phục"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 83e15d8..f327653 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"选择"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"屏幕截图"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"在浏览器中打开"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"在应用内打开"</string>
     <string name="new_window_text" msgid="6318648868380652280">"新窗口"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"管理窗口"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"更改宽高比"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"关闭菜单"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"打开菜单"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"最大化屏幕"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"屏幕快照"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"无法将应用移至此处"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"沉浸式"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"恢复"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index f60b3ef..e1ecd44 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"選取"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"螢幕截圖"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"在瀏覽器中開啟"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"在應用程式中開啟"</string>
     <string name="new_window_text" msgid="6318648868380652280">"新視窗"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"管理視窗"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更長寬比"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"打開選單"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至這裡"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"身歷其境"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"還原"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index b2227de..1b8f704 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"選取"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"螢幕截圖"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"在瀏覽器中開啟"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"在應用程式中開啟"</string>
     <string name="new_window_text" msgid="6318648868380652280">"新視窗"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"管理視窗"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更顯示比例"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"開啟選單"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至此處"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"沉浸"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"還原"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 10d904f..6040317 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -125,6 +125,7 @@
     <string name="select_text" msgid="5139083974039906583">"Khetha"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Isithombe-skrini"</string>
     <string name="open_in_browser_text" msgid="9181692926376072904">"Vula kubhrawuza"</string>
+    <string name="open_in_app_text" msgid="2874590745116268525">"Vula Ku-app"</string>
     <string name="new_window_text" msgid="6318648868380652280">"Iwindi Elisha"</string>
     <string name="manage_windows_text" msgid="5567366688493093920">"Phatha Amawindi"</string>
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Shintsha ukubukeka kwesilinganiselo"</string>
@@ -132,7 +133,8 @@
     <string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string>
     <string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Vula Imenyu"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Khulisa Isikrini Sifike Ekugcineni"</string>
-    <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Thwebula Isikrini"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+    <skip />
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"I-app ayikwazi ukuhanjiswa lapha"</string>
     <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Okugxilile"</string>
     <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Buyisela"</string>
diff --git a/libs/WindowManager/Shell/shared/Android.bp b/libs/WindowManager/Shell/shared/Android.bp
new file mode 100644
index 0000000..5113d98
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/Android.bp
@@ -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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+    default_team: "trendy_team_multitasking_windowing",
+}
+
+filegroup {
+    name: "wm_shell-shared-utils",
+    srcs: [
+        "src/com/android/wm/shell/shared/TransitionUtil.java",
+    ],
+}
+
+filegroup {
+    name: "wm_shell-shared-aidls",
+
+    srcs: [
+        "**/*.aidl",
+    ],
+
+    path: "src",
+}
+
+// NOTE: This shared lib is built with various apps and should not
+//       contain resources that can be overlaid, as they would need
+//       to be overlaid in each app individually.
+android_library {
+    name: "WindowManager-Shell-shared",
+
+    resource_dirs: [
+        "res",
+    ],
+    srcs: [
+        "**/*.java",
+        "**/*.kt",
+        ":wm_shell-shared-aidls",
+    ],
+    static_libs: [
+        "androidx.core_core-animation",
+        "androidx.dynamicanimation_dynamicanimation",
+        "jsr330",
+    ],
+    kotlincflags: ["-Xjvm-default=all"],
+    use_resource_processor: true,
+}
+
+// NOTE: This shared lib is built with various apps and should not
+//       contain resources that can be overlaid, as they would need
+//       to be overlaid in each app individually.
+java_library {
+    name: "WindowManager-Shell-shared-desktopMode",
+
+    srcs: [
+        "**/desktopmode/*.java",
+        "**/desktopmode/*.kt",
+    ],
+    static_libs: [
+        "com.android.window.flags.window-aconfig-java",
+    ],
+}
diff --git a/packages/BackupRestoreConfirmation/res/values/styles.xml b/libs/WindowManager/Shell/shared/AndroidManifest.xml
similarity index 61%
copy from packages/BackupRestoreConfirmation/res/values/styles.xml
copy to libs/WindowManager/Shell/shared/AndroidManifest.xml
index ce54568..5a4af51 100644
--- a/packages/BackupRestoreConfirmation/res/values/styles.xml
+++ b/libs/WindowManager/Shell/shared/AndroidManifest.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2024 The Android Open Source Project
+<!--
+     Copyright (C) 2024 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,12 +14,6 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <!--
-        TODO(b/309578419): Make activities handle insets properly and then remove this.
-    -->
-    <style name="OptOutEdgeToEdgeEnforcement">
-        <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
-    </style>
-</resources>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.wm.shell.shared">
+</manifest>
diff --git a/libs/WindowManager/Shell/shared/res/values/config.xml b/libs/WindowManager/Shell/shared/res/values/config.xml
new file mode 100644
index 0000000..a1d81ce
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/res/values/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<resources>
+</resources>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/shared/res/values/strings.xml b/libs/WindowManager/Shell/shared/res/values/strings.xml
new file mode 100644
index 0000000..d1804c0
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<resources>
+  <!-- Accessibility text for the icons generated by the Manage Windows submenu
+  in desktop mode and taskbar. [CHAR LIMIT=NONE] -->
+  <string name="manage_windows_icon_text">Open Window %1$d</string>
+</resources>
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/multiinstance/ManageWindowsViewContainer.kt
similarity index 95%
rename from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/ManageWindowsViewContainer.kt
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/multiinstance/ManageWindowsViewContainer.kt
index f14dfdb..0954b52 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/multiinstance/ManageWindowsViewContainer.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.shared.desktopmode
+package com.android.wm.shell.shared.multiinstance
 import android.animation.Animator
 import android.animation.AnimatorListenerAdapter
 import android.animation.AnimatorSet
@@ -34,6 +34,7 @@
 import android.view.ViewGroup.MarginLayoutParams
 import android.widget.LinearLayout
 import android.window.TaskSnapshot
+import com.android.wm.shell.shared.R
 
 /**
  * View for the All Windows menu option, used by both Desktop Windowing and Taskbar.
@@ -167,6 +168,9 @@
                 val appSnapshotButton = SurfaceView(context)
                 appSnapshotButton.cornerRadius = iconRadius
                 appSnapshotButton.setZOrderOnTop(true)
+                appSnapshotButton.contentDescription = context.resources.getString(
+                    R.string.manage_windows_icon_text, iconCount + 1
+                )
                 appSnapshotButton.setOnClickListener {
                     onIconClickListener?.invoke(taskId)
                 }
@@ -230,10 +234,12 @@
         /** Play the animation for opening the menu. */
         fun animateOpen() {
             animateView(rootView, MENU_BOUNDS_SHRUNK_SCALE, MENU_BOUNDS_FULL_SCALE,
-                MENU_START_ALPHA, MENU_FULL_ALPHA)
+                MENU_START_ALPHA, MENU_FULL_ALPHA
+            )
             for (view in iconViews) {
                 animateView(view, MENU_BOUNDS_SHRUNK_SCALE, MENU_BOUNDS_FULL_SCALE,
-                    MENU_START_ALPHA, MENU_FULL_ALPHA)
+                    MENU_START_ALPHA, MENU_FULL_ALPHA
+                )
             }
             createAnimatorSet().start()
         }
@@ -241,10 +247,12 @@
         /** Play the animation for closing the menu. */
         fun animateClose(callback: () -> Unit) {
             animateView(rootView, MENU_BOUNDS_FULL_SCALE, MENU_BOUNDS_SHRUNK_SCALE,
-                MENU_FULL_ALPHA, MENU_START_ALPHA)
+                MENU_FULL_ALPHA, MENU_START_ALPHA
+            )
             for (view in iconViews) {
                 animateView(view, MENU_BOUNDS_FULL_SCALE, MENU_BOUNDS_SHRUNK_SCALE,
-                    MENU_FULL_ALPHA, MENU_START_ALPHA)
+                    MENU_FULL_ALPHA, MENU_START_ALPHA
+                )
             }
             createAnimatorSet().apply {
                 addListener(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index ce7a977..e9cfd9b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -37,6 +37,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
+import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.IActivityTaskManager;
 import android.app.TaskInfo;
@@ -73,10 +74,12 @@
 import android.window.BackNavigationInfo;
 import android.window.BackTouchTracker;
 import android.window.IBackAnimationFinishedCallback;
+import android.window.IBackAnimationHandoffHandler;
 import android.window.IBackAnimationRunner;
 import android.window.IOnBackInvokedCallback;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
+import android.window.WindowAnimationState;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
@@ -84,6 +87,8 @@
 import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.view.AppearanceRegion;
+import com.android.systemui.animation.TransitionAnimator;
+import com.android.window.flags.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.ExternalInterfaceBinder;
 import com.android.wm.shell.common.RemoteCallable;
@@ -227,6 +232,15 @@
     private Runnable mPilferPointerCallback;
     private BackAnimation.TopUiRequest mRequestTopUiCallback;
 
+    private final IBackAnimationHandoffHandler mHandoffHandler =
+            new IBackAnimationHandoffHandler.Stub() {
+                @Override
+                public void handOffAnimation(
+                        RemoteAnimationTarget[] targets, WindowAnimationState[] states) {
+                    mBackTransitionHandler.handOffAnimation(targets, states);
+                }
+            };
+
     public BackAnimationController(
             @NonNull ShellInit shellInit,
             @NonNull ShellController shellController,
@@ -282,7 +296,7 @@
         mShellCommandHandler = shellCommandHandler;
         mWindowManager = context.getSystemService(WindowManager.class);
         mTransitions = transitions;
-        mBackTransitionHandler = new BackTransitionHandler();
+        mBackTransitionHandler = new BackTransitionHandler(mTransitions);
         mTransitions.addHandler(mBackTransitionHandler);
         mHandler = handler;
         mTransitions.registerObserver(mBackTransitionObserver);
@@ -715,6 +729,9 @@
         }
         try {
             callback.onBackStarted(backEvent);
+            if (mBackTransitionHandler.canHandOffAnimation()) {
+                callback.setHandoffHandler(mHandoffHandler);
+            }
             mOnBackStartDispatched = true;
         } catch (RemoteException e) {
             Log.e(TAG, "dispatchOnBackStarted error: ", e);
@@ -1192,6 +1209,7 @@
     }
 
     class BackTransitionHandler implements Transitions.TransitionHandler {
+        private final Transitions mTransitions;
 
         Runnable mOnAnimationFinishCallback;
         boolean mCloseTransitionRequested;
@@ -1203,6 +1221,12 @@
         // animation is canceled, start a close prepare transition to finish the whole transition.
         IBinder mClosePrepareTransition;
         TransitionInfo mOpenTransitionInfo;
+        Transitions.TransitionHandler mTakeoverHandler;
+
+        BackTransitionHandler(Transitions transitions) {
+            mTransitions = transitions;
+        }
+
         void onAnimationFinished() {
             if (!mCloseTransitionRequested && mPrepareOpenTransition != null) {
                 createClosePrepareTransition();
@@ -1214,18 +1238,23 @@
         }
 
         private void applyFinishOpenTransition() {
-            mOpenTransitionInfo = null;
-            mPrepareOpenTransition = null;
             if (mFinishOpenTransaction != null) {
                 final SurfaceControl.Transaction t = mFinishOpenTransaction;
-                mFinishOpenTransaction = null;
                 t.apply();
             }
             if (mFinishOpenTransitionCallback != null) {
                 final Transitions.TransitionFinishCallback callback = mFinishOpenTransitionCallback;
-                mFinishOpenTransitionCallback = null;
                 callback.onTransitionFinished(null);
             }
+            cleanUpInternalState();
+        }
+
+        private void cleanUpInternalState() {
+            mOpenTransitionInfo = null;
+            mPrepareOpenTransition = null;
+            mFinishOpenTransaction = null;
+            mFinishOpenTransitionCallback = null;
+            mTakeoverHandler = null;
         }
 
         private void applyAndFinish(@NonNull SurfaceControl.Transaction st,
@@ -1237,6 +1266,7 @@
             finishCallback.onTransitionFinished(null);
             mCloseTransitionRequested = false;
         }
+
         @Override
         public boolean startAnimation(@NonNull IBinder transition,
                 @NonNull TransitionInfo info,
@@ -1246,6 +1276,9 @@
             final boolean isPrepareTransition =
                     info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION;
             if (isPrepareTransition) {
+                if (checkTakeoverFlags()) {
+                    mTakeoverHandler = mTransitions.getHandlerForTakeover(transition, info);
+                }
                 kickStartAnimation();
             }
             // Both mShellExecutor and Transitions#mMainExecutor are ShellMainThread, so we don't
@@ -1288,6 +1321,57 @@
             return handleCloseTransition(info, st, ft, finishCallback);
         }
 
+        private boolean canHandOffAnimation() {
+            if (!checkTakeoverFlags()) {
+                return false;
+            }
+
+            return mTakeoverHandler != null;
+        }
+
+        private void handOffAnimation(
+                RemoteAnimationTarget[] targets, WindowAnimationState[] states) {
+            if (!checkTakeoverFlags()) {
+                ProtoLog.e(WM_SHELL_BACK_PREVIEW,
+                        "Trying to hand off the animation, but the required flags are disabled.");
+                return;
+            } else if (mTakeoverHandler == null) {
+                ProtoLog.e(WM_SHELL_BACK_PREVIEW,
+                        "Missing takeover handler when trying to hand off animation.");
+                return;
+            } else if (targets.length != states.length) {
+                ProtoLog.e(WM_SHELL_BACK_PREVIEW,
+                        "Targets passed for takeover don't match the window states.");
+                return;
+            }
+
+            // The states passed to this method are paired with the targets, but they need to be
+            // paired with the changes inside the TransitionInfo. So for each change we find its
+            // matching target, and leave the state for any change missing a matching target blank.
+            WindowAnimationState[] updatedStates =
+                    new WindowAnimationState[mOpenTransitionInfo.getChanges().size()];
+            for (int i = 0; i < mOpenTransitionInfo.getChanges().size(); i++) {
+                ActivityManager.RunningTaskInfo taskInfo =
+                        mOpenTransitionInfo.getChanges().get(i).getTaskInfo();
+                if (taskInfo == null) {
+                    continue;
+                }
+
+                for (int j = 0; j < targets.length; j++) {
+                    if (taskInfo.taskId == targets[j].taskId) {
+                        updatedStates[i] = states[j];
+                        break;
+                    }
+                }
+            }
+
+            mTakeoverHandler.takeOverAnimation(
+                    mPrepareOpenTransition, mOpenTransitionInfo, new SurfaceControl.Transaction(),
+                    mFinishOpenTransitionCallback, updatedStates);
+
+            cleanUpInternalState();
+        }
+
         @Override
         public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted,
                 @Nullable SurfaceControl.Transaction finishTransaction) {
@@ -1673,6 +1757,11 @@
             }
             return null;
         }
+
+        private static boolean checkTakeoverFlags() {
+            return TransitionAnimator.Companion.longLivedReturnAnimationsEnabled()
+                    && Flags.unifyBackNavigationTransition();
+        }
     }
 
     private static boolean isNotGestureBackTransition(@NonNull TransitionInfo info) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index 3733930..7e5a82e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -39,6 +39,8 @@
 import android.view.animation.Interpolator
 import android.view.animation.Transformation
 import android.window.BackEvent
+import android.window.BackEvent.EDGE_LEFT
+import android.window.BackEvent.EDGE_RIGHT
 import android.window.BackMotionEvent
 import android.window.BackNavigationInfo
 import android.window.BackProgressAnimator
@@ -50,6 +52,7 @@
 import com.android.internal.policy.ScreenDecorationsUtils
 import com.android.internal.policy.SystemBarUtils
 import com.android.internal.protolog.ProtoLog
+import com.android.window.flags.Flags.predictiveBackTimestampApi
 import com.android.wm.shell.R
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.protolog.ShellProtoLogGroup
@@ -118,7 +121,9 @@
     private val postCommitFlingSpring = SpringForce(SPRING_SCALE)
             .setStiffness(SpringForce.STIFFNESS_LOW)
             .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+    private var swipeEdge = EDGE_LEFT
     protected var gestureProgress = 0f
+    private val velocityTracker = ProgressVelocityTracker()
 
     /** Background color to be used during the animation, also see [getBackgroundColor] */
     protected var customizedBackgroundColor = 0
@@ -175,6 +180,7 @@
             )
             return
         }
+        swipeEdge = backMotionEvent.swipeEdge
         triggerBack = backMotionEvent.triggerBack
         initialTouchPos.set(backMotionEvent.touchX, backMotionEvent.touchY)
 
@@ -241,6 +247,9 @@
         )
         applyTransaction()
         background.customizeStatusBarAppearance(currentClosingRect.top.toInt())
+        if (predictiveBackTimestampApi()) {
+            velocityTracker.addPosition(backEvent.frameTimeMillis, progress)
+        }
     }
 
     private fun getYOffset(centeredRect: RectF, touchY: Float): Float {
@@ -272,10 +281,19 @@
 
         // kick off spring animation with the current velocity from the pre-commit phase, this
         // affects the scaling of the closing and/or opening activity during post-commit
-        val startVelocity =
-            if (gestureProgress < 0.1f) -DEFAULT_FLING_VELOCITY else -velocity * SPRING_SCALE
+
+        var startVelocity = if (predictiveBackTimestampApi()) {
+            // pronounce fling animation more for gestures
+            val velocityFactor = if (swipeEdge == EDGE_LEFT || swipeEdge == EDGE_RIGHT) 2f else 1f
+            velocity * SPRING_SCALE * (1f - MAX_SCALE) * velocityFactor
+        } else {
+            velocity * SPRING_SCALE
+        }
+        if (gestureProgress < 0.1f) {
+            startVelocity = startVelocity.coerceAtLeast(DEFAULT_FLING_VELOCITY)
+        }
         val flingAnimation = SpringAnimation(postCommitFlingScale, SPRING_SCALE)
-            .setStartVelocity(startVelocity.coerceIn(-MAX_FLING_VELOCITY, 0f))
+            .setStartVelocity(-startVelocity.coerceIn(0f, MAX_FLING_VELOCITY))
             .setStartValue(SPRING_SCALE)
             .setSpring(postCommitFlingSpring)
         flingAnimation.start()
@@ -338,6 +356,7 @@
         lastPostCommitFlingScale = SPRING_SCALE
         gestureProgress = 0f
         triggerBack = false
+        velocityTracker.resetTracking()
     }
 
     protected fun applyTransform(
@@ -520,7 +539,11 @@
         override fun onBackInvoked() {
             triggerBack = true
             progressAnimator.reset()
-            onGestureCommitted(progressAnimator.velocity)
+            if (predictiveBackTimestampApi()) {
+                onGestureCommitted(velocityTracker.calculateVelocity())
+            } else {
+                onGestureCommitted(progressAnimator.velocity)
+            }
         }
     }
 
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 dc50fdb..f48b3ff 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,7 +16,6 @@
 
 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;
@@ -43,10 +42,8 @@
 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;
@@ -132,9 +129,8 @@
     private final SpringForce mPostCommitFlingSpring = new SpringForce(SPRING_SCALE)
             .setStiffness(FLING_SPRING_STIFFNESS)
             .setDampingRatio(1f);
-    private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
+    private final ProgressVelocityTracker mVelocityTracker = new ProgressVelocityTracker();
     private float mGestureProgress = 0f;
-    private long mDownTime = 0L;
 
     @Inject
     public CrossTaskBackAnimation(Context context, BackAnimationBackground background,
@@ -316,8 +312,7 @@
         mClosingCurrentRect.setEmpty();
         mInitialTouchPos.set(0, 0);
         mGestureProgress = 0;
-        mDownTime = 0;
-        mVelocityTracker.clear();
+        mVelocityTracker.resetTracking();
 
         if (mFinishCallback != null) {
             try {
@@ -333,22 +328,13 @@
     private void onGestureProgress(@NonNull BackEvent backEvent) {
         if (!mBackInProgress) {
             mBackInProgress = true;
-            mDownTime = backEvent.getFrameTimeMillis();
         }
         float progress = backEvent.getProgress();
         mTouchPos.set(backEvent.getTouchX(), backEvent.getTouchY());
         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
-                    )
-            );
+            mVelocityTracker.addPosition(backEvent.getFrameTimeMillis(),
+                    interpolatedProgress * SPRING_SCALE);
         }
         updateGestureBackProgress(interpolatedProgress, backEvent);
     }
@@ -362,9 +348,8 @@
         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();
+                    ? -DEFAULT_FLING_VELOCITY : -mVelocityTracker.calculateVelocity();
             SpringAnimation flingAnimation =
                     new SpringAnimation(mPostCommitFlingScale, SPRING_SCALE)
                     .setStartVelocity(Math.max(-MAX_FLING_VELOCITY, Math.min(0f, startVelocity)))
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ProgressVelocityTracker.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ProgressVelocityTracker.kt
new file mode 100644
index 0000000..6bbda0f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ProgressVelocityTracker.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.back
+
+import android.view.MotionEvent
+import android.view.VelocityTracker
+
+internal class ProgressVelocityTracker {
+    private val velocityTracker: VelocityTracker = VelocityTracker.obtain()
+    private var downTime = -1L
+
+    fun addPosition(timeMillis: Long, position: Float) {
+        if (downTime == -1L) downTime = timeMillis
+        velocityTracker.addMovement(
+            MotionEvent.obtain(
+                /* downTime */ downTime,
+                /* eventTime */ timeMillis,
+                /* action */ MotionEvent.ACTION_MOVE,
+                /* x */ position,
+                /* y */ 0f,
+                /* metaState */0
+            )
+        )
+    }
+
+    /** calculates current velocity (unit: progress per second) */
+    fun calculateVelocity(): Float {
+        velocityTracker.computeCurrentVelocity(1000)
+        return velocityTracker.xVelocity
+    }
+
+    fun resetTracking() {
+        velocityTracker.clear()
+        downTime = -1L
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 2945691..dc2025b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -898,7 +898,10 @@
             Bubble oldest = mOverflowBubbles.get(mOverflowBubbles.size() - 1);
             ProtoLog.d(WM_SHELL_BUBBLES, "overflow full, remove=%s", oldest.getKey());
             mStateChange.bubbleRemoved(oldest, Bubbles.DISMISS_OVERFLOW_MAX_REACHED);
-            mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED);
+            if (!mPositioner.isShowingInBubbleBar()) {
+                // Only logged for bubbles in stack view
+                mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED);
+            }
             mOverflowBubbles.remove(oldest);
             mStateChange.removedOverflowBubble = oldest;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 068b2d2..0fd4206 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -101,9 +101,13 @@
     private int mBubbleBarTopOnScreen;
 
     public BubblePositioner(Context context, WindowManager windowManager) {
+        this(context, DeviceConfig.create(context, windowManager));
+    }
+
+    public BubblePositioner(Context context, DeviceConfig deviceConfig) {
         mContext = context;
-        mDeviceConfig = DeviceConfig.create(context, windowManager);
-        update(mDeviceConfig);
+        mDeviceConfig = deviceConfig;
+        update(deviceConfig);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt
index 68fc0c9..a517a2d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt
@@ -42,6 +42,16 @@
     var componentName: ComponentName? = null
       private set
 
+    /**
+     * Whether the task view is visible and has a surface. Note that this does not check the alpha
+     * value of the task view.
+     *
+     * When this is `true` it is safe to start showing the task view. Otherwise if this is `false`
+     * callers should wait for it to be visible which will be indicated either by a call to
+     * [TaskView.Listener.onTaskCreated] or [TaskView.Listener.onTaskVisibilityChanged]. */
+    var isVisible = false
+      private set
+
     /** [TaskView.Listener] for users of this class. */
     var delegateListener: TaskView.Listener? = null
 
@@ -61,9 +71,12 @@
             this@BubbleTaskView.taskId = taskId
             isCreated = true
             componentName = name
+            // when the task is created it is visible
+            isVisible = true
         }
 
         override fun onTaskVisibilityChanged(taskId: Int, visible: Boolean) {
+            this@BubbleTaskView.isVisible = visible
             delegateListener?.onTaskVisibilityChanged(taskId, visible)
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index 74c3748..a313bd0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -161,6 +161,7 @@
 
         updateExpandedView();
         bbev.setAnimating(true);
+        bbev.setSurfaceZOrderedOnTop(true);
         bbev.setContentVisibility(false);
         bbev.setAlpha(0f);
         bbev.setTaskViewAlpha(0f);
@@ -171,28 +172,29 @@
 
         bbev.setAnimationMatrix(mExpandedViewContainerMatrix);
 
-        mExpandedViewAlphaAnimator.start();
+        bbev.animateExpansionWhenTaskViewVisible(() -> {
+            mExpandedViewAlphaAnimator.start();
 
-        PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel();
-        PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
-                .spring(AnimatableScaleMatrix.SCALE_X,
-                        AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
-                        mScaleInSpringConfig)
-                .spring(AnimatableScaleMatrix.SCALE_Y,
-                        AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
-                        mScaleInSpringConfig)
-                .addUpdateListener((target, values) -> {
-                    bbev.setAnimationMatrix(mExpandedViewContainerMatrix);
-                })
-                .withEndActions(() -> {
-                    bbev.setAnimationMatrix(null);
-                    updateExpandedView();
-                    bbev.setSurfaceZOrderedOnTop(false);
-                    if (afterAnimation != null) {
-                        afterAnimation.run();
-                    }
-                })
-                .start();
+            PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel();
+            PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
+                    .spring(AnimatableScaleMatrix.SCALE_X,
+                            AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
+                            mScaleInSpringConfig)
+                    .spring(AnimatableScaleMatrix.SCALE_Y,
+                            AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
+                            mScaleInSpringConfig)
+                    .addUpdateListener((target, values) -> {
+                        bbev.setAnimationMatrix(mExpandedViewContainerMatrix);
+                    })
+                    .withEndActions(() -> {
+                        bbev.setAnimationMatrix(null);
+                        updateExpandedView();
+                        if (afterAnimation != null) {
+                            afterAnimation.run();
+                        }
+                    })
+                    .start();
+        });
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 3764bcd..ed49417 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -131,6 +131,11 @@
     /** Current corner radius */
     private float mCurrentCornerRadius = 0f;
 
+    /** A runnable to start the expansion animation as soon as the task view is made visible. */
+    @Nullable
+    private Runnable mAnimateExpansion = null;
+    private TaskViewVisibilityState mVisibilityState = TaskViewVisibilityState.INVISIBLE;
+
     /**
      * Whether we want the {@code TaskView}'s content to be visible (alpha = 1f). If
      * {@link #mIsAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha
@@ -140,6 +145,18 @@
     private boolean mIsAnimating;
     private boolean mIsDragging;
 
+    /** An enum value that tracks the visibility state of the task view */
+    private enum TaskViewVisibilityState {
+        /** The task view is going away, and we're waiting for the surface to be destroyed. */
+        PENDING_INVISIBLE,
+        /** The task view is invisible and does not have a surface. */
+        INVISIBLE,
+        /** The task view is in the process of being added to a surface. */
+        PENDING_VISIBLE,
+        /** The task view is visible and has a surface. */
+        VISIBLE
+    }
+
     public BubbleBarExpandedView(Context context) {
         this(context, null);
     }
@@ -206,16 +223,27 @@
             mBubbleTaskViewHelper = new BubbleTaskViewHelper(mContext, expandedViewManager,
                     /* listener= */ this, bubbleTaskView,
                     /* viewParent= */ this);
+
+            // if the task view is already attached to a parent we need to remove it
             if (mTaskView.getParent() != null) {
+                // it's possible that the task view is visible, e.g. if we're unfolding, in which
+                // case removing it will trigger a visibility change. we have to wait for that
+                // signal before we can add it to this expanded view, otherwise the signal will be
+                // incorrect because the task view will have a surface.
+                // if the task view is not visible, then it has no surface and removing it will not
+                // trigger any visibility change signals.
+                if (bubbleTaskView.isVisible()) {
+                    mVisibilityState = TaskViewVisibilityState.PENDING_INVISIBLE;
+                }
                 ((ViewGroup) mTaskView.getParent()).removeView(mTaskView);
             }
-            FrameLayout.LayoutParams lp =
-                    new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
-            addView(mTaskView, lp);
-            mTaskView.setEnableSurfaceClipping(true);
-            mTaskView.setCornerRadius(mCurrentCornerRadius);
-            mTaskView.setVisibility(VISIBLE);
-            mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0));
+
+            // if we're invisible it's safe to setup the task view and then await on the visibility
+            // signal.
+            if (mVisibilityState == TaskViewVisibilityState.INVISIBLE) {
+                mVisibilityState = TaskViewVisibilityState.PENDING_VISIBLE;
+                setupTaskView();
+            }
 
             // Handle view needs to draw on top of task view.
             bringChildToFront(mHandleView);
@@ -269,6 +297,16 @@
         });
     }
 
+    private void setupTaskView() {
+        FrameLayout.LayoutParams lp =
+                new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
+        addView(mTaskView, lp);
+        mTaskView.setEnableSurfaceClipping(true);
+        mTaskView.setCornerRadius(mCurrentCornerRadius);
+        mTaskView.setVisibility(VISIBLE);
+        mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0));
+    }
+
     public BubbleBarHandleView getHandleView() {
         return mHandleView;
     }
@@ -326,15 +364,28 @@
 
     @Override
     public void onTaskCreated() {
-        setContentVisibility(true);
+        if (mTaskView != null) {
+            mTaskView.setAlpha(0);
+        }
         if (mListener != null) {
             mListener.onTaskCreated();
         }
+        // when the task is created we're visible
+        onTaskViewVisible();
     }
 
     @Override
     public void onContentVisibilityChanged(boolean visible) {
-        setContentVisibility(visible);
+        if (mVisibilityState == TaskViewVisibilityState.PENDING_INVISIBLE && !visible) {
+            // the surface is now destroyed. set up the task view and wait for the visibility
+            // signal.
+            mVisibilityState = TaskViewVisibilityState.PENDING_VISIBLE;
+            setupTaskView();
+            return;
+        }
+        if (visible) {
+            onTaskViewVisible();
+        }
     }
 
     @Override
@@ -350,6 +401,25 @@
         mListener.onBackPressed();
     }
 
+    void animateExpansionWhenTaskViewVisible(Runnable animateExpansion) {
+        if (mVisibilityState == TaskViewVisibilityState.VISIBLE || mIsOverflow) {
+            animateExpansion.run();
+        } else {
+            mAnimateExpansion = animateExpansion;
+        }
+    }
+
+    private void onTaskViewVisible() {
+        // if we're waiting to be visible, start the expansion animation if it's pending.
+        if (mVisibilityState == TaskViewVisibilityState.PENDING_VISIBLE) {
+            mVisibilityState = TaskViewVisibilityState.VISIBLE;
+            if (mAnimateExpansion != null) {
+                mAnimateExpansion.run();
+                mAnimateExpansion = null;
+            }
+        }
+    }
+
     /**
      * Set whether this view is currently being dragged.
      *
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
index 9abf0f6..de5c834 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
@@ -33,6 +33,9 @@
 
     default void onRecentTaskListFrozenChanged(boolean frozen) { }
 
+    /** A task is removed from recents as a result of another task being added to recent tasks. */
+    default void onRecentTaskRemovedForAddTask(int taskId) { }
+
     @BinderThread
     default void onTaskStackChangedBackground() { }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java
index d8859ba..4e1dec6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java
@@ -59,6 +59,7 @@
     private static final int ON_TASK_LIST_FROZEN_UNFROZEN = 18;
     private static final int ON_TASK_DESCRIPTION_CHANGED = 19;
     private static final int ON_ACTIVITY_ROTATION = 20;
+    private static final int ON_RECENT_TASK_REMOVED_FOR_ADD_TASK = 21;
 
     /**
      * List of {@link TaskStackListenerCallback} registered from {@link #addListener}.
@@ -132,6 +133,11 @@
     }
 
     @Override
+    public void onRecentTaskRemovedForAddTask(int taskId) {
+        mMainHandler.obtainMessage(ON_RECENT_TASK_REMOVED_FOR_ADD_TASK, taskId).sendToTarget();
+    }
+
+    @Override
     public void onTaskStackChanged() {
         // Call the task changed callback for the non-ui thread listeners first. Copy to a set
         // of temp listeners so that we don't lock on mTaskStackListeners while calling all the
@@ -408,6 +414,13 @@
                     }
                     break;
                 }
+                case ON_RECENT_TASK_REMOVED_FOR_ADD_TASK: {
+                    final int taskId = (int) msg.obj;
+                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                        mTaskStackListeners.get(i).onRecentTaskRemovedForAddTask(taskId);
+                    }
+                    break;
+                }
                 case ON_TASK_DESCRIPTION_CHANGED: {
                     final ActivityManager.RunningTaskInfo
                             info = (ActivityManager.RunningTaskInfo) msg.obj;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index cf858de..2c418d3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -90,8 +90,8 @@
     private int mHandleRegionHeight;
 
     /**
-     * Tracks divider bar visible bounds in screen-based coordination. Used to calculate with
-     * insets.
+     * This is not the visible bounds you see on screen, but the actual behind-the-scenes window
+     * bounds, which is larger.
      */
     private final Rect mDividerBounds = new Rect();
     private final Rect mTempRect = new Rect();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java
new file mode 100644
index 0000000..381f0b0
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.common.split;
+
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+
+import static com.android.wm.shell.common.split.SplitLayout.RESTING_TOUCH_LAYER;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.PixelFormat;
+import android.os.Binder;
+import android.view.MotionEvent;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowlessWindowManager;
+
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+/**
+ * Holds and manages a single touchable surface. These are used in offscreen split layouts, where
+ * we use them as a signal that the user wants to bring an offscreen app back onscreen.
+ * <br>
+ *                       Split root
+ *                    /      |       \
+ *         Stage root      Divider      Stage root
+ *           /   \
+ *      Task       *this class*
+ *
+ */
+public class OffscreenTouchZone {
+    private static final String TAG = "OffscreenTouchZone";
+
+    /**
+     * Whether this touch zone is on the top/left or the bottom/right screen edge.
+     */
+    private final boolean mIsTopLeft;
+    /** The function that will be run when this zone is tapped. */
+    private final Runnable mOnClickRunnable;
+    private SurfaceControlViewHost mViewHost;
+
+    /**
+     * @param isTopLeft Whether the desired touch zone will be on the top/left or the bottom/right
+     *                  screen edge.
+     * @param runnable The function to run when the touch zone is tapped.
+     */
+    OffscreenTouchZone(boolean isTopLeft, Runnable runnable) {
+        mIsTopLeft = isTopLeft;
+        mOnClickRunnable = runnable;
+    }
+
+    /** Sets up a touch zone. */
+    public void inflate(Context context, Configuration config, SyncTransactionQueue syncQueue,
+            SurfaceControl stageRoot) {
+        View touchableView = new View(context);
+        touchableView.setOnTouchListener(new OffscreenTouchListener());
+
+        // Set WM flags, tokens, and sizing on the touchable view. It will be the same size as its
+        // parent, the stage root.
+        // TODO (b/349828130): It's a bit wasteful to have the touch zone cover the whole app
+        //  surface, even extending offscreen (keeps buffer active in memory), so can trim it down
+        //  to the visible onscreen area in a future patch.
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.TYPE_INPUT_CONSUMER,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                PixelFormat.TRANSLUCENT);
+        lp.token = new Binder();
+        lp.setTitle(TAG);
+        lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
+        touchableView.setLayoutParams(lp);
+
+        // Create a new leash under our stage leash.
+        final SurfaceControl.Builder builder = new SurfaceControl.Builder()
+                .setContainerLayer()
+                .setName(TAG + (mIsTopLeft ? "TopLeft" : "BottomRight"))
+                .setCallsite("OffscreenTouchZone::init");
+        builder.setParent(stageRoot);
+        SurfaceControl leash = builder.build();
+
+        // Create a ViewHost that will hold our view.
+        WindowlessWindowManager wwm = new WindowlessWindowManager(config, leash, null);
+        mViewHost = new SurfaceControlViewHost(context, context.getDisplay(), wwm,
+                "SplitTouchZones");
+        mViewHost.setView(touchableView, lp);
+
+        // Create a transaction so that we can activate and reposition our surface.
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        // Set layer to maximum. We want this surface to be above the app layer, or else touches
+        // will be blocked.
+        t.setLayer(leash, RESTING_TOUCH_LAYER);
+        // Leash starts off hidden, show it.
+        t.show(leash);
+        syncQueue.runInSync(transaction -> {
+            transaction.merge(t);
+            t.close();
+        });
+    }
+
+    /** Releases the touch zone when it's no longer needed. */
+    void release() {
+        if (mViewHost != null) {
+            mViewHost.release();
+        }
+    }
+
+    /**
+     * Listens for touch events.
+     * TODO (b/349828130): Update for mouse click events as well, and possibly keyboard?
+     */
+    private class OffscreenTouchListener implements View.OnTouchListener {
+        @Override
+        public boolean onTouch(View view, MotionEvent motionEvent) {
+            if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
+                mOnClickRunnable.run();
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Returns {@code true} if this touch zone represents an offscreen app on the top/left edge of
+     * the display, {@code false} for bottom/right.
+     */
+    public boolean isTopLeft() {
+        return mIsTopLeft;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index de3152a..d20ad5d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -23,8 +23,8 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 
-import static com.android.wm.shell.common.split.SplitLayout.BEHIND_APP_VEIL_LAYER;
-import static com.android.wm.shell.common.split.SplitLayout.FRONT_APP_VEIL_LAYER;
+import static com.android.wm.shell.common.split.SplitLayout.ANIMATING_BACK_APP_VEIL_LAYER;
+import static com.android.wm.shell.common.split.SplitLayout.ANIMATING_FRONT_APP_VEIL_LAYER;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.FADE_DURATION;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.VEIL_DELAY_DURATION;
 
@@ -66,6 +66,13 @@
  * Currently, we show a veil when:
  *  a) Task is resizing down from a fullscreen window.
  *  b) Task is being stretched past its original bounds.
+ * <br>
+ *                       Split root
+ *                    /      |       \
+ *         Stage root      Divider      Stage root
+ *           /   \
+ *      Task       *this class*
+ *
  */
 public class SplitDecorManager extends WindowlessWindowManager {
     private static final String TAG = SplitDecorManager.class.getSimpleName();
@@ -77,6 +84,7 @@
     private Drawable mIcon;
     private ImageView mVeilIconView;
     private SurfaceControlViewHost mViewHost;
+    /** The parent surface that this is attached to. Should be the stage root. */
     private SurfaceControl mHostLeash;
     private SurfaceControl mIconLeash;
     private SurfaceControl mBackgroundLeash;
@@ -389,7 +397,9 @@
         mOffsetX = (int) iconOffsetX;
         mOffsetY = (int) iconOffsetY;
 
-        t.setLayer(leash, isGoingBehind ? BEHIND_APP_VEIL_LAYER : FRONT_APP_VEIL_LAYER);
+        t.setLayer(leash, isGoingBehind
+                ? ANIMATING_BACK_APP_VEIL_LAYER
+                : ANIMATING_FRONT_APP_VEIL_LAYER);
 
         if (!mShown) {
             if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 0f21756..6beff19 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -33,6 +33,8 @@
 import static com.android.wm.shell.shared.animation.Interpolators.SLOWDOWN_INTERPOLATOR;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_10_90;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_90_10;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_3_10_45_45;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_3_45_45_10;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -72,6 +74,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.protolog.ProtoLog;
+import com.android.wm.shell.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
@@ -80,6 +83,7 @@
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.pip.PipUtils;
 import com.android.wm.shell.common.split.DividerSnapAlgorithm.SnapTarget;
+import com.android.wm.shell.common.split.SplitWindowManager.ParentContainerCallbacks;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 import com.android.wm.shell.shared.split.SplitScreenConstants.PersistentSnapPosition;
@@ -88,6 +92,7 @@
 import com.android.wm.shell.splitscreen.StageTaskListener;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Consumer;
 
@@ -112,15 +117,19 @@
     public static final float OFFSCREEN_ASYMMETRIC_RATIO = 0.1f;
 
     // Here are some (arbitrarily decided) layer definitions used during animations to make sure the
-    // layers stay in order. Note: This does not affect any other layer numbering systems because
-    // the layer system in WindowManager is local within sibling groups. So, for example, each
-    // "veil layer" defined here actually has two sub-layers; and *their* layer values, which we set
-    // in SplitDecorManager, are only important relative to each other.
-    public static final int DIVIDER_LAYER = 0;
-    public static final int FRONT_APP_VEIL_LAYER = DIVIDER_LAYER + 20;
-    public static final int FRONT_APP_LAYER = DIVIDER_LAYER + 10;
-    public static final int BEHIND_APP_VEIL_LAYER = DIVIDER_LAYER - 10;
-    public static final int BEHIND_APP_LAYER = DIVIDER_LAYER - 20;
+    // layers stay in order. (During transitions, everything is reparented onto a transition root
+    // and can be freely relayered.)
+    public static final int ANIMATING_DIVIDER_LAYER = 0;
+    public static final int ANIMATING_FRONT_APP_VEIL_LAYER = ANIMATING_DIVIDER_LAYER + 20;
+    public static final int ANIMATING_FRONT_APP_LAYER = ANIMATING_DIVIDER_LAYER + 10;
+    public static final int ANIMATING_BACK_APP_VEIL_LAYER = ANIMATING_DIVIDER_LAYER - 10;
+    public static final int ANIMATING_BACK_APP_LAYER = ANIMATING_DIVIDER_LAYER - 20;
+    // The divider is on the split root, and is sibling with the stage roots. We want to keep it
+    // above the app stages.
+    public static final int RESTING_DIVIDER_LAYER = Integer.MAX_VALUE;
+    // The touch layer is on a stage root, and is sibling with things like the app activity itself
+    // and the app veil. We want it to be above all those.
+    public static final int RESTING_TOUCH_LAYER = Integer.MAX_VALUE;
 
     // Animation specs for the swap animation
     private static final int SWAP_ANIMATION_TOTAL_DURATION = 500;
@@ -155,10 +164,16 @@
     // The temp bounds outside of display bounds for side stage when split screen inactive to avoid
     // flicker next time active split screen.
     private final Rect mInvisibleBounds = new Rect();
+    /**
+     * Areas on the screen that the user can touch to shift the layout, bringing offscreen apps
+     * onscreen. If n apps are offscreen, there should be n such areas. Empty otherwise.
+     */
+    private final List<OffscreenTouchZone> mOffscreenTouchZones = new ArrayList<>();
     private final SplitLayoutHandler mSplitLayoutHandler;
     private final SplitWindowManager mSplitWindowManager;
     private final DisplayController mDisplayController;
     private final DisplayImeController mDisplayImeController;
+    private final ParentContainerCallbacks mParentContainerCallbacks;
     private final ImePositionProcessor mImePositionProcessor;
     private final ResizingEffectPolicy mSurfaceEffectPolicy;
     private final ShellTaskOrganizer mTaskOrganizer;
@@ -199,6 +214,7 @@
         mSplitLayoutHandler = splitLayoutHandler;
         mDisplayController = displayController;
         mDisplayImeController = displayImeController;
+        mParentContainerCallbacks = parentContainerCallbacks;
         mSplitWindowManager = new SplitWindowManager(windowName, mContext, configuration,
                 parentContainerCallbacks);
         mTaskOrganizer = taskOrganizer;
@@ -269,18 +285,6 @@
         return new Rect(mRootBounds);
     }
 
-    /** Gets bounds of divider window with screen based coordinate. */
-    public Rect getDividerBounds() {
-        return new Rect(mDividerBounds);
-    }
-
-    /** Gets bounds of divider window with parent based coordinate. */
-    public Rect getRefDividerBounds() {
-        final Rect outBounds = getDividerBounds();
-        outBounds.offset(-mRootBounds.left, -mRootBounds.top);
-        return outBounds;
-    }
-
     /** Copies the top/left bounds to the provided Rect (screen-based coordinates). */
     public void copyTopLeftBounds(Rect rect) {
         rect.set(getTopLeftBounds());
@@ -319,12 +323,36 @@
         return mContentBounds.getLast();
     }
 
-    /** Gets bounds of divider window with screen based coordinate on the param Rect. */
+    /**
+     * Gets the bounds of divider window, in screen-based coordinates. This is not the visible
+     * bounds you see on screen, but the actual behind-the-scenes window bounds, which is larger.
+     */
+    public Rect getDividerBounds() {
+        return new Rect(mDividerBounds);
+    }
+
+    /**
+     * Gets the bounds of divider window, in parent-based coordinates. This is not the visible
+     * bounds you see on screen, but the actual behind-the-scenes window bounds, which is larger.
+     */
+    public Rect getRefDividerBounds() {
+        final Rect outBounds = getDividerBounds();
+        outBounds.offset(-mRootBounds.left, -mRootBounds.top);
+        return outBounds;
+    }
+
+    /**
+     * Gets the bounds of divider window, in screen-based coordinates. This is not the visible
+     * bounds you see on screen, but the actual behind-the-scenes window bounds, which is larger.
+     */
     public void getDividerBounds(Rect rect) {
         rect.set(mDividerBounds);
     }
 
-    /** Gets bounds of divider window with parent based coordinate on the param Rect. */
+    /**
+     * Gets the bounds of divider window, in parent-based coordinates. This is not the visible
+     * bounds you see on screen, but the actual behind-the-scenes window bounds, which is larger.
+     */
     public void getRefDividerBounds(Rect rect) {
         getDividerBounds(rect);
         rect.offset(-mRootBounds.left, -mRootBounds.top);
@@ -372,6 +400,46 @@
                 mIsLeftRightSplit ? 0 : mRootBounds.bottom);
     }
 
+    /**
+     * (Re)calculates and activates any needed touch zones, so the user can tap them and retrieve
+     * offscreen apps.
+     */
+    public void populateTouchZones() {
+        if (!Flags.enableFlexibleTwoAppSplit()) {
+            return;
+        }
+
+        if (!mOffscreenTouchZones.isEmpty()) {
+            removeTouchZones();
+        }
+
+        int currentPosition = calculateCurrentSnapPosition();
+        switch (currentPosition) {
+            case SNAP_TO_2_10_90:
+            case SNAP_TO_3_10_45_45:
+                mOffscreenTouchZones.add(new OffscreenTouchZone(true /* isTopLeft */,
+                        () -> flingDividerToOtherSide(currentPosition)));
+                break;
+            case SNAP_TO_2_90_10:
+            case SNAP_TO_3_45_45_10:
+                mOffscreenTouchZones.add(new OffscreenTouchZone(false /* isTopLeft */,
+                        () -> flingDividerToOtherSide(currentPosition)));
+                break;
+        }
+
+        mOffscreenTouchZones.forEach(mParentContainerCallbacks::inflateOnStageRoot);
+    }
+
+    /** Removes all touch zones. */
+    public void removeTouchZones() {
+        if (!Flags.enableFlexibleTwoAppSplit()) {
+            return;
+        }
+
+        mOffscreenTouchZones.forEach(OffscreenTouchZone::release);
+        mOffscreenTouchZones.clear();
+    }
+
     /** Applies new configuration, returns {@code false} if there's no effect to the layout. */
     public boolean updateConfiguration(Configuration configuration) {
         // Update the split bounds when necessary. Besides root bounds changed, split bounds need to
@@ -509,6 +577,7 @@
         if (mInitialized) return;
         mInitialized = true;
         mSplitWindowManager.init(this, mInsetsState, false /* isRestoring */);
+        populateTouchZones();
         mDisplayImeController.addPositionProcessor(mImePositionProcessor);
     }
 
@@ -517,6 +586,7 @@
         if (!mInitialized) return;
         mInitialized = false;
         mSplitWindowManager.release(t);
+        removeTouchZones();
         mDisplayImeController.removePositionProcessor(mImePositionProcessor);
         mImePositionProcessor.reset();
         if (mDividerFlingAnimator != null) {
@@ -540,6 +610,7 @@
             mImePositionProcessor.reset();
         }
         mSplitWindowManager.init(this, mInsetsState, true /* isRestoring */);
+        populateTouchZones();
         // Update the surface positions again after recreating the divider in case nothing else
         // triggers it
         mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this);
@@ -782,6 +853,9 @@
      *  DividerSnapAlgorithm will need to be refactored, and this function will change as well.
      */
     public void flingDividerToOtherSide(@PersistentSnapPosition int currentSnapPosition) {
+        // If a fling animation is already running, just return.
+        if (mDividerFlingAnimator != null) return;
+
         switch (currentSnapPosition) {
             case SNAP_TO_2_10_90 ->
                     snapToTarget(mDividerPosition, mDividerSnapAlgorithm.getLastSplitTarget(),
@@ -1018,9 +1092,11 @@
 
             // Set layers
             if (taskInfo != null) {
-                t.setLayer(leash, isGoingBehind ? BEHIND_APP_LAYER : FRONT_APP_LAYER);
+                t.setLayer(leash, isGoingBehind
+                        ? ANIMATING_BACK_APP_LAYER
+                        : ANIMATING_FRONT_APP_LAYER);
             } else {
-                t.setLayer(leash, DIVIDER_LAYER);
+                t.setLayer(leash, ANIMATING_DIVIDER_LAYER);
             }
 
             if (offsetX == 0 && offsetY == 0) {
@@ -1079,7 +1155,7 @@
             getRefDividerBounds(mTempRect);
             t.setPosition(dividerLeash, mTempRect.left, mTempRect.top);
             // Resets layer of divider bar to make sure it is always on top.
-            t.setLayer(dividerLeash, Integer.MAX_VALUE);
+            t.setLayer(dividerLeash, RESTING_DIVIDER_LAYER);
         }
         copyTopLeftRefBounds(mTempRect);
         t.setPosition(leash1, mTempRect.left, mTempRect.top)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
index c5f1974..89573cc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
@@ -67,6 +67,8 @@
     public interface ParentContainerCallbacks {
         void attachToParentSurface(SurfaceControl.Builder b);
         void onLeashReady(SurfaceControl leash);
+        /** Inflates the given touch zone on the appropriate stage root. */
+        void inflateOnStageRoot(OffscreenTouchZone touchZone);
     }
 
     public SplitWindowManager(String windowName, Context context, Configuration config,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/transition/TransitionStateHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/transition/TransitionStateHolder.kt
new file mode 100644
index 0000000..4dda2a8
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/transition/TransitionStateHolder.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.common.transition
+
+import com.android.wm.shell.dagger.WMSingleton
+import com.android.wm.shell.recents.RecentsTransitionHandler
+import com.android.wm.shell.recents.RecentsTransitionStateListener
+import com.android.wm.shell.recents.RecentsTransitionStateListener.RecentsTransitionState
+import com.android.wm.shell.recents.RecentsTransitionStateListener.isRunning
+import com.android.wm.shell.sysui.ShellInit
+import javax.inject.Inject
+
+/**
+ * Holder for the state of the transitions.
+ */
+@WMSingleton
+class TransitionStateHolder @Inject constructor(
+    shellInit: ShellInit,
+    private val recentsTransitionHandler: RecentsTransitionHandler
+) {
+
+    @Volatile
+    @RecentsTransitionState
+    private var recentsTransitionState: Int =
+        RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING
+
+    init {
+        shellInit.addInitCallback({ onInit() }, this)
+    }
+
+    fun isRecentsTransitionRunning(): Boolean = isRunning(recentsTransitionState)
+
+    private fun onInit() {
+        recentsTransitionHandler.addTransitionStateListener(
+            object : RecentsTransitionStateListener {
+                override fun onTransitionStateChanged(@RecentsTransitionState state: Int) {
+                    recentsTransitionState = state
+                }
+            }
+        )
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java
index 49c2785..688f8ca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUILayout.java
@@ -68,7 +68,7 @@
 
     private void setViewVisibility(@IdRes int resId, boolean show) {
         final View view = findViewById(resId);
-        int visibility = show ? View.VISIBLE : View.INVISIBLE;
+        int visibility = show ? View.VISIBLE : View.GONE;
         if (view.getVisibility() == visibility) {
             return;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayout.java
index fd1bbc4..b141beb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayout.java
@@ -100,7 +100,7 @@
 
     private void setViewVisibility(@IdRes int resId, boolean show) {
         final View view = findViewById(resId);
-        int visibility = show ? View.VISIBLE : View.INVISIBLE;
+        int visibility = show ? View.VISIBLE : View.GONE;
         if (view.getVisibility() == visibility) {
             return;
         }
@@ -171,7 +171,7 @@
         fadeOut.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                view.setVisibility(View.INVISIBLE);
+                view.setVisibility(View.GONE);
             }
         });
         fadeOut.start();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxController.kt
index 0ac7aff..523e2f5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxController.kt
@@ -18,133 +18,51 @@
 
 import android.graphics.Rect
 import android.view.SurfaceControl
-import com.android.internal.protolog.ProtoLog
-import com.android.wm.shell.dagger.WMSingleton
-import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
-import javax.inject.Inject
+import android.view.SurfaceControl.Transaction
 
 /**
- * Component responsible for handling the lifecycle of the letterbox surfaces.
+ * Abstracts the component responsible to handle a single or multiple letterbox surfaces for a
+ * specific [Change].
  */
-@WMSingleton
-class LetterboxController @Inject constructor(
-    private val letterboxConfiguration: LetterboxConfiguration
-) {
-
-    companion object {
-        /*
-         * Letterbox surfaces need to stay below the activity layer which is 0.
-         */
-        // TODO(b/378673153): Consider adding this to [TaskConstants].
-        @JvmStatic
-        private val TASK_CHILD_LAYER_LETTERBOX_BACKGROUND = -1000
-        @JvmStatic
-        private val TAG = "LetterboxController"
-    }
-
-    private val letterboxMap = mutableMapOf<LetterboxKey, LetterboxItem>()
+interface LetterboxController {
 
     /**
      * Creates a Letterbox Surface for a given displayId/taskId if it doesn't exist.
      */
     fun createLetterboxSurface(
         key: LetterboxKey,
-        startTransaction: SurfaceControl.Transaction,
+        transaction: Transaction,
         parentLeash: SurfaceControl
-    ) {
-        letterboxMap.runOnItem(key, onMissed = { k, m ->
-            m[k] = LetterboxItem(
-                SurfaceControl.Builder()
-                    .setName("ShellLetterboxSurface-$key")
-                    .setHidden(true)
-                    .setColorLayer()
-                    .setParent(parentLeash)
-                    .setCallsite("LetterboxController-createLetterboxSurface")
-                    .build().apply {
-                        startTransaction.setLayer(
-                            this,
-                            TASK_CHILD_LAYER_LETTERBOX_BACKGROUND
-                        ).setColorSpaceAgnostic(this, true)
-                            .setColor(this, letterboxConfiguration.getBackgroundColorRgbArray())
-                    }
-            )
-        })
-    }
+    )
 
     /**
      * Invoked to destroy the surfaces for a letterbox session for given displayId/taskId.
      */
     fun destroyLetterboxSurface(
         key: LetterboxKey,
-        startTransaction: SurfaceControl.Transaction
-    ) {
-        letterboxMap.runOnItem(key, onFound = { item ->
-            item.fullWindowSurface?.run {
-                startTransaction.remove(this)
-            }
-        })
-        letterboxMap.remove(key)
-    }
+        transaction: Transaction
+    )
 
     /**
      * Invoked to show/hide the letterbox surfaces for given displayId/taskId.
      */
     fun updateLetterboxSurfaceVisibility(
         key: LetterboxKey,
-        startTransaction: SurfaceControl.Transaction,
-        visible: Boolean = true
-    ) {
-        letterboxMap.runOnItem(key, onFound = { item ->
-            item.fullWindowSurface?.run {
-                startTransaction.setVisibility(this, visible)
-            }
-        })
-    }
+        transaction: Transaction,
+        visible: Boolean
+    )
 
     /**
      * Updates the bounds for the letterbox surfaces for given displayId/taskId.
      */
     fun updateLetterboxSurfaceBounds(
         key: LetterboxKey,
-        startTransaction: SurfaceControl.Transaction,
-        bounds: Rect
-    ) {
-        letterboxMap.runOnItem(key, onFound = { item ->
-            item.fullWindowSurface?.run {
-                startTransaction.moveAndCrop(this, bounds)
-            }
-        })
-    }
+        transaction: Transaction,
+        taskBounds: Rect
+    )
 
-    /*
-     * Executes [onFound] on the [LetterboxItem] if present or [onMissed] if not present.
+    /**
+     * Utility method to dump the current state.
      */
-    private fun MutableMap<LetterboxKey, LetterboxItem>.runOnItem(
-        key: LetterboxKey,
-        onFound: (LetterboxItem) -> Unit = { _ -> },
-        onMissed: (
-            LetterboxKey,
-            MutableMap<LetterboxKey, LetterboxItem>
-        ) -> Unit = { _, _ -> }
-    ) {
-        this[key]?.let {
-            return onFound(it)
-        }
-        return onMissed(key, this)
-    }
-
-    fun dump() {
-        ProtoLog.v(WM_SHELL_APP_COMPAT, "%s: %s", TAG, "${letterboxMap.keys}")
-    }
-
-    private fun SurfaceControl.Transaction.moveAndCrop(
-        surface: SurfaceControl,
-        rect: Rect
-    ): SurfaceControl.Transaction =
-        setPosition(surface, rect.left.toFloat(), rect.top.toFloat())
-            .setWindowCrop(
-                surface,
-                rect.width(),
-                rect.height()
-            )
+    fun dump()
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxData.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxData.kt
index 98fd247..adb034c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxData.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxData.kt
@@ -16,10 +16,5 @@
 
 package com.android.wm.shell.compatui.letterbox
 
-import android.view.SurfaceControl
-
 // The key to use for identify the letterbox sessions.
-data class LetterboxKey(val displayId: Int, val taskId: Int)
-
-// Encapsulate the objects for the specific letterbox session.
-data class LetterboxItem(val fullWindowSurface: SurfaceControl?)
\ No newline at end of file
+data class LetterboxKey(val displayId: Int, val taskId: Int)
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxSurfaceBuilder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxSurfaceBuilder.kt
new file mode 100644
index 0000000..e88d91f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxSurfaceBuilder.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.letterbox
+
+import android.view.SurfaceControl
+import com.android.wm.shell.dagger.WMSingleton
+import javax.inject.Inject
+
+/**
+ * Component responsible for the actual creation of the Letterbox surfaces.
+ */
+@WMSingleton
+class LetterboxSurfaceBuilder @Inject constructor(
+    private val letterboxConfiguration: LetterboxConfiguration
+) {
+
+    companion object {
+        /*
+         * Letterbox surfaces need to stay below the activity layer which is 0.
+         */
+        // TODO(b/378673153): Consider adding this to [TaskConstants].
+        @JvmStatic
+        private val TASK_CHILD_LAYER_LETTERBOX_BACKGROUND = -1000
+    }
+
+    fun createSurface(
+        tx: SurfaceControl.Transaction,
+        parentLeash: SurfaceControl,
+        surfaceName: String,
+        callSite: String,
+        surfaceBuilder: SurfaceControl.Builder = SurfaceControl.Builder()
+    ) = surfaceBuilder
+        .setName(surfaceName)
+        .setHidden(true)
+        .setColorLayer()
+        .setParent(parentLeash)
+        .setCallsite(callSite)
+        .build().apply {
+            tx.setLayer(
+                this,
+                TASK_CHILD_LAYER_LETTERBOX_BACKGROUND
+            ).setColorSpaceAgnostic(this, true)
+                .setColor(this, letterboxConfiguration.getBackgroundColorRgbArray())
+        }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserver.kt
index 67429bd..b50716a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserver.kt
@@ -43,12 +43,7 @@
 
     init {
         if (appCompatRefactoring()) {
-            ProtoLog.v(
-                WM_SHELL_APP_COMPAT,
-                "%s: %s",
-                TAG,
-                "Initializing LetterboxTransitionObserver"
-            )
+            logV("Initializing LetterboxTransitionObserver")
             shellInit.addInitCallback({
                 transitions.registerObserver(this)
             }, this)
@@ -69,38 +64,45 @@
         for (change in info.changes) {
             change.taskInfo?.let { ti ->
                 val key = LetterboxKey(ti.displayId, ti.taskId)
-                if (isClosingType(change.mode)) {
-                    letterboxController.destroyLetterboxSurface(
-                        key,
-                        startTransaction
-                    )
-                } else {
-                    val isTopActivityLetterboxed = ti.appCompatTaskInfo.isTopActivityLetterboxed
-                    if (isTopActivityLetterboxed) {
-                        letterboxController.createLetterboxSurface(
+                val taskBounds = Rect(
+                    change.endRelOffset.x,
+                    change.endRelOffset.y,
+                    change.endAbsBounds.width(),
+                    change.endAbsBounds.height()
+                )
+                with(letterboxController) {
+                    if (isClosingType(change.mode)) {
+                        destroyLetterboxSurface(
                             key,
-                            startTransaction,
-                            change.leash
+                            startTransaction
                         )
-                        letterboxController.updateLetterboxSurfaceBounds(
+                    } else {
+                        val isTopActivityLetterboxed = ti.appCompatTaskInfo.isTopActivityLetterboxed
+                        if (isTopActivityLetterboxed) {
+                            createLetterboxSurface(
+                                key,
+                                startTransaction,
+                                change.leash
+                            )
+                            updateLetterboxSurfaceBounds(
+                                key,
+                                startTransaction,
+                                taskBounds
+                            )
+                        }
+                        updateLetterboxSurfaceVisibility(
                             key,
                             startTransaction,
-                            Rect(
-                                change.endRelOffset.x,
-                                change.endRelOffset.y,
-                                change.endAbsBounds.width(),
-                                change.endAbsBounds.height()
-                            )
+                            isTopActivityLetterboxed
                         )
                     }
-                    letterboxController.updateLetterboxSurfaceVisibility(
-                        key,
-                        startTransaction,
-                        isTopActivityLetterboxed
-                    )
+                    dump()
                 }
-                letterboxController.dump()
             }
         }
     }
+
+    private fun logV(msg: String) {
+        ProtoLog.v(WM_SHELL_APP_COMPAT, "%s: %s", TAG, msg)
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt
new file mode 100644
index 0000000..f21a727
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.letterbox
+
+import android.graphics.Rect
+import android.view.SurfaceControl
+import android.view.SurfaceControl.Transaction
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.dagger.WMSingleton
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
+import javax.inject.Inject
+
+/**
+ * Component responsible for handling the lifecycle of a single letterbox surface.
+ */
+@WMSingleton
+class SingleSurfaceLetterboxController @Inject constructor(
+    private val letterboxBuilder: LetterboxSurfaceBuilder
+) : LetterboxController {
+
+    companion object {
+        @JvmStatic
+        private val TAG = "LetterboxController"
+    }
+
+    private val letterboxMap = mutableMapOf<LetterboxKey, SurfaceControl>()
+
+    /**
+     * Creates a Letterbox Surface for a given displayId/taskId if it doesn't exist.
+     */
+    override fun createLetterboxSurface(
+        key: LetterboxKey,
+        transaction: Transaction,
+        parentLeash: SurfaceControl
+    ) {
+        letterboxMap.runOnItem(key, onMissed = { k, m ->
+            m[k] = letterboxBuilder.createSurface(
+                transaction,
+                parentLeash,
+                surfaceName = "ShellLetterboxSurface-$key",
+                callSite = "LetterboxController-createLetterboxSurface"
+            )
+        })
+    }
+
+    /**
+     * Invoked to destroy the surfaces for a letterbox session for given displayId/taskId.
+     */
+    override fun destroyLetterboxSurface(
+        key: LetterboxKey,
+        transaction: Transaction
+    ) {
+        letterboxMap.runOnItem(key, onFound = { item ->
+            item.run {
+                transaction.remove(this)
+            }
+        })
+        letterboxMap.remove(key)
+    }
+
+    /**
+     * Invoked to show/hide the letterbox surfaces for given displayId/taskId.
+     */
+    override fun updateLetterboxSurfaceVisibility(
+        key: LetterboxKey,
+        transaction: Transaction,
+        visible: Boolean
+    ) {
+        letterboxMap.runOnItem(key, onFound = { item ->
+            item.run {
+                transaction.setVisibility(this, visible)
+            }
+        })
+    }
+
+    /**
+     * Updates the bounds for the letterbox surfaces for given displayId/taskId.
+     */
+    override fun updateLetterboxSurfaceBounds(
+        key: LetterboxKey,
+        transaction: Transaction,
+        taskBounds: Rect
+    ) {
+        letterboxMap.runOnItem(key, onFound = { item ->
+            item.run {
+                transaction.moveAndCrop(this, taskBounds)
+            }
+        })
+    }
+
+    override fun dump() {
+        ProtoLog.v(WM_SHELL_APP_COMPAT, "%s: %s", TAG, "${letterboxMap.keys}")
+    }
+
+    /*
+     * Executes [onFound] on the [SurfaceControl] if present or [onMissed] if not present.
+     */
+    private fun MutableMap<LetterboxKey, SurfaceControl>.runOnItem(
+        key: LetterboxKey,
+        onFound: (SurfaceControl) -> Unit = { _ -> },
+        onMissed: (
+            LetterboxKey,
+            MutableMap<LetterboxKey, SurfaceControl>
+        ) -> Unit = { _, _ -> }
+    ) {
+        this[key]?.let {
+            return onFound(it)
+        }
+        return onMissed(key, this)
+    }
+
+    private fun Transaction.moveAndCrop(
+        surface: SurfaceControl,
+        rect: Rect
+    ): Transaction =
+        setPosition(surface, rect.left.toFloat(), rect.top.toFloat())
+            .setWindowCrop(
+                surface,
+                rect.width(),
+                rect.height()
+            )
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 6023750..cb9c20e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -799,10 +799,11 @@
             Transitions transitions,
             TaskStackListenerImpl taskStackListener,
             @ShellMainThread Handler mainHandler,
-            @ShellMainThread ShellExecutor mainExecutor) {
+            @ShellMainThread ShellExecutor mainExecutor,
+            FocusTransitionObserver focusTransitionObserver) {
         return new KeyguardTransitionHandler(
                 shellInit, shellController, displayController, transitions, taskStackListener,
-                mainHandler, mainExecutor);
+                mainHandler, mainExecutor, focusTransitionObserver);
     }
 
     @WMSingleton
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 5995462..9745353 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
@@ -17,6 +17,7 @@
 package com.android.wm.shell.dagger;
 
 import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_ENTER_TRANSITIONS;
+import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY;
 import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_TASK_LIMIT;
 import static android.window.DesktopModeFlags.ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS;
 
@@ -28,6 +29,7 @@
 import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
 import android.hardware.input.InputManager;
 import android.os.Handler;
 import android.os.UserManager;
@@ -69,6 +71,7 @@
 import com.android.wm.shell.compatui.letterbox.LetterboxCommandHandler;
 import com.android.wm.shell.compatui.letterbox.LetterboxController;
 import com.android.wm.shell.compatui.letterbox.LetterboxTransitionObserver;
+import com.android.wm.shell.compatui.letterbox.SingleSurfaceLetterboxController;
 import com.android.wm.shell.dagger.back.ShellBackAnimationModule;
 import com.android.wm.shell.dagger.pip.PipModule;
 import com.android.wm.shell.desktopmode.CloseDesktopTaskTransitionHandler;
@@ -82,6 +85,7 @@
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
 import com.android.wm.shell.desktopmode.DesktopModeKeyGestureHandler;
 import com.android.wm.shell.desktopmode.DesktopModeLoggerTransitionObserver;
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger;
 import com.android.wm.shell.desktopmode.DesktopRepository;
 import com.android.wm.shell.desktopmode.DesktopTaskChangeListener;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -94,6 +98,7 @@
 import com.android.wm.shell.desktopmode.SpringDragToDesktopTransitionHandler;
 import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler;
 import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
+import com.android.wm.shell.desktopmode.compatui.SystemModalsTransitionHandler;
 import com.android.wm.shell.desktopmode.education.AppHandleEducationController;
 import com.android.wm.shell.desktopmode.education.AppHandleEducationFilter;
 import com.android.wm.shell.desktopmode.education.AppToWebEducationController;
@@ -286,57 +291,15 @@
             @ShellBackgroundThread ShellExecutor bgExecutor,
             ShellInit shellInit,
             IWindowManager windowManager,
-            ShellCommandHandler shellCommandHandler,
             ShellTaskOrganizer taskOrganizer,
-            @DynamicOverride DesktopRepository desktopRepository,
             DisplayController displayController,
-            ShellController shellController,
-            DisplayInsetsController displayInsetsController,
             SyncTransactionQueue syncQueue,
             Transitions transitions,
-            Optional<DesktopTasksController> desktopTasksController,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
-            InteractionJankMonitor interactionJankMonitor,
-            AppToWebGenericLinksParser genericLinksParser,
-            AssistContentRequester assistContentRequester,
-            MultiInstanceHelper multiInstanceHelper,
-            Optional<DesktopTasksLimiter> desktopTasksLimiter,
-            AppHandleEducationController appHandleEducationController,
-            AppToWebEducationController appToWebEducationController,
-            WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
-            Optional<DesktopActivityOrientationChangeHandler> desktopActivityOrientationHandler,
             FocusTransitionObserver focusTransitionObserver,
-            DesktopModeEventLogger desktopModeEventLogger) {
-        if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
-            return new DesktopModeWindowDecorViewModel(
-                    context,
-                    mainExecutor,
-                    mainHandler,
-                    mainChoreographer,
-                    bgExecutor,
-                    shellInit,
-                    shellCommandHandler,
-                    windowManager,
-                    taskOrganizer,
-                    desktopRepository,
-                    displayController,
-                    shellController,
-                    displayInsetsController,
-                    syncQueue,
-                    transitions,
-                    desktopTasksController,
-                    rootTaskDisplayAreaOrganizer,
-                    interactionJankMonitor,
-                    genericLinksParser,
-                    assistContentRequester,
-                    multiInstanceHelper,
-                    desktopTasksLimiter,
-                    appHandleEducationController,
-                    appToWebEducationController,
-                    windowDecorCaptionHandleRepository,
-                    desktopActivityOrientationHandler,
-                    focusTransitionObserver,
-                    desktopModeEventLogger);
+            Optional<DesktopModeWindowDecorViewModel> desktopModeWindowDecorViewModel) {
+        if (desktopModeWindowDecorViewModel.isPresent()) {
+            return desktopModeWindowDecorViewModel.get();
         }
         return new CaptionWindowDecorViewModel(
                 context,
@@ -741,6 +704,7 @@
             InputManager inputManager,
             FocusTransitionObserver focusTransitionObserver,
             DesktopModeEventLogger desktopModeEventLogger,
+            DesktopModeUiEventLogger desktopModeUiEventLogger,
             DesktopTilingDecorViewModel desktopTilingDecorViewModel) {
         return new DesktopTasksController(
                 context,
@@ -771,6 +735,7 @@
                 interactionJankMonitor,
                 mainHandler,
                 desktopModeEventLogger,
+                desktopModeUiEventLogger,
                 desktopTilingDecorViewModel);
     }
 
@@ -890,14 +855,15 @@
             Optional<DesktopTasksController> desktopTasksController,
             InputManager inputManager,
             ShellTaskOrganizer shellTaskOrganizer,
-            FocusTransitionObserver focusTransitionObserver) {
+            FocusTransitionObserver focusTransitionObserver,
+            @ShellMainThread ShellExecutor mainExecutor) {
         if (DesktopModeStatus.canEnterDesktopMode(context) && useKeyGestureEventHandler()
                 && manageKeyGestures()
                 && (Flags.enableMoveToNextDisplayShortcut()
                 || Flags.enableTaskResizingKeyboardShortcuts())) {
             return Optional.of(new DesktopModeKeyGestureHandler(context,
                     desktopModeWindowDecorViewModel, desktopTasksController,
-                    inputManager, shellTaskOrganizer, focusTransitionObserver));
+                    inputManager, shellTaskOrganizer, focusTransitionObserver, mainExecutor));
         }
         return Optional.empty();
     }
@@ -908,7 +874,7 @@
             Context context,
             @ShellMainThread ShellExecutor shellExecutor,
             @ShellMainThread Handler mainHandler,
-            Choreographer mainChoreographer,
+            @ShellMainThread Choreographer mainChoreographer,
             @ShellBackgroundThread ShellExecutor bgExecutor,
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
@@ -921,6 +887,7 @@
             SyncTransactionQueue syncQueue,
             Transitions transitions,
             Optional<DesktopTasksController> desktopTasksController,
+            Optional<DesktopImmersiveController> desktopImmersiveController,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
             InteractionJankMonitor interactionJankMonitor,
             AppToWebGenericLinksParser genericLinksParser,
@@ -932,20 +899,42 @@
             WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
             Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
             FocusTransitionObserver focusTransitionObserver,
-            DesktopModeEventLogger desktopModeEventLogger
+            DesktopModeEventLogger desktopModeEventLogger,
+            DesktopModeUiEventLogger desktopModeUiEventLogger
     ) {
-        if (!DesktopModeStatus.canEnterDesktopMode(context)) {
+        if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
             return Optional.empty();
         }
         return Optional.of(new DesktopModeWindowDecorViewModel(context, shellExecutor, mainHandler,
                 mainChoreographer, bgExecutor, shellInit, shellCommandHandler, windowManager,
                 taskOrganizer, desktopRepository, displayController, shellController,
                 displayInsetsController, syncQueue, transitions, desktopTasksController,
+                desktopImmersiveController.get(),
                 rootTaskDisplayAreaOrganizer, interactionJankMonitor, genericLinksParser,
                 assistContentRequester, multiInstanceHelper, desktopTasksLimiter,
                 appHandleEducationController, appToWebEducationController,
                 windowDecorCaptionHandleRepository, activityOrientationChangeHandler,
-                focusTransitionObserver, desktopModeEventLogger));
+                focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger));
+    }
+
+    @WMSingleton
+    @Provides
+    static Optional<SystemModalsTransitionHandler> provideSystemModalsTransitionHandler(
+            Context context,
+            @ShellMainThread ShellExecutor mainExecutor,
+            @ShellAnimationThread ShellExecutor animExecutor,
+            ShellInit shellInit,
+            Transitions transitions,
+            @DynamicOverride DesktopRepository desktopRepository) {
+        if (!DesktopModeStatus.canEnterDesktopMode(context)
+                || !ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue()
+                || !Flags.enableDesktopSystemDialogsTransitions()) {
+            return Optional.empty();
+        }
+        return Optional.of(
+                new SystemModalsTransitionHandler(
+                        context, mainExecutor, animExecutor, shellInit, transitions,
+                        desktopRepository));
     }
 
     @WMSingleton
@@ -1250,6 +1239,15 @@
                 mainScope);
     }
 
+    @WMSingleton
+    @Provides
+    static DesktopModeUiEventLogger provideDesktopUiEventLogger(
+            UiEventLogger uiEventLogger,
+            PackageManager packageManager
+    ) {
+        return new DesktopModeUiEventLogger(uiEventLogger, packageManager);
+    }
+
     //
     // Drag and drop
     //
@@ -1304,7 +1302,8 @@
             @NonNull LetterboxCommandHandler letterboxCommandHandler,
             Optional<DesktopTasksTransitionObserver> desktopTasksTransitionObserverOptional,
             Optional<DesktopDisplayEventHandler> desktopDisplayEventHandler,
-            Optional<DesktopModeKeyGestureHandler> desktopModeKeyGestureHandler) {
+            Optional<DesktopModeKeyGestureHandler> desktopModeKeyGestureHandler,
+            Optional<SystemModalsTransitionHandler> systemModalsTransitionHandler) {
         return new Object();
     }
 
@@ -1321,4 +1320,9 @@
     ) {
         return new LetterboxTransitionObserver(shellInit, transitions, letterboxController);
     }
+
+    @WMSingleton
+    @Binds
+    abstract LetterboxController bindsLetterboxController(
+            SingleSurfaceLetterboxController letterboxController);
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
index 1acde73..dd95273d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
@@ -99,6 +99,7 @@
 
     /** Starts a transition to enter full immersive state inside the desktop. */
     fun moveTaskToImmersive(taskInfo: RunningTaskInfo) {
+        check(taskInfo.isFreeform) { "Task must already be in freeform" }
         if (inProgress) {
             logV(
                 "Cannot start entry because transition(s) already in progress: %s",
@@ -119,7 +120,9 @@
         )
     }
 
-    fun moveTaskToNonImmersive(taskInfo: RunningTaskInfo) {
+    /** Starts a transition to move an immersive task out of immersive. */
+    fun moveTaskToNonImmersive(taskInfo: RunningTaskInfo, reason: ExitReason) {
+        check(taskInfo.isFreeform) { "Task must already be in freeform" }
         if (inProgress) {
             logV(
                 "Cannot start exit because transition(s) already in progress: %s",
@@ -131,7 +134,7 @@
         val wct = WindowContainerTransaction().apply {
             setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
         }
-        logV("Moving task ${taskInfo.taskId} out of immersive mode")
+        logV("Moving task %d out of immersive mode, reason: %s", taskInfo.taskId, reason)
         val transition = transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ this)
         state = TransitionState(
             transition = transition,
@@ -151,10 +154,11 @@
     fun exitImmersiveIfApplicable(
         transition: IBinder,
         wct: WindowContainerTransaction,
-        displayId: Int
+        displayId: Int,
+        reason: ExitReason,
     ) {
         if (!Flags.enableFullyImmersiveInDesktop()) return
-        val result = exitImmersiveIfApplicable(wct, displayId)
+        val result = exitImmersiveIfApplicable(wct, displayId, excludeTaskId = null, reason)
         result.asExit()?.runOnTransitionStart?.invoke(transition)
     }
 
@@ -170,6 +174,7 @@
         wct: WindowContainerTransaction,
         displayId: Int,
         excludeTaskId: Int? = null,
+        reason: ExitReason,
     ): ExitResult {
         if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
         val immersiveTask = desktopRepository.getTaskInFullImmersiveState(displayId)
@@ -179,7 +184,10 @@
         }
         val taskInfo = shellTaskOrganizer.getRunningTaskInfo(immersiveTask)
             ?: return ExitResult.NoExit
-        logV("Appending immersive exit for task: $immersiveTask in display: $displayId")
+        logV(
+            "Appending immersive exit for task: %d in display: %d for reason: %s",
+            immersiveTask, displayId, reason
+        )
         wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
         return ExitResult.Exit(
             exitingTask = immersiveTask,
@@ -198,14 +206,15 @@
      */
     fun exitImmersiveIfApplicable(
         wct: WindowContainerTransaction,
-        taskInfo: RunningTaskInfo
+        taskInfo: RunningTaskInfo,
+        reason: ExitReason,
     ): ExitResult {
         if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
         if (desktopRepository.isTaskInFullImmersiveState(taskInfo.taskId)) {
             // A full immersive task is being minimized, make sure the immersive state is broken
             // (i.e. resize back to max bounds).
             wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
-            logV("Appending immersive exit for task: ${taskInfo.taskId}")
+            logV("Appending immersive exit for task: %d for reason: %s", taskInfo.taskId, reason)
             return ExitResult.Exit(
                 exitingTask = taskInfo.taskId,
                 runOnTransitionStart = { transition ->
@@ -550,6 +559,15 @@
         ENTER, EXIT
     }
 
+    /** The reason for moving the task out of desktop immersive mode. */
+    enum class ExitReason {
+        APP_NOT_IMMERSIVE, // The app stopped requesting immersive treatment.
+        USER_INTERACTION, // Explicit user intent request, e.g. a button click.
+        TASK_LAUNCH, // A task launched/moved on top of the immersive task.
+        MINIMIZED, // The immersive task was minimized.
+        CLOSED, // The immersive task was closed.
+    }
+
     private fun logV(msg: String, vararg arguments: Any?) {
         ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
index 39586e3..dc23128 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
@@ -187,8 +187,10 @@
      */
     fun logTaskResizingStarted(
         resizeTrigger: ResizeTrigger,
-        motionEvent: MotionEvent?,
+        inputMethod: InputMethod,
         taskInfo: RunningTaskInfo,
+        taskWidth: Int? = null,
+        taskHeight: Int? = null,
         displayController: DisplayController? = null,
         displayLayoutSize: Size? = null,
     ) {
@@ -205,8 +207,10 @@
 
         val taskSizeUpdate = createTaskSizeUpdate(
             resizeTrigger,
-            motionEvent,
+            inputMethod,
             taskInfo,
+            taskWidth,
+            taskHeight,
             displayController = displayController,
             displayLayoutSize = displayLayoutSize,
         )
@@ -228,10 +232,10 @@
      */
     fun logTaskResizingEnded(
         resizeTrigger: ResizeTrigger,
-        motionEvent: MotionEvent?,
+        inputMethod: InputMethod,
         taskInfo: RunningTaskInfo,
-        taskHeight: Int? = null,
         taskWidth: Int? = null,
+        taskHeight: Int? = null,
         displayController: DisplayController? = null,
         displayLayoutSize: Size? = null,
     ) {
@@ -248,10 +252,10 @@
 
         val taskSizeUpdate = createTaskSizeUpdate(
             resizeTrigger,
-            motionEvent,
+            inputMethod,
             taskInfo,
-            taskHeight,
             taskWidth,
+            taskHeight,
             displayController,
             displayLayoutSize,
         )
@@ -271,10 +275,10 @@
 
     private fun createTaskSizeUpdate(
         resizeTrigger: ResizeTrigger,
-        motionEvent: MotionEvent?,
+        inputMethod: InputMethod,
         taskInfo: RunningTaskInfo,
-        taskHeight: Int? = null,
         taskWidth: Int? = null,
+        taskHeight: Int? = null,
         displayController: DisplayController? = null,
         displayLayoutSize: Size? = null,
     ): TaskSizeUpdate {
@@ -292,7 +296,7 @@
 
         return TaskSizeUpdate(
             resizeTrigger,
-            getInputMethodFromMotionEvent(motionEvent),
+            inputMethod,
             taskInfo.taskId,
             taskInfo.effectiveUid,
             height,
@@ -442,7 +446,8 @@
             val displayArea: Int?,
         )
 
-        private fun getInputMethodFromMotionEvent(e: MotionEvent?): InputMethod {
+        @JvmStatic
+        fun getInputMethodFromMotionEvent(e: MotionEvent?): InputMethod {
             if (e == null) return InputMethod.UNKNOWN_INPUT_METHOD
 
             val toolType = e.getToolType(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
index ac07eaa..2b0724d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
@@ -30,9 +30,11 @@
 import android.content.Context
 import com.android.hardware.input.Flags.manageKeyGestures
 import com.android.window.flags.Flags.enableTaskResizingKeyboardShortcuts
+import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
 import com.android.wm.shell.transition.FocusTransitionObserver
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+import com.android.wm.shell.shared.annotations.ShellMainThread
 import java.util.Optional
 
 /**
@@ -45,6 +47,7 @@
     inputManager: InputManager,
     private val shellTaskOrganizer: ShellTaskOrganizer,
     private val focusTransitionObserver: FocusTransitionObserver,
+    @ShellMainThread private val mainExecutor: ShellExecutor,
     ) : KeyGestureEventHandler {
 
     init {
@@ -66,15 +69,14 @@
                 }
                 return true
             }
-            // TODO(b/375356876): Modify function to pass in keyboard shortcut as the input
-            // method for logging task resize
             KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW -> {
                 logV("Key gesture SNAP_LEFT_FREEFORM_WINDOW is handled")
                 getGloballyFocusedFreeformTask()?.let {
                     desktopModeWindowDecorViewModel.get().onSnapResize(
                         it.taskId,
                         true,
-                        null
+                        DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
+                        /* fromMenu= */ false
                     )
                 }
                 return true
@@ -85,7 +87,8 @@
                     desktopModeWindowDecorViewModel.get().onSnapResize(
                         it.taskId,
                         false,
-                        null
+                        DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
+                        /* fromMenu= */ false
                     )
                 }
                 return true
@@ -96,7 +99,7 @@
                     desktopTasksController.get().toggleDesktopTaskSize(
                         it,
                         ResizeTrigger.MAXIMIZE_MENU,
-                        null,
+                        DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
                     )
                 }
                 return true
@@ -104,9 +107,11 @@
             KeyGestureEvent.KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW -> {
                 logV("Key gesture MINIMIZE_FREEFORM_WINDOW is handled")
                 getGloballyFocusedFreeformTask()?.let {
-                    desktopTasksController.get().minimizeTask(
-                        it,
-                    )
+                    mainExecutor.execute {
+                        desktopTasksController.get().minimizeTask(
+                            it,
+                        )
+                    }
                 }
                 return true
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
index a9d4e5f..2c432bc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
@@ -16,22 +16,23 @@
 
 package com.android.wm.shell.desktopmode
 
-import android.util.Log
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.pm.PackageManager
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.InstanceIdSequence
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
-import com.android.wm.shell.dagger.WMSingleton
-import javax.inject.Inject
+import com.android.internal.logging.UiEventLogger.UiEventEnum
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
 
 /** Log Aster UIEvents for desktop windowing mode. */
-@WMSingleton
-class DesktopModeUiEventLogger
-@Inject
-constructor(
-    private val mUiEventLogger: UiEventLogger,
-    private val mInstanceIdSequence: InstanceIdSequence
+class DesktopModeUiEventLogger(
+    private val uiEventLogger: UiEventLogger,
+    private val packageManager: PackageManager,
 ) {
+    private val instanceIdSequence = InstanceIdSequence(Integer.MAX_VALUE)
+
     /**
      * Logs an event for a CUI, on a particular package.
      *
@@ -41,14 +42,25 @@
      */
     fun log(uid: Int, packageName: String, event: DesktopUiEventEnum) {
         if (packageName.isEmpty() || uid < 0) {
-            Log.d(TAG, "Skip logging since package name is empty or bad uid")
+            logD("Skip logging since package name is empty or bad uid")
             return
         }
-        mUiEventLogger.log(event, uid, packageName)
+        uiEventLogger.log(event, uid, packageName)
+    }
+
+    /** Logs an event for a CUI on a particular task. */
+    fun log(taskInfo: RunningTaskInfo, event: DesktopUiEventEnum) {
+        val packageName = taskInfo.baseActivity?.packageName
+        if (packageName == null) {
+            logD("Skip logging due to null base activity")
+            return
+        }
+        val uid = getUid(packageName, taskInfo.userId)
+        log(uid, packageName, event)
     }
 
     /** Retrieves a new instance id for a new interaction. */
-    fun getNewInstanceId(): InstanceId = mInstanceIdSequence.newInstanceId()
+    fun getNewInstanceId(): InstanceId = instanceIdSequence.newInstanceId()
 
     /**
      * Logs an event as part of a particular CUI, on a particular package.
@@ -66,28 +78,71 @@
         event: DesktopUiEventEnum
     ) {
         if (packageName.isEmpty() || uid < 0) {
-            Log.d(TAG, "Skip logging since package name is empty or bad uid")
+            logD("Skip logging since package name is empty or bad uid")
             return
         }
-        mUiEventLogger.logWithInstanceId(event, uid, packageName, instanceId)
+        uiEventLogger.logWithInstanceId(event, uid, packageName, instanceId)
+    }
+
+    private fun getUid(packageName: String, userId: Int): Int = try {
+        packageManager.getApplicationInfoAsUser(packageName, /* flags= */ 0, userId).uid
+    } catch (e: PackageManager.NameNotFoundException) {
+        INVALID_PACKAGE_UID
+    }
+
+    private fun logD(msg: String, vararg arguments: Any?) {
+        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+    }
+
+    /** Enums for logging desktop windowing mode UiEvents. */
+    enum class DesktopUiEventEnum(private val mId: Int) : UiEventEnum {
+
+        @UiEvent(doc = "Resize the window in desktop windowing mode by dragging the edge")
+        DESKTOP_WINDOW_EDGE_DRAG_RESIZE(1721),
+        @UiEvent(doc = "Resize the window in desktop windowing mode by dragging the corner")
+        DESKTOP_WINDOW_CORNER_DRAG_RESIZE(1722),
+        @UiEvent(doc = "Tap on the window header maximize button in desktop windowing mode")
+        DESKTOP_WINDOW_MAXIMIZE_BUTTON_TAP(1723),
+        @UiEvent(doc = "Double tap on window header to maximize it in desktop windowing mode")
+        DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_MAXIMIZE(1724),
+        @UiEvent(doc = "Tap on the window Handle to open the Handle Menu")
+        DESKTOP_WINDOW_APP_HANDLE_TAP(1998),
+        @UiEvent(doc = "Tap on the desktop mode option under app handle menu")
+        DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_DESKTOP_MODE(1999),
+        @UiEvent(doc = "Tap on the split screen option under app handle menu")
+        DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_SPLIT_SCREEN(2000),
+        @UiEvent(doc = "Tap on the full screen option under app handle menu")
+        DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_FULL_SCREEN(2001),
+        @UiEvent(doc = "When user successfully drags the app handle to desktop mode")
+        DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_DESKTOP_MODE(2002),
+        @UiEvent(doc = "When user successfully drags the app handle to split screen")
+        DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_SPLIT_SCREEN(2003),
+        @UiEvent(doc = "When user successfully drags the app handle to full screen")
+        DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_FULL_SCREEN(2004),
+        @UiEvent(doc = "Drag the window header to the top to switch to full screen mode")
+        DESKTOP_WINDOW_APP_HEADER_DRAG_TO_FULL_SCREEN(2005),
+        @UiEvent(doc = "Drag the window header to an edge to tile it to the left side")
+        DESKTOP_WINDOW_APP_HEADER_DRAG_TO_TILE_TO_LEFT(2006),
+        @UiEvent(doc = "Drag the window header to an edge to tile it to the right side")
+        DESKTOP_WINDOW_APP_HEADER_DRAG_TO_TILE_TO_RIGHT(2007),
+        @UiEvent(doc = "Hover or long press the maximize button to reveal the menu")
+        DESKTOP_WINDOW_MAXIMIZE_BUTTON_REVEAL_MENU(2015),
+        @UiEvent(doc = "Tap on the maximize option in the maximize button menu")
+        DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_MAXIMIZE(2009),
+        @UiEvent(doc = "Tap on the immersive option in the maximize button menu")
+        DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_IMMERSIVE(2010),
+        @UiEvent(doc = "Tap on the restore option in the maximize button menu")
+        DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_RESTORE(2011),
+        @UiEvent(doc = "Tap on the tile to left option in the maximize button menu")
+        DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_TILE_TO_LEFT(2012),
+        @UiEvent(doc = "Tap on the tile to right option in the maximize button menu")
+        DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_TILE_TO_RIGHT(2013);
+
+        override fun getId(): Int = mId
     }
 
     companion object {
-        /** Enums for logging desktop windowing mode UiEvents. */
-        enum class DesktopUiEventEnum(private val mId: Int) : UiEventLogger.UiEventEnum {
-
-            @UiEvent(doc = "Resize the window in desktop windowing mode by dragging the edge")
-            DESKTOP_WINDOW_EDGE_DRAG_RESIZE(1721),
-            @UiEvent(doc = "Resize the window in desktop windowing mode by dragging the corner")
-            DESKTOP_WINDOW_CORNER_DRAG_RESIZE(1722),
-            @UiEvent(doc = "Tap on the window header maximize button in desktop windowing mode")
-            DESKTOP_WINDOW_MAXIMIZE_BUTTON_TAP(1723),
-            @UiEvent(doc = "Double tap on window header to maximize it in desktop windowing mode")
-            DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_MAXIMIZE(1724);
-
-            override fun getId(): Int = mId
-        }
-
         private const val TAG = "DesktopModeUiEventLogger"
+        private const val INVALID_PACKAGE_UID = -1
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 09e77fe..80d8ecc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -120,6 +120,7 @@
     private View mView;
     private IndicatorType mCurrentType;
     private DragStartState mDragStartState;
+    private boolean mIsReleased;
 
     public DesktopModeVisualIndicator(SyncTransactionQueue syncQueue,
             ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController,
@@ -240,6 +241,7 @@
      * Create a fullscreen indicator with no animation
      */
     private void createView() {
+        if (mIsReleased) return;
         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         final Resources resources = mContext.getResources();
         final DisplayMetrics metrics = resources.getDisplayMetrics();
@@ -295,6 +297,12 @@
      * @param finishCallback called when animation ends or gets cancelled
      */
     void fadeOutIndicator(@Nullable Runnable finishCallback) {
+        if (mCurrentType == NO_INDICATOR) {
+            // In rare cases, fade out can be requested before the indicator has determined its
+            // initial type and started animating in. In this case, no animator is needed.
+            finishCallback.run();
+            return;
+        }
         final VisualIndicatorAnimator animator = VisualIndicatorAnimator
                 .fadeBoundsOut(mView, mCurrentType,
                         mDisplayController.getDisplayLayout(mTaskInfo.displayId));
@@ -335,6 +343,7 @@
      * Release the indicator and its components when it is no longer needed.
      */
     public void releaseVisualIndicator(SurfaceControl.Transaction t) {
+        mIsReleased = true;
         if (mViewHost == null) return;
         if (mViewHost != null) {
             mViewHost.release();
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 a0bdd9f..c479ab3 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
@@ -70,7 +70,6 @@
 import com.android.internal.policy.ScreenDecorationsUtils
 import com.android.internal.protolog.ProtoLog
 import com.android.window.flags.Flags
-import com.android.window.flags.Flags.enableMoveToNextDisplayShortcut
 import com.android.wm.shell.Flags.enableFlexibleSplit
 import com.android.wm.shell.R
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
@@ -129,10 +128,14 @@
 import java.util.Optional
 import java.util.concurrent.Executor
 import java.util.function.Consumer
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum
 import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.Companion.DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS
 import com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION
 import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler.FULLSCREEN_ANIMATION_DURATION
+import com.android.wm.shell.recents.RecentsTransitionStateListener.RecentsTransitionState
+import com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING
 
 /** Handles moving tasks in and out of desktop */
 class DesktopTasksController(
@@ -164,6 +167,7 @@
     private val interactionJankMonitor: InteractionJankMonitor,
     @ShellMainThread private val handler: Handler,
     private val desktopModeEventLogger: DesktopModeEventLogger,
+    private val desktopModeUiEventLogger: DesktopModeUiEventLogger,
     private val desktopTilingDecorViewModel: DesktopTilingDecorViewModel,
 ) :
     RemoteCallable<DesktopTasksController>,
@@ -209,7 +213,9 @@
     val draggingTaskId
         get() = dragToDesktopTransitionHandler.draggingTaskId
 
-    private var recentsAnimationRunning = false
+    @RecentsTransitionState
+    private var recentsTransitionState = TRANSITION_STATE_NOT_RUNNING
+
     private lateinit var splitScreenController: SplitScreenController
     lateinit var freeformTaskTransitionStarter: FreeformTaskTransitionStarter
     // Launch cookie used to identify a drag and drop transition to fullscreen after it has begun.
@@ -238,10 +244,15 @@
         dragToDesktopTransitionHandler.dragToDesktopStateListener = dragToDesktopStateListener
         recentsTransitionHandler.addTransitionStateListener(
             object : RecentsTransitionStateListener {
-                override fun onAnimationStateChanged(running: Boolean) {
-                    logV("Recents animation state changed running=%b", running)
-                    recentsAnimationRunning = running
-                    desktopTilingDecorViewModel.onOverviewAnimationStateChange(running)
+                override fun onTransitionStateChanged(@RecentsTransitionState state: Int) {
+                    logV(
+                        "Recents transition state changed: %s",
+                        RecentsTransitionStateListener.stateToString(state)
+                    )
+                    recentsTransitionState = state
+                    desktopTilingDecorViewModel.onOverviewAnimationStateChange(
+                        RecentsTransitionStateListener.isAnimating(state)
+                    )
                 }
             }
         )
@@ -381,6 +392,7 @@
             wct = wct,
             displayId = DEFAULT_DISPLAY,
             excludeTaskId = taskId,
+            reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
         )
         wct.startTask(
             taskId,
@@ -413,6 +425,7 @@
             wct = wct,
             displayId = task.displayId,
             excludeTaskId = task.taskId,
+            reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
         )
         // Bring other apps to front first
         val taskIdToMinimize =
@@ -460,7 +473,11 @@
             bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
         addMoveToDesktopChanges(wct, taskInfo)
         val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(
-            wct, taskInfo.displayId)
+            wct = wct,
+            displayId = taskInfo.displayId,
+            excludeTaskId = null,
+            reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH
+        )
         val transition = dragToDesktopTransitionHandler.finishDragToDesktopTransition(wct)
         desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
             DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS.toInt()
@@ -508,8 +525,11 @@
                 taskId
             )
         )
-        return desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo).asExit()
-            ?.runOnTransitionStart
+        return desktopImmersiveController.exitImmersiveIfApplicable(
+            wct = wct,
+            taskInfo = taskInfo,
+            reason = DesktopImmersiveController.ExitReason.CLOSED
+        ).asExit()?.runOnTransitionStart
     }
 
     fun minimizeTask(taskInfo: RunningTaskInfo) {
@@ -518,7 +538,11 @@
         val wct = WindowContainerTransaction()
         performDesktopExitCleanupIfNeeded(taskId, wct)
         // Notify immersive handler as it might need to exit immersive state.
-        val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo)
+        val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(
+            wct = wct,
+            taskInfo = taskInfo,
+            reason = DesktopImmersiveController.ExitReason.MINIMIZED
+        )
 
         wct.reorder(taskInfo.token, false)
         val transition = freeformTaskTransitionStarter.startMinimizedModeTransition(wct)
@@ -675,6 +699,7 @@
             wct = wct,
             displayId = displayId,
             excludeTaskId = launchingTaskId,
+            reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
         )
         if (remoteTransition == null) {
             val t = desktopMixedTransitionHandler.startLaunchTransition(
@@ -763,25 +788,6 @@
         transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */)
     }
 
-    /** Moves a task in/out of full immersive state within the desktop. */
-    fun toggleDesktopTaskFullImmersiveState(taskInfo: RunningTaskInfo) {
-        if (taskRepository.isTaskInFullImmersiveState(taskInfo.taskId)) {
-            exitDesktopTaskFromFullImmersive(taskInfo)
-        } else {
-            moveDesktopTaskToFullImmersive(taskInfo)
-        }
-    }
-
-    private fun moveDesktopTaskToFullImmersive(taskInfo: RunningTaskInfo) {
-        check(taskInfo.isFreeform) { "Task must already be in freeform" }
-        desktopImmersiveController.moveTaskToImmersive(taskInfo)
-    }
-
-    private fun exitDesktopTaskFromFullImmersive(taskInfo: RunningTaskInfo) {
-        check(taskInfo.isFreeform) { "Task must already be in freeform" }
-        desktopImmersiveController.moveTaskToNonImmersive(taskInfo)
-    }
-
     /**
      * Quick-resizes a desktop task, toggling between a fullscreen state (represented by the stable
      * bounds) and a free floating state (either the last saved bounds if available or the default
@@ -790,16 +796,23 @@
     fun toggleDesktopTaskSize(
         taskInfo: RunningTaskInfo,
         resizeTrigger: ResizeTrigger,
-        motionEvent: MotionEvent?,
+        inputMethod: InputMethod,
+        maximizeCujRecorder: (() -> Unit)? = null,
+        unmaximizeCujRecorder: (() -> Unit)? = null,
     ) {
+        val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
         desktopModeEventLogger.logTaskResizingStarted(
-            resizeTrigger, motionEvent, taskInfo, displayController
+            resizeTrigger,
+            inputMethod,
+            taskInfo,
+            currentTaskBounds.width(),
+            currentTaskBounds.height(),
+            displayController
         )
 
         val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
 
         val stableBounds = Rect().apply { displayLayout.getStableBounds(this) }
-        val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
         val destinationBounds = Rect()
 
         val isMaximized = isTaskMaximized(taskInfo, stableBounds)
@@ -807,6 +820,7 @@
         // helpful to eliminate the current task from logic to calculate taskbar corner rounding.
         val willMaximize = !isMaximized
         if (isMaximized) {
+            unmaximizeCujRecorder?.invoke()
             // The desktop task is at the maximized width and/or height of the stable bounds.
             // If the task's pre-maximize stable bounds were saved, toggle the task to those bounds.
             // Otherwise, toggle to the default bounds.
@@ -822,6 +836,7 @@
                 }
             }
         } else {
+            maximizeCujRecorder?.invoke()
             // Save current bounds so that task can be restored back to original bounds if necessary
             // and toggle to the stable bounds.
             desktopTilingDecorViewModel.removeTaskIfTiled(taskInfo.displayId, taskInfo.taskId)
@@ -843,8 +858,9 @@
         taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding)
         val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
         desktopModeEventLogger.logTaskResizingEnded(
-            resizeTrigger, motionEvent, taskInfo, destinationBounds.height(),
-            destinationBounds.width(), displayController
+            resizeTrigger, inputMethod,
+            taskInfo, destinationBounds.width(),
+            destinationBounds.height(), displayController
         )
         toggleResizeDesktopTaskTransitionHandler.startTransition(wct)
     }
@@ -874,7 +890,11 @@
             return
         }
 
-        toggleDesktopTaskSize(taskInfo, ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER, motionEvent)
+        toggleDesktopTaskSize(
+            taskInfo,
+            ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER,
+            DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
+        )
     }
 
     private fun getMaximizeBounds(taskInfo: RunningTaskInfo, stableBounds: Rect): Rect {
@@ -965,11 +985,26 @@
         currentDragBounds: Rect,
         position: SnapPosition,
         resizeTrigger: ResizeTrigger,
-        motionEvent: MotionEvent?,
+        inputMethod: InputMethod,
         desktopWindowDecoration: DesktopModeWindowDecoration,
     ) {
         desktopModeEventLogger.logTaskResizingStarted(
-            resizeTrigger, motionEvent, taskInfo, displayController
+            resizeTrigger,
+            inputMethod,
+            taskInfo,
+            currentDragBounds.width(),
+            currentDragBounds.height(),
+            displayController
+        )
+
+        val destinationBounds = getSnapBounds(taskInfo, position)
+        desktopModeEventLogger.logTaskResizingEnded(
+            resizeTrigger,
+            inputMethod,
+            taskInfo,
+            destinationBounds.width(),
+            destinationBounds.height(),
+            displayController,
         )
 
         if (DesktopModeFlags.ENABLE_TILE_RESIZING.isTrue()) {
@@ -984,15 +1019,7 @@
             }
             return
         }
-        val destinationBounds = getSnapBounds(taskInfo, position)
-        desktopModeEventLogger.logTaskResizingEnded(
-            resizeTrigger,
-            motionEvent,
-            taskInfo,
-            destinationBounds.height(),
-            destinationBounds.width(),
-            displayController,
-        )
+
         if (destinationBounds == taskInfo.configuration.windowConfiguration.bounds) {
             // Handle the case where we attempt to snap resize when already snap resized: the task
             // position won't need to change but we want to animate the surface going back to the
@@ -1022,7 +1049,7 @@
         taskInfo: RunningTaskInfo,
         position: SnapPosition,
         resizeTrigger: ResizeTrigger,
-        motionEvent: MotionEvent? = null,
+        inputMethod: InputMethod,
         desktopModeWindowDecoration: DesktopModeWindowDecoration,
     ) {
         if (!isSnapResizingAllowed(taskInfo)) {
@@ -1040,7 +1067,7 @@
             taskInfo.configuration.windowConfiguration.bounds,
             position,
             resizeTrigger,
-            motionEvent,
+            inputMethod,
             desktopModeWindowDecoration
         )
     }
@@ -1091,7 +1118,7 @@
                 currentDragBounds,
                 position,
                 resizeTrigger,
-                motionEvent,
+                DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
                 desktopModeWindowDecoration,
             )
         }
@@ -1292,6 +1319,8 @@
         // Check if we should skip handling this transition
         var reason = ""
         val triggerTask = request.triggerTask
+        val recentsAnimationRunning =
+            RecentsTransitionStateListener.isAnimating(recentsTransitionState)
         var shouldHandleMidRecentsFreeformLaunch =
             recentsAnimationRunning && isFreeformRelaunch(triggerTask, request)
         val isDragAndDropFullscreenTransition = taskContainsDragAndDropCookie(triggerTask)
@@ -1479,6 +1508,7 @@
                     wct = wct,
                     displayId = callingTask.displayId,
                     excludeTaskId = requestedTaskId,
+                    reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
                 )
             val transition = transitions.startTransition(TRANSIT_OPEN, wct, null)
             taskIdToMinimize?.let { addPendingMinimizeTransition(transition, it) }
@@ -1628,7 +1658,12 @@
         }
         // Desktop Mode is showing and we're launching a new Task:
         // 1) Exit immersive if needed.
-        desktopImmersiveController.exitImmersiveIfApplicable(transition, wct, task.displayId)
+        desktopImmersiveController.exitImmersiveIfApplicable(
+            transition = transition,
+            wct = wct,
+            displayId = task.displayId,
+            reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
+        )
         // 2) minimize a Task if needed.
         val taskIdToMinimize = addAndGetMinimizeChanges(task.displayId, wct, task.taskId)
         addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize)
@@ -1653,8 +1688,11 @@
             return WindowContainerTransaction().also { wct ->
                 addMoveToDesktopChanges(wct, task)
                 // In some launches home task is moved behind new task being launched. Make sure
-                // that's not the case for launches in desktop.
-                if (task.baseIntent.flags.and(Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0) {
+                // that's not the case for launches in desktop. Also, if this launch is the first
+                // one to trigger the desktop mode (e.g., when [forceEnterDesktop()]), activate the
+                // desktop mode here.
+                if (task.baseIntent.flags.and(Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0
+                    || !isDesktopModeShowing(task.displayId)) {
                     bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
                     wct.reorder(task.token, true)
                 }
@@ -1665,7 +1703,10 @@
                 taskIdToMinimize?.let { addPendingMinimizeTransition(transition, it) }
                 addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize)
                 desktopImmersiveController.exitImmersiveIfApplicable(
-                    transition, wct, task.displayId
+                    transition,
+                    wct,
+                    task.displayId,
+                    reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH
                 )
             }
         } else if (taskRepository.isActiveTask(task.taskId)) {
@@ -2027,6 +2068,10 @@
                 if (DesktopModeStatus.shouldMaximizeWhenDragToTopEdge(context)) {
                     dragToMaximizeDesktopTask(taskInfo, taskSurface, currentDragBounds, motionEvent)
                 } else {
+                    desktopModeUiEventLogger.log(
+                        taskInfo,
+                        DesktopUiEventEnum.DESKTOP_WINDOW_APP_HEADER_DRAG_TO_FULL_SCREEN
+                    )
                     moveToFullscreenWithAnimation(
                         taskInfo,
                         position,
@@ -2035,6 +2080,10 @@
                 }
             }
             IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+                desktopModeUiEventLogger.log(
+                    taskInfo,
+                    DesktopUiEventEnum.DESKTOP_WINDOW_APP_HEADER_DRAG_TO_TILE_TO_LEFT
+                )
                 handleSnapResizingTaskOnDrag(
                     taskInfo,
                     SnapPosition.LEFT,
@@ -2046,6 +2095,10 @@
                 )
             }
             IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+                desktopModeUiEventLogger.log(
+                    taskInfo,
+                    DesktopUiEventEnum.DESKTOP_WINDOW_APP_HEADER_DRAG_TO_TILE_TO_RIGHT
+                )
                 handleSnapResizingTaskOnDrag(
                     taskInfo,
                     SnapPosition.RIGHT,
@@ -2132,16 +2185,32 @@
                 // Start a new jank interaction for the drag release to desktop window animation.
                 interactionJankMonitor.begin(taskSurface, context, handler,
                     CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE, "to_desktop")
+                desktopModeUiEventLogger.log(
+                    taskInfo,
+                    DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_DESKTOP_MODE
+                )
                 finalizeDragToDesktop(taskInfo)
             }
             IndicatorType.NO_INDICATOR,
             IndicatorType.TO_FULLSCREEN_INDICATOR -> {
+                desktopModeUiEventLogger.log(
+                    taskInfo,
+                    DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_FULL_SCREEN
+                )
                 cancelDragToDesktop(taskInfo)
             }
             IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+                desktopModeUiEventLogger.log(
+                    taskInfo,
+                    DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_SPLIT_SCREEN
+                )
                 requestSplit(taskInfo, leftOrTop = true)
             }
             IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+                desktopModeUiEventLogger.log(
+                    taskInfo,
+                    DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_SPLIT_SCREEN
+                )
                 requestSplit(taskInfo, leftOrTop = false)
             }
         }
@@ -2282,9 +2351,13 @@
         if (!Flags.enableFullyImmersiveInDesktop()) return
         val inImmersive = taskRepository.isTaskInFullImmersiveState(taskInfo.taskId)
         val requestingImmersive = taskInfo.requestingImmersive
-        if (inImmersive && !requestingImmersive) {
+        if (inImmersive && !requestingImmersive
+            && !RecentsTransitionStateListener.isRunning(recentsTransitionState)) {
             // Exit immersive if the app is no longer requesting it.
-            exitDesktopTaskFromFullImmersive(taskInfo)
+            desktopImmersiveController.moveTaskToNonImmersive(
+                taskInfo,
+                DesktopImmersiveController.ExitReason.APP_NOT_IMMERSIVE
+            )
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
index e835b2f..909a066 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
@@ -17,12 +17,10 @@
 package com.android.wm.shell.desktopmode
 
 import android.app.Activity
-import android.app.ActivityManager
+import android.app.TaskInfo
 import android.content.ComponentName
 import android.os.Bundle
 import android.view.WindowManager
-import com.android.internal.protolog.ProtoLog
-import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
 
 /**
  * A transparent activity used in the desktop mode to show the wallpaper under the freeform windows.
@@ -42,11 +40,12 @@
 
     companion object {
         private const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
-        private val wallpaperActivityComponent =
+        @JvmStatic
+        val wallpaperActivityComponent =
             ComponentName(SYSTEM_UI_PACKAGE_NAME, DesktopWallpaperActivity::class.java.name)
 
         @JvmStatic
-        fun isWallpaperTask(taskInfo: ActivityManager.RunningTaskInfo) =
+        fun isWallpaperTask(taskInfo: TaskInfo) =
             taskInfo.baseIntent.component?.let(::isWallpaperComponent) ?: false
 
         @JvmStatic
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
index 9411150..6df3302 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
@@ -119,6 +119,7 @@
                             initialBounds = null
                             boundsAnimator = null
                             interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW)
+                            interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW)
                             interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_SNAP_RESIZE)
                         }
                     )
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt
new file mode 100644
index 0000000..826de08
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode.compatui
+
+import android.animation.ValueAnimator
+import android.content.Context
+import android.os.IBinder
+import android.view.Display.DEFAULT_DISPLAY
+import android.view.SurfaceControl
+import android.window.TransitionInfo
+import android.window.TransitionRequestInfo
+import android.window.WindowContainerTransaction
+import androidx.core.animation.addListener
+import com.android.app.animation.Interpolators
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
+import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+import com.android.wm.shell.shared.TransitionUtil.isClosingMode
+import com.android.wm.shell.shared.TransitionUtil.isClosingType
+import com.android.wm.shell.shared.TransitionUtil.isOpeningMode
+import com.android.wm.shell.shared.TransitionUtil.isOpeningType
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.transition.Transitions.TransitionHandler
+
+/** Handles transitions related to system modals, e.g. launch and close transitions. */
+class SystemModalsTransitionHandler(
+    private val context: Context,
+    private val mainExecutor: ShellExecutor,
+    private val animExecutor: ShellExecutor,
+    private val shellInit: ShellInit,
+    private val transitions: Transitions,
+    private val desktopRepository: DesktopRepository,
+) : TransitionHandler {
+
+    private val showingSystemModalsIds = mutableSetOf<Int>()
+
+    init {
+        shellInit.addInitCallback({ transitions.addHandler(this) }, this)
+    }
+
+    override fun startAnimation(
+        transition: IBinder,
+        info: TransitionInfo,
+        startTransaction: SurfaceControl.Transaction,
+        finishTransaction: SurfaceControl.Transaction,
+        finishCallback: Transitions.TransitionFinishCallback,
+    ): Boolean {
+        if (!isDesktopModeShowing(DEFAULT_DISPLAY)) return false
+        if (isOpeningType(info.type)) {
+            val launchChange = getLaunchingSystemModal(info) ?: return false
+            val taskInfo = launchChange.taskInfo
+            requireNotNull(taskInfo)
+            logV("Animating system modal launch: taskId=%d", taskInfo.taskId)
+            showingSystemModalsIds.add(taskInfo.taskId)
+            animateSystemModal(
+                launchChange.leash,
+                startTransaction,
+                finishTransaction,
+                finishCallback,
+                /* toShow= */ true,
+            )
+            return true
+        }
+        if (isClosingType(info.type)) {
+            val closeChange = getClosingSystemModal(info) ?: return false
+            val taskInfo = closeChange.taskInfo
+            requireNotNull(taskInfo)
+            logV("Animating system modal close: taskId=%d", taskInfo.taskId)
+            showingSystemModalsIds.remove(taskInfo.taskId)
+            animateSystemModal(
+                closeChange.leash,
+                startTransaction,
+                finishTransaction,
+                finishCallback,
+                /* toShow= */ false,
+            )
+            return true
+        }
+        return false
+    }
+
+    private fun animateSystemModal(
+        leash: SurfaceControl,
+        startTransaction: SurfaceControl.Transaction,
+        finishTransaction: SurfaceControl.Transaction,
+        finishCallback: Transitions.TransitionFinishCallback,
+        toShow: Boolean, // Whether to show or to hide the system modal
+    ) {
+        val startAlpha = if (toShow) 0f else 1f
+        val endAlpha = if (toShow) 1f else 0f
+        val animator =
+            createAlphaAnimator(SurfaceControl.Transaction(), leash, startAlpha, endAlpha)
+        animator.addListener(
+            onEnd = { _ ->
+                mainExecutor.execute { finishCallback.onTransitionFinished(/* wct= */ null) }
+            }
+        )
+        if (toShow) {
+            finishTransaction.show(leash)
+        } else {
+            finishTransaction.hide(leash)
+        }
+        startTransaction.setAlpha(leash, startAlpha)
+        startTransaction.apply()
+        animExecutor.execute { animator.start() }
+    }
+
+    private fun getLaunchingSystemModal(info: TransitionInfo): TransitionInfo.Change? =
+        info.changes.find { change ->
+            if (!isOpeningMode(change.mode)) {
+                return@find false
+            }
+            val taskInfo = change.taskInfo ?: return@find false
+            return@find isTopActivityExemptFromDesktopWindowing(context, taskInfo)
+        }
+
+    private fun getClosingSystemModal(info: TransitionInfo): TransitionInfo.Change? =
+        info.changes.find { change ->
+            if (!isClosingMode(change.mode)) {
+                return@find false
+            }
+            val taskInfo = change.taskInfo ?: return@find false
+            return@find isTopActivityExemptFromDesktopWindowing(context, taskInfo) ||
+                showingSystemModalsIds.contains(taskInfo.taskId)
+        }
+
+    private fun createAlphaAnimator(
+        transaction: SurfaceControl.Transaction,
+        leash: SurfaceControl,
+        startVal: Float,
+        endVal: Float,
+    ): ValueAnimator =
+        ValueAnimator.ofFloat(startVal, endVal).apply {
+            duration = LAUNCH_ANIM_ALPHA_DURATION_MS
+            interpolator = Interpolators.LINEAR
+            addUpdateListener { animation ->
+                transaction.setAlpha(leash, animation.animatedValue as Float).apply()
+            }
+        }
+
+    private fun isDesktopModeShowing(displayId: Int): Boolean =
+        desktopRepository.getVisibleTaskCount(displayId) > 0
+
+    override fun handleRequest(
+        transition: IBinder,
+        request: TransitionRequestInfo,
+    ): WindowContainerTransaction? = null
+
+    private fun logV(msg: String, vararg arguments: Any?) {
+        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+    }
+
+    companion object {
+        private const val TAG = "SystemModalsTransitionHandler"
+        private const val LAUNCH_ANIM_ALPHA_DURATION_MS = 150L
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
index e01c448..c5fca02 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
@@ -36,8 +36,8 @@
 import com.android.wm.shell.windowdecor.common.DecorThemeUtil
 import com.android.wm.shell.windowdecor.common.Theme
 import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController
-import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipEducationViewConfig
 import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipColorScheme
+import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipEducationViewConfig
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.MainCoroutineDispatcher
@@ -74,293 +74,330 @@
     @ShellMainThread private val applicationCoroutineScope: CoroutineScope,
     @ShellBackgroundThread private val backgroundDispatcher: MainCoroutineDispatcher,
 ) {
-  private val decorThemeUtil = DecorThemeUtil(context)
-  private lateinit var openHandleMenuCallback: (Int) -> Unit
-  private lateinit var toDesktopModeCallback: (Int, DesktopModeTransitionSource) -> Unit
+    private val decorThemeUtil = DecorThemeUtil(context)
+    private lateinit var openHandleMenuCallback: (Int) -> Unit
+    private lateinit var toDesktopModeCallback: (Int, DesktopModeTransitionSource) -> Unit
 
-  init {
-    runIfEducationFeatureEnabled {
-      applicationCoroutineScope.launch {
-        // Central block handling the app handle's educational flow end-to-end.
-        isEducationViewedFlow()
-            .flatMapLatest { isEducationViewed ->
-              if (isEducationViewed) {
-                // If the education is viewed then return emptyFlow() that completes immediately.
-                // This will help us to not listen to [captionHandleStateFlow] after the education
-                // has been viewed already.
-                emptyFlow()
-              } else {
-                // Listen for changes to window decor's caption handle.
-                windowDecorCaptionHandleRepository.captionStateFlow
-                    // Wait for few seconds before emitting the latest state.
-                    .debounce(APP_HANDLE_EDUCATION_DELAY_MILLIS)
-                    .filter { captionState ->
-                      captionState is CaptionState.AppHandle &&
-                          appHandleEducationFilter.shouldShowAppHandleEducation(captionState)
+    init {
+        runIfEducationFeatureEnabled {
+            applicationCoroutineScope.launch {
+                // Central block handling the app handle's educational flow end-to-end.
+                isAppHandleHintViewedFlow()
+                    .flatMapLatest { isAppHandleHintViewed ->
+                        if (isAppHandleHintViewed) {
+                            // If the education is viewed then return emptyFlow() that completes
+                            // immediately.
+                            // This will help us to not listen to [captionHandleStateFlow] after the
+                            // education
+                            // has been viewed already.
+                            emptyFlow()
+                        } else {
+                            // Listen for changes to window decor's caption handle.
+                            windowDecorCaptionHandleRepository.captionStateFlow
+                                // Wait for few seconds before emitting the latest state.
+                                .debounce(APP_HANDLE_EDUCATION_DELAY_MILLIS)
+                                .filter { captionState ->
+                                    captionState is CaptionState.AppHandle &&
+                                        appHandleEducationFilter.shouldShowAppHandleEducation(
+                                            captionState
+                                        )
+                                }
+                        }
                     }
-              }
-            }
-            .flowOn(backgroundDispatcher)
-            .collectLatest { captionState ->
-              val tooltipColorScheme = tooltipColorScheme(captionState)
+                    .flowOn(backgroundDispatcher)
+                    .collectLatest { captionState ->
+                        val tooltipColorScheme = tooltipColorScheme(captionState)
 
-              showEducation(captionState, tooltipColorScheme)
-              // After showing first tooltip, mark education as viewed
-              appHandleEducationDatastoreRepository.updateEducationViewedTimestampMillis(true)
+                        showEducation(captionState, tooltipColorScheme)
+                        // After showing first tooltip, mark education as viewed
+                        appHandleEducationDatastoreRepository
+                            .updateAppHandleHintViewedTimestampMillis(true)
+                    }
             }
-      }
 
-      applicationCoroutineScope.launch {
-        if (isFeatureUsed()) return@launch
+            applicationCoroutineScope.launch {
+                if (isAppHandleHintUsed()) return@launch
+                windowDecorCaptionHandleRepository.captionStateFlow
+                    .filter { captionState ->
+                        captionState is CaptionState.AppHandle && captionState.isHandleMenuExpanded
+                    }
+                    .take(1)
+                    .flowOn(backgroundDispatcher)
+                    .collect {
+                        // If user expands app handle, mark user has used the app handle hint
+                        appHandleEducationDatastoreRepository
+                            .updateAppHandleHintUsedTimestampMillis(true)
+                    }
+            }
+        }
+    }
+
+    private inline fun runIfEducationFeatureEnabled(block: () -> Unit) {
+        if (canEnterDesktopMode(context) && Flags.enableDesktopWindowingAppHandleEducation())
+            block()
+    }
+
+    private fun showEducation(captionState: CaptionState, tooltipColorScheme: TooltipColorScheme) {
+        val appHandleBounds = (captionState as CaptionState.AppHandle).globalAppHandleBounds
+        val tooltipGlobalCoordinates =
+            Point(appHandleBounds.left + appHandleBounds.width() / 2, appHandleBounds.bottom)
+        // TODO: b/370546801 - Differentiate between user dismissing the tooltip vs following the
+        // cue.
+        // Populate information important to inflate app handle education tooltip.
+        val appHandleTooltipConfig =
+            TooltipEducationViewConfig(
+                tooltipViewLayout = R.layout.desktop_windowing_education_top_arrow_tooltip,
+                tooltipColorScheme = tooltipColorScheme,
+                tooltipViewGlobalCoordinates = tooltipGlobalCoordinates,
+                tooltipText = getString(R.string.windowing_app_handle_education_tooltip),
+                arrowDirection =
+                    DesktopWindowingEducationTooltipController.TooltipArrowDirection.UP,
+                onEducationClickAction = {
+                    launchWithExceptionHandling {
+                        showWindowingImageButtonTooltip(tooltipColorScheme)
+                    }
+                    openHandleMenuCallback(captionState.runningTaskInfo.taskId)
+                },
+                onDismissAction = {
+                    launchWithExceptionHandling {
+                        showWindowingImageButtonTooltip(tooltipColorScheme)
+                    }
+                },
+            )
+
+        windowingEducationViewController.showEducationTooltip(
+            tooltipViewConfig = appHandleTooltipConfig,
+            taskId = captionState.runningTaskInfo.taskId,
+        )
+    }
+
+    /** Show tooltip that points to windowing image button in app handle menu */
+    private suspend fun showWindowingImageButtonTooltip(tooltipColorScheme: TooltipColorScheme) {
+        val appInfoPillHeight = getSize(R.dimen.desktop_mode_handle_menu_app_info_pill_height)
+        val windowingOptionPillHeight =
+            getSize(R.dimen.desktop_mode_handle_menu_windowing_pill_height)
+        val appHandleMenuWidth =
+            getSize(R.dimen.desktop_mode_handle_menu_width) +
+                getSize(R.dimen.desktop_mode_handle_menu_pill_spacing_margin)
+        val appHandleMenuMargins =
+            getSize(R.dimen.desktop_mode_handle_menu_margin_top) +
+                getSize(R.dimen.desktop_mode_handle_menu_pill_spacing_margin)
+
         windowDecorCaptionHandleRepository.captionStateFlow
-            .filter { captionState ->
-              captionState is CaptionState.AppHandle && captionState.isHandleMenuExpanded
+            // After the first tooltip was dismissed, wait for 400 ms and see if the app handle menu
+            // has been expanded.
+            .timeout(APP_HANDLE_EDUCATION_TIMEOUT_MILLIS.milliseconds)
+            .catchTimeoutAndLog {
+                // TODO: b/341320146 - Log previous tooltip was dismissed
             }
+            // Wait for few milliseconds before emitting the latest state.
+            .debounce(APP_HANDLE_EDUCATION_DELAY_MILLIS)
+            .filter { captionState ->
+                // Filter out states when app handle is not visible or not expanded.
+                captionState is CaptionState.AppHandle && captionState.isHandleMenuExpanded
+            }
+            // Before showing this tooltip, stop listening to further emissions to avoid
+            // accidentally
+            // showing the same tooltip on future emissions.
             .take(1)
             .flowOn(backgroundDispatcher)
-            .collect {
-              // If user expands app handle, mark user has used the feature
-              appHandleEducationDatastoreRepository.updateFeatureUsedTimestampMillis(true)
+            .collectLatest { captionState ->
+                captionState as CaptionState.AppHandle
+                val appHandleBounds = captionState.globalAppHandleBounds
+                val tooltipGlobalCoordinates =
+                    Point(
+                        appHandleBounds.left + appHandleBounds.width() / 2 + appHandleMenuWidth / 2,
+                        appHandleBounds.top +
+                            appHandleMenuMargins +
+                            appInfoPillHeight +
+                            windowingOptionPillHeight / 2,
+                    )
+                // Populate information important to inflate windowing image button education
+                // tooltip.
+                val windowingImageButtonTooltipConfig =
+                    TooltipEducationViewConfig(
+                        tooltipViewLayout = R.layout.desktop_windowing_education_left_arrow_tooltip,
+                        tooltipColorScheme = tooltipColorScheme,
+                        tooltipViewGlobalCoordinates = tooltipGlobalCoordinates,
+                        tooltipText =
+                            getString(
+                                R.string.windowing_desktop_mode_image_button_education_tooltip
+                            ),
+                        arrowDirection =
+                            DesktopWindowingEducationTooltipController.TooltipArrowDirection.LEFT,
+                        onEducationClickAction = {
+                            launchWithExceptionHandling {
+                                showExitWindowingTooltip(tooltipColorScheme)
+                            }
+                            toDesktopModeCallback(
+                                captionState.runningTaskInfo.taskId,
+                                DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON,
+                            )
+                        },
+                        onDismissAction = {
+                            launchWithExceptionHandling {
+                                showExitWindowingTooltip(tooltipColorScheme)
+                            }
+                        },
+                    )
+
+                windowingEducationViewController.showEducationTooltip(
+                    taskId = captionState.runningTaskInfo.taskId,
+                    tooltipViewConfig = windowingImageButtonTooltipConfig,
+                )
             }
-      }
     }
-  }
 
-  private inline fun runIfEducationFeatureEnabled(block: () -> Unit) {
-    if (canEnterDesktopMode(context) && Flags.enableDesktopWindowingAppHandleEducation()) block()
-  }
+    /** Show tooltip that points to app chip button and educates user on how to exit desktop mode */
+    private suspend fun showExitWindowingTooltip(tooltipColorScheme: TooltipColorScheme) {
+        windowDecorCaptionHandleRepository.captionStateFlow
+            // After the previous tooltip was dismissed, wait for 400 ms and see if the user entered
+            // desktop mode.
+            .timeout(APP_HANDLE_EDUCATION_TIMEOUT_MILLIS.milliseconds)
+            .catchTimeoutAndLog {
+                // TODO: b/341320146 - Log previous tooltip was dismissed
+            }
+            // Wait for few milliseconds before emitting the latest state.
+            .debounce(APP_HANDLE_EDUCATION_DELAY_MILLIS)
+            .filter { captionState ->
+                // Filter out states when app header is not visible or expanded.
+                captionState is CaptionState.AppHeader && !captionState.isHeaderMenuExpanded
+            }
+            // Before showing this tooltip, stop listening to further emissions to avoid
+            // accidentally
+            // showing the same tooltip on future emissions.
+            .take(1)
+            .flowOn(backgroundDispatcher)
+            .collectLatest { captionState ->
+                captionState as CaptionState.AppHeader
+                val globalAppChipBounds = captionState.globalAppChipBounds
+                val tooltipGlobalCoordinates =
+                    Point(
+                        globalAppChipBounds.right,
+                        globalAppChipBounds.top + globalAppChipBounds.height() / 2,
+                    )
+                // Populate information important to inflate exit desktop mode education tooltip.
+                val exitWindowingTooltipConfig =
+                    TooltipEducationViewConfig(
+                        tooltipViewLayout = R.layout.desktop_windowing_education_left_arrow_tooltip,
+                        tooltipColorScheme = tooltipColorScheme,
+                        tooltipViewGlobalCoordinates = tooltipGlobalCoordinates,
+                        tooltipText =
+                            getString(R.string.windowing_desktop_mode_exit_education_tooltip),
+                        arrowDirection =
+                            DesktopWindowingEducationTooltipController.TooltipArrowDirection.LEFT,
+                        onDismissAction = {},
+                        onEducationClickAction = {
+                            openHandleMenuCallback(captionState.runningTaskInfo.taskId)
+                        },
+                    )
+                windowingEducationViewController.showEducationTooltip(
+                    taskId = captionState.runningTaskInfo.taskId,
+                    tooltipViewConfig = exitWindowingTooltipConfig,
+                )
+            }
+    }
 
-  private fun showEducation(captionState: CaptionState, tooltipColorScheme: TooltipColorScheme) {
-    val appHandleBounds = (captionState as CaptionState.AppHandle).globalAppHandleBounds
-    val tooltipGlobalCoordinates =
-        Point(appHandleBounds.left + appHandleBounds.width() / 2, appHandleBounds.bottom)
-    // TODO: b/370546801 - Differentiate between user dismissing the tooltip vs following the cue.
-    // Populate information important to inflate app handle education tooltip.
-    val appHandleTooltipConfig =
-        TooltipEducationViewConfig(
-            tooltipViewLayout = R.layout.desktop_windowing_education_top_arrow_tooltip,
-            tooltipColorScheme = tooltipColorScheme,
-            tooltipViewGlobalCoordinates = tooltipGlobalCoordinates,
-            tooltipText = getString(R.string.windowing_app_handle_education_tooltip),
-            arrowDirection = DesktopWindowingEducationTooltipController.TooltipArrowDirection.UP,
-            onEducationClickAction = {
-              launchWithExceptionHandling { showWindowingImageButtonTooltip(tooltipColorScheme) }
-              openHandleMenuCallback(captionState.runningTaskInfo.taskId)
-            },
-            onDismissAction = {
-              launchWithExceptionHandling { showWindowingImageButtonTooltip(tooltipColorScheme) }
-            },
-        )
+    private fun tooltipColorScheme(captionState: CaptionState): TooltipColorScheme {
+        context.withStyledAttributes(
+            set = null,
+            attrs =
+                intArrayOf(
+                    com.android.internal.R.attr.materialColorOnTertiaryFixed,
+                    com.android.internal.R.attr.materialColorTertiaryFixed,
+                    com.android.internal.R.attr.materialColorTertiaryFixedDim,
+                ),
+            defStyleAttr = 0,
+            defStyleRes = 0,
+        ) {
+            val onTertiaryFixed = getColor(/* index= */ 0, /* defValue= */ 0)
+            val tertiaryFixed = getColor(/* index= */ 1, /* defValue= */ 0)
+            val tertiaryFixedDim = getColor(/* index= */ 2, /* defValue= */ 0)
+            val taskInfo = (captionState as CaptionState.AppHandle).runningTaskInfo
 
-    windowingEducationViewController.showEducationTooltip(
-        tooltipViewConfig = appHandleTooltipConfig, taskId = captionState.runningTaskInfo.taskId)
-  }
-
-  /** Show tooltip that points to windowing image button in app handle menu */
-  private suspend fun showWindowingImageButtonTooltip(tooltipColorScheme: TooltipColorScheme) {
-    val appInfoPillHeight = getSize(R.dimen.desktop_mode_handle_menu_app_info_pill_height)
-    val windowingOptionPillHeight = getSize(R.dimen.desktop_mode_handle_menu_windowing_pill_height)
-    val appHandleMenuWidth =
-        getSize(R.dimen.desktop_mode_handle_menu_width) +
-            getSize(R.dimen.desktop_mode_handle_menu_pill_spacing_margin)
-    val appHandleMenuMargins =
-        getSize(R.dimen.desktop_mode_handle_menu_margin_top) +
-            getSize(R.dimen.desktop_mode_handle_menu_pill_spacing_margin)
-
-    windowDecorCaptionHandleRepository.captionStateFlow
-        // After the first tooltip was dismissed, wait for 400 ms and see if the app handle menu
-        // has been expanded.
-        .timeout(APP_HANDLE_EDUCATION_TIMEOUT_MILLIS.milliseconds)
-        .catchTimeoutAndLog {
-          // TODO: b/341320146 - Log previous tooltip was dismissed
+            val tooltipContainerColor =
+                if (decorThemeUtil.getAppTheme(taskInfo) == Theme.LIGHT) {
+                    tertiaryFixed
+                } else {
+                    tertiaryFixedDim
+                }
+            return TooltipColorScheme(tooltipContainerColor, onTertiaryFixed, onTertiaryFixed)
         }
-        // Wait for few milliseconds before emitting the latest state.
-        .debounce(APP_HANDLE_EDUCATION_DELAY_MILLIS)
-        .filter { captionState ->
-          // Filter out states when app handle is not visible or not expanded.
-          captionState is CaptionState.AppHandle && captionState.isHandleMenuExpanded
+        return TooltipColorScheme(0, 0, 0)
+    }
+
+    /**
+     * Setup callbacks for app handle education tooltips.
+     *
+     * @param openHandleMenuCallback callback invoked to open app handle menu or app chip menu.
+     * @param toDesktopModeCallback callback invoked to move task into desktop mode.
+     */
+    fun setAppHandleEducationTooltipCallbacks(
+        openHandleMenuCallback: (taskId: Int) -> Unit,
+        toDesktopModeCallback: (taskId: Int, DesktopModeTransitionSource) -> Unit,
+    ) {
+        this.openHandleMenuCallback = openHandleMenuCallback
+        this.toDesktopModeCallback = toDesktopModeCallback
+    }
+
+    private inline fun <T> Flow<T>.catchTimeoutAndLog(crossinline block: () -> Unit) =
+        catch { exception ->
+            if (exception is TimeoutCancellationException) block() else throw exception
         }
-        // Before showing this tooltip, stop listening to further emissions to avoid accidentally
-        // showing the same tooltip on future emissions.
-        .take(1)
-        .flowOn(backgroundDispatcher)
-        .collectLatest { captionState ->
-          captionState as CaptionState.AppHandle
-          val appHandleBounds = captionState.globalAppHandleBounds
-          val tooltipGlobalCoordinates =
-              Point(
-                  appHandleBounds.left + appHandleBounds.width() / 2 + appHandleMenuWidth / 2,
-                  appHandleBounds.top +
-                      appHandleMenuMargins +
-                      appInfoPillHeight +
-                      windowingOptionPillHeight / 2)
-          // Populate information important to inflate windowing image button education tooltip.
-          val windowingImageButtonTooltipConfig =
-              TooltipEducationViewConfig(
-                  tooltipViewLayout = R.layout.desktop_windowing_education_left_arrow_tooltip,
-                  tooltipColorScheme = tooltipColorScheme,
-                  tooltipViewGlobalCoordinates = tooltipGlobalCoordinates,
-                  tooltipText =
-                      getString(R.string.windowing_desktop_mode_image_button_education_tooltip),
-                  arrowDirection =
-                      DesktopWindowingEducationTooltipController.TooltipArrowDirection.LEFT,
-                  onEducationClickAction = {
-                    launchWithExceptionHandling { showExitWindowingTooltip(tooltipColorScheme) }
-                    toDesktopModeCallback(
-                        captionState.runningTaskInfo.taskId,
-                        DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON)
-                  },
-                  onDismissAction = {
-                    launchWithExceptionHandling { showExitWindowingTooltip(tooltipColorScheme) }
-                  },
-              )
 
-          windowingEducationViewController.showEducationTooltip(
-              taskId = captionState.runningTaskInfo.taskId,
-              tooltipViewConfig = windowingImageButtonTooltipConfig)
+    private fun launchWithExceptionHandling(block: suspend () -> Unit) =
+        applicationCoroutineScope.launch {
+            try {
+                block()
+            } catch (e: Throwable) {
+                Slog.e(TAG, "Error: ", e)
+            }
         }
-  }
 
-  /** Show tooltip that points to app chip button and educates user on how to exit desktop mode */
-  private suspend fun showExitWindowingTooltip(tooltipColorScheme: TooltipColorScheme) {
-    windowDecorCaptionHandleRepository.captionStateFlow
-        // After the previous tooltip was dismissed, wait for 400 ms and see if the user entered
-        // desktop mode.
-        .timeout(APP_HANDLE_EDUCATION_TIMEOUT_MILLIS.milliseconds)
-        .catchTimeoutAndLog {
-          // TODO: b/341320146 - Log previous tooltip was dismissed
-        }
-        // Wait for few milliseconds before emitting the latest state.
-        .debounce(APP_HANDLE_EDUCATION_DELAY_MILLIS)
-        .filter { captionState ->
-          // Filter out states when app header is not visible or expanded.
-          captionState is CaptionState.AppHeader && !captionState.isHeaderMenuExpanded
-        }
-        // Before showing this tooltip, stop listening to further emissions to avoid accidentally
-        // showing the same tooltip on future emissions.
-        .take(1)
-        .flowOn(backgroundDispatcher)
-        .collectLatest { captionState ->
-          captionState as CaptionState.AppHeader
-          val globalAppChipBounds = captionState.globalAppChipBounds
-          val tooltipGlobalCoordinates =
-              Point(
-                  globalAppChipBounds.right,
-                  globalAppChipBounds.top + globalAppChipBounds.height() / 2)
-          // Populate information important to inflate exit desktop mode education tooltip.
-          val exitWindowingTooltipConfig =
-              TooltipEducationViewConfig(
-                  tooltipViewLayout = R.layout.desktop_windowing_education_left_arrow_tooltip,
-                  tooltipColorScheme = tooltipColorScheme,
-                  tooltipViewGlobalCoordinates = tooltipGlobalCoordinates,
-                  tooltipText = getString(R.string.windowing_desktop_mode_exit_education_tooltip),
-                  arrowDirection =
-                      DesktopWindowingEducationTooltipController.TooltipArrowDirection.LEFT,
-                  onDismissAction = {},
-                  onEducationClickAction = {
-                    openHandleMenuCallback(captionState.runningTaskInfo.taskId)
-                  },
-              )
-          windowingEducationViewController.showEducationTooltip(
-              taskId = captionState.runningTaskInfo.taskId,
-              tooltipViewConfig = exitWindowingTooltipConfig,
-          )
-        }
-  }
+    /**
+     * Listens to the changes to [WindowingEducationProto#hasAppHandleHintViewedTimestampMillis()]
+     * in datastore proto object.
+     *
+     * If [SHOULD_OVERRIDE_EDUCATION_CONDITIONS] is true, this flow will always emit false. That
+     * means it will always emit app handle hint has not been viewed yet.
+     */
+    private fun isAppHandleHintViewedFlow(): Flow<Boolean> =
+        appHandleEducationDatastoreRepository.dataStoreFlow
+            .map { preferences ->
+                preferences.hasAppHandleHintViewedTimestampMillis() &&
+                    !SHOULD_OVERRIDE_EDUCATION_CONDITIONS
+            }
+            .distinctUntilChanged()
 
-  private fun tooltipColorScheme(captionState: CaptionState): TooltipColorScheme {
-    context.withStyledAttributes(
-        set = null,
-        attrs =
-            intArrayOf(
-                com.android.internal.R.attr.materialColorOnTertiaryFixed,
-                com.android.internal.R.attr.materialColorTertiaryFixed,
-                com.android.internal.R.attr.materialColorTertiaryFixedDim),
-        defStyleAttr = 0,
-        defStyleRes = 0) {
-          val onTertiaryFixed = getColor(/* index= */ 0, /* defValue= */ 0)
-          val tertiaryFixed = getColor(/* index= */ 1, /* defValue= */ 0)
-          val tertiaryFixedDim = getColor(/* index= */ 2, /* defValue= */ 0)
-          val taskInfo = (captionState as CaptionState.AppHandle).runningTaskInfo
+    /**
+     * Listens to the changes to [WindowingEducationProto#hasAppHandleHintUsedTimestampMillis()] in
+     * datastore proto object.
+     */
+    private suspend fun isAppHandleHintUsed(): Boolean =
+        appHandleEducationDatastoreRepository.dataStoreFlow
+            .first()
+            .hasAppHandleHintUsedTimestampMillis()
 
-          val tooltipContainerColor =
-              if (decorThemeUtil.getAppTheme(taskInfo) == Theme.LIGHT) {
-                tertiaryFixed
-              } else {
-                tertiaryFixedDim
-              }
-          return TooltipColorScheme(tooltipContainerColor, onTertiaryFixed, onTertiaryFixed)
-        }
-    return TooltipColorScheme(0, 0, 0)
-  }
+    private fun getSize(@DimenRes resourceId: Int): Int {
+        if (resourceId == Resources.ID_NULL) return 0
+        return context.resources.getDimensionPixelSize(resourceId)
+    }
 
-  /**
-   * Setup callbacks for app handle education tooltips.
-   *
-   * @param openHandleMenuCallback callback invoked to open app handle menu or app chip menu.
-   * @param toDesktopModeCallback callback invoked to move task into desktop mode.
-   */
-  fun setAppHandleEducationTooltipCallbacks(
-      openHandleMenuCallback: (taskId: Int) -> Unit,
-      toDesktopModeCallback: (taskId: Int, DesktopModeTransitionSource) -> Unit
-  ) {
-    this.openHandleMenuCallback = openHandleMenuCallback
-    this.toDesktopModeCallback = toDesktopModeCallback
-  }
+    private fun getString(@StringRes resId: Int): String = context.resources.getString(resId)
 
-  private inline fun <T> Flow<T>.catchTimeoutAndLog(crossinline block: () -> Unit) =
-      catch { exception ->
-        if (exception is TimeoutCancellationException) block() else throw exception
-      }
+    companion object {
+        const val TAG = "AppHandleEducationController"
+        val APP_HANDLE_EDUCATION_DELAY_MILLIS: Long
+            get() = SystemProperties.getLong("persist.windowing_app_handle_education_delay", 3000L)
 
-  private fun launchWithExceptionHandling(block: suspend () -> Unit) =
-      applicationCoroutineScope.launch {
-        try {
-          block()
-        } catch (e: Throwable) {
-          Slog.e(TAG, "Error: ", e)
-        }
-      }
+        val APP_HANDLE_EDUCATION_TIMEOUT_MILLIS: Long
+            get() = SystemProperties.getLong("persist.windowing_app_handle_education_timeout", 400L)
 
-  /**
-   * Listens to the changes to [WindowingEducationProto#hasEducationViewedTimestampMillis()] in
-   * datastore proto object.
-   *
-   * If [SHOULD_OVERRIDE_EDUCATION_CONDITIONS] is true, this flow will always emit false. That means
-   * it will emit education has not been viewed yet always.
-   */
-  private fun isEducationViewedFlow(): Flow<Boolean> =
-      appHandleEducationDatastoreRepository.dataStoreFlow
-          .map { preferences ->
-            preferences.hasEducationViewedTimestampMillis() && !SHOULD_OVERRIDE_EDUCATION_CONDITIONS
-          }
-          .distinctUntilChanged()
-
-  /**
-   * Listens to the changes to [WindowingEducationProto#hasFeatureUsedTimestampMillis()] in
-   * datastore proto object.
-   */
-  private suspend fun isFeatureUsed(): Boolean =
-      appHandleEducationDatastoreRepository.dataStoreFlow.first().hasFeatureUsedTimestampMillis()
-
-  private fun getSize(@DimenRes resourceId: Int): Int {
-    if (resourceId == Resources.ID_NULL) return 0
-    return context.resources.getDimensionPixelSize(resourceId)
-  }
-
-  private fun getString(@StringRes resId: Int): String = context.resources.getString(resId)
-
-  companion object {
-    const val TAG = "AppHandleEducationController"
-    val APP_HANDLE_EDUCATION_DELAY_MILLIS: Long
-      get() = SystemProperties.getLong("persist.windowing_app_handle_education_delay", 3000L)
-
-    val APP_HANDLE_EDUCATION_TIMEOUT_MILLIS: Long
-      get() = SystemProperties.getLong("persist.windowing_app_handle_education_timeout", 400L)
-
-    val SHOULD_OVERRIDE_EDUCATION_CONDITIONS: Boolean
-      get() =
-          SystemProperties.getBoolean(
-              "persist.desktop_windowing_app_handle_education_override_conditions", false)
-  }
+        val SHOULD_OVERRIDE_EDUCATION_CONDITIONS: Boolean
+            get() =
+                SystemProperties.getBoolean(
+                    "persist.desktop_windowing_app_handle_education_override_conditions",
+                    false,
+                )
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilter.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilter.kt
index 144370d..9990846 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilter.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilter.kt
@@ -32,106 +32,114 @@
 /** Filters incoming app handle education triggers based on set conditions. */
 class AppHandleEducationFilter(
     private val context: Context,
-    private val appHandleEducationDatastoreRepository: AppHandleEducationDatastoreRepository
+    private val appHandleEducationDatastoreRepository: AppHandleEducationDatastoreRepository,
 ) {
-  private val usageStatsManager =
-      context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
+    private val usageStatsManager =
+        context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
 
-  /**
-   * Returns true if conditions to show app handle education are met, returns false otherwise.
-   *
-   * If [SHOULD_OVERRIDE_EDUCATION_CONDITIONS] is true, this method will always return
-   * ![captionState.isHandleMenuExpanded].
-   */
-  suspend fun shouldShowAppHandleEducation(captionState: CaptionState): Boolean {
-    if ((captionState as CaptionState.AppHandle).isHandleMenuExpanded) return false
-    if (SHOULD_OVERRIDE_EDUCATION_CONDITIONS) return true
+    /**
+     * Returns true if conditions to show app handle education are met, returns false otherwise.
+     *
+     * If [SHOULD_OVERRIDE_EDUCATION_CONDITIONS] is true, this method will always return
+     * ![captionState.isHandleMenuExpanded].
+     */
+    suspend fun shouldShowAppHandleEducation(captionState: CaptionState): Boolean {
+        if ((captionState as CaptionState.AppHandle).isHandleMenuExpanded) return false
+        if (SHOULD_OVERRIDE_EDUCATION_CONDITIONS) return true
 
-    val focusAppPackageName =
-        captionState.runningTaskInfo.topActivityInfo?.packageName ?: return false
-    val windowingEducationProto = appHandleEducationDatastoreRepository.windowingEducationProto()
+        val focusAppPackageName =
+            captionState.runningTaskInfo.topActivityInfo?.packageName ?: return false
+        val windowingEducationProto =
+            appHandleEducationDatastoreRepository.windowingEducationProto()
 
-    return isFocusAppInAllowlist(focusAppPackageName) &&
-        !isOtherEducationShowing() &&
-        hasSufficientTimeSinceSetup() &&
-        !isEducationViewedBefore(windowingEducationProto) &&
-        !isFeatureUsedBefore(windowingEducationProto) &&
-        hasMinAppUsage(windowingEducationProto, focusAppPackageName)
-  }
+        return isFocusAppInAllowlist(focusAppPackageName) &&
+            !isOtherEducationShowing() &&
+            hasSufficientTimeSinceSetup() &&
+            !isAppHandleHintViewedBefore(windowingEducationProto) &&
+            !isAppHandleHintUsedBefore(windowingEducationProto) &&
+            hasMinAppUsage(windowingEducationProto, focusAppPackageName)
+    }
 
-  private fun isFocusAppInAllowlist(focusAppPackageName: String): Boolean =
-      focusAppPackageName in
-          context.resources.getStringArray(
-              R.array.desktop_windowing_app_handle_education_allowlist_apps)
+    private fun isFocusAppInAllowlist(focusAppPackageName: String): Boolean =
+        focusAppPackageName in
+            context.resources.getStringArray(
+                R.array.desktop_windowing_app_handle_education_allowlist_apps
+            )
 
-  // TODO: b/350953004 - Add checks based on App compat
-  // TODO: b/350951797 - Add checks based on PKT tips education
-  private fun isOtherEducationShowing(): Boolean = isTaskbarEducationShowing()
+    // TODO: b/350953004 - Add checks based on App compat
+    // TODO: b/350951797 - Add checks based on PKT tips education
+    private fun isOtherEducationShowing(): Boolean = isTaskbarEducationShowing()
 
-  private fun isTaskbarEducationShowing(): Boolean =
-      Secure.getInt(context.contentResolver, Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING, 0) == 1
+    private fun isTaskbarEducationShowing(): Boolean =
+        Secure.getInt(context.contentResolver, Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING, 0) == 1
 
-  private fun hasSufficientTimeSinceSetup(): Boolean =
-      Duration.ofMillis(SystemClock.elapsedRealtime()) >
-          convertIntegerResourceToDuration(
-              R.integer.desktop_windowing_education_required_time_since_setup_seconds)
+    private fun hasSufficientTimeSinceSetup(): Boolean =
+        Duration.ofMillis(SystemClock.elapsedRealtime()) >
+            convertIntegerResourceToDuration(
+                R.integer.desktop_windowing_education_required_time_since_setup_seconds
+            )
 
-  private fun isEducationViewedBefore(windowingEducationProto: WindowingEducationProto): Boolean =
-      windowingEducationProto.hasEducationViewedTimestampMillis()
+    private fun isAppHandleHintViewedBefore(
+        windowingEducationProto: WindowingEducationProto
+    ): Boolean = windowingEducationProto.hasAppHandleHintViewedTimestampMillis()
 
-  private fun isFeatureUsedBefore(windowingEducationProto: WindowingEducationProto): Boolean =
-      windowingEducationProto.hasFeatureUsedTimestampMillis()
+    private fun isAppHandleHintUsedBefore(
+        windowingEducationProto: WindowingEducationProto
+    ): Boolean = windowingEducationProto.hasAppHandleHintUsedTimestampMillis()
 
-  private suspend fun hasMinAppUsage(
-      windowingEducationProto: WindowingEducationProto,
-      focusAppPackageName: String
-  ): Boolean =
-      (launchCountByPackageName(windowingEducationProto)[focusAppPackageName] ?: 0) >=
-          context.resources.getInteger(R.integer.desktop_windowing_education_min_app_launch_count)
+    private suspend fun hasMinAppUsage(
+        windowingEducationProto: WindowingEducationProto,
+        focusAppPackageName: String,
+    ): Boolean =
+        (launchCountByPackageName(windowingEducationProto)[focusAppPackageName] ?: 0) >=
+            context.resources.getInteger(R.integer.desktop_windowing_education_min_app_launch_count)
 
-  private suspend fun launchCountByPackageName(
-      windowingEducationProto: WindowingEducationProto
-  ): Map<String, Int> =
-      if (isAppUsageCacheStale(windowingEducationProto)) {
-        // Query and return user stats, update cache in datastore
-        getAndCacheAppUsageStats()
-      } else {
-        // Return cached usage stats
-        windowingEducationProto.appHandleEducation.appUsageStatsMap
-      }
+    private suspend fun launchCountByPackageName(
+        windowingEducationProto: WindowingEducationProto
+    ): Map<String, Int> =
+        if (isAppUsageCacheStale(windowingEducationProto)) {
+            // Query and return user stats, update cache in datastore
+            getAndCacheAppUsageStats()
+        } else {
+            // Return cached usage stats
+            windowingEducationProto.appHandleEducation.appUsageStatsMap
+        }
 
-  private fun isAppUsageCacheStale(windowingEducationProto: WindowingEducationProto): Boolean {
-    val currentTime = currentTimeInDuration()
-    val lastUpdateTime =
-        Duration.ofMillis(
-            windowingEducationProto.appHandleEducation.appUsageStatsLastUpdateTimestampMillis)
-    val appUsageStatsCachingInterval =
-        convertIntegerResourceToDuration(
-            R.integer.desktop_windowing_education_app_usage_cache_interval_seconds)
-    return (currentTime - lastUpdateTime) > appUsageStatsCachingInterval
-  }
+    private fun isAppUsageCacheStale(windowingEducationProto: WindowingEducationProto): Boolean {
+        val currentTime = currentTimeInDuration()
+        val lastUpdateTime =
+            Duration.ofMillis(
+                windowingEducationProto.appHandleEducation.appUsageStatsLastUpdateTimestampMillis
+            )
+        val appUsageStatsCachingInterval =
+            convertIntegerResourceToDuration(
+                R.integer.desktop_windowing_education_app_usage_cache_interval_seconds
+            )
+        return (currentTime - lastUpdateTime) > appUsageStatsCachingInterval
+    }
 
-  private suspend fun getAndCacheAppUsageStats(): Map<String, Int> {
-    val currentTime = currentTimeInDuration()
-    val appUsageStats = queryAppUsageStats()
-    appHandleEducationDatastoreRepository.updateAppUsageStats(appUsageStats, currentTime)
-    return appUsageStats
-  }
+    private suspend fun getAndCacheAppUsageStats(): Map<String, Int> {
+        val currentTime = currentTimeInDuration()
+        val appUsageStats = queryAppUsageStats()
+        appHandleEducationDatastoreRepository.updateAppUsageStats(appUsageStats, currentTime)
+        return appUsageStats
+    }
 
-  private fun queryAppUsageStats(): Map<String, Int> {
-    val endTime = currentTimeInDuration()
-    val appLaunchInterval =
-        convertIntegerResourceToDuration(
-            R.integer.desktop_windowing_education_app_launch_interval_seconds)
-    val startTime = endTime - appLaunchInterval
+    private fun queryAppUsageStats(): Map<String, Int> {
+        val endTime = currentTimeInDuration()
+        val appLaunchInterval =
+            convertIntegerResourceToDuration(
+                R.integer.desktop_windowing_education_app_launch_interval_seconds
+            )
+        val startTime = endTime - appLaunchInterval
 
-    return usageStatsManager
-        .queryAndAggregateUsageStats(startTime.toMillis(), endTime.toMillis())
-        .mapValues { it.value.appLaunchCount }
-  }
+        return usageStatsManager
+            .queryAndAggregateUsageStats(startTime.toMillis(), endTime.toMillis())
+            .mapValues { it.value.appLaunchCount }
+    }
 
-  private fun convertIntegerResourceToDuration(@IntegerRes resourceId: Int): Duration =
-      Duration.ofSeconds(context.resources.getInteger(resourceId).toLong())
+    private fun convertIntegerResourceToDuration(@IntegerRes resourceId: Int): Duration =
+        Duration.ofSeconds(context.resources.getInteger(resourceId).toLong())
 
-  private fun currentTimeInDuration(): Duration = Duration.ofMillis(System.currentTimeMillis())
+    private fun currentTimeInDuration(): Duration = Duration.ofMillis(System.currentTimeMillis())
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppToWebEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppToWebEducationController.kt
index 693da81..bfe1b12 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppToWebEducationController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppToWebEducationController.kt
@@ -53,8 +53,8 @@
 /**
  * Controls App-to-Web education end to end.
  *
- * Listen to usages of App-to-Web, calls an api to check if the education
- * should be shown and controls education UI.
+ * Listen to usages of App-to-Web, calls an api to check if the education should be shown and
+ * controls education UI.
  */
 @OptIn(kotlinx.coroutines.FlowPreview::class)
 @kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -88,8 +88,9 @@
                                 .debounce(APP_TO_WEB_EDUCATION_DELAY_MILLIS)
                                 .filter { captionState ->
                                     captionState !is CaptionState.NoCaption &&
-                                            appToWebEducationFilter
-                                                .shouldShowAppToWebEducation(captionState)
+                                        appToWebEducationFilter.shouldShowAppToWebEducation(
+                                            captionState
+                                        )
                                 }
                         }
                     }
@@ -104,12 +105,12 @@
 
             applicationCoroutineScope.launch {
                 if (isFeatureUsed()) return@launch
-                windowDecorCaptionHandleRepository.appToWebUsageFlow
-                    .collect {
-                        // If user utilizes App-to-Web, mark user has used the feature
-                        appToWebEducationDatastoreRepository
-                            .updateFeatureUsedTimestampMillis(isViewed = true)
-                    }
+                windowDecorCaptionHandleRepository.appToWebUsageFlow.collect {
+                    // If user utilizes App-to-Web, mark user has used the feature
+                    appToWebEducationDatastoreRepository.updateFeatureUsedTimestampMillis(
+                        isViewed = true
+                    )
+                }
             }
         }
     }
@@ -126,10 +127,8 @@
                 val appHandleBounds = captionState.globalAppHandleBounds
                 val educationWidth =
                     loadDimensionPixelSize(R.dimen.desktop_windowing_education_promo_width)
-                educationGlobalCoordinates = Point(
-                    appHandleBounds.centerX() - educationWidth / 2,
-                    appHandleBounds.bottom
-                )
+                educationGlobalCoordinates =
+                    Point(appHandleBounds.centerX() - educationWidth / 2, appHandleBounds.bottom)
                 taskId = captionState.runningTaskInfo.taskId
             }
 
@@ -152,19 +151,22 @@
                 viewGlobalCoordinates = educationGlobalCoordinates,
                 educationText = getString(R.string.desktop_windowing_app_to_web_education_text),
                 widthId = R.dimen.desktop_windowing_education_promo_width,
-                heightId = R.dimen.desktop_windowing_education_promo_height
+                heightId = R.dimen.desktop_windowing_education_promo_height,
             )
 
         windowingEducationViewController.showEducation(
-            viewConfig = educationConfig, taskId = taskId)
+            viewConfig = educationConfig,
+            taskId = taskId,
+        )
     }
 
     private fun educationColorScheme(captionState: CaptionState): EducationColorScheme? {
-        val taskInfo: RunningTaskInfo = when (captionState) {
-            is CaptionState.AppHandle -> captionState.runningTaskInfo
-            is CaptionState.AppHeader -> captionState.runningTaskInfo
-            else -> return null
-        }
+        val taskInfo: RunningTaskInfo =
+            when (captionState) {
+                is CaptionState.AppHandle -> captionState.runningTaskInfo
+                is CaptionState.AppHeader -> captionState.runningTaskInfo
+                else -> return null
+            }
 
         val colorScheme = decorThemeUtil.getColorScheme(taskInfo)
         val tooltipContainerColor = colorScheme.surfaceBright.toArgb()
@@ -178,8 +180,7 @@
      */
     private fun isEducationViewLimitReachedFlow(): Flow<Boolean> =
         appToWebEducationDatastoreRepository.dataStoreFlow
-            .map { preferences ->
-                appToWebEducationFilter.isEducationViewLimitReached(preferences)}
+            .map { preferences -> appToWebEducationFilter.isEducationViewLimitReached(preferences) }
             .distinctUntilChanged()
 
     /**
@@ -199,9 +200,6 @@
     companion object {
         const val TAG = "AppToWebEducationController"
         val APP_TO_WEB_EDUCATION_DELAY_MILLIS: Long
-            get() = SystemProperties.getLong(
-                "persist.windowing_app_handle_education_delay",
-                3000L
-            )
+            get() = SystemProperties.getLong("persist.windowing_app_handle_education_delay", 3000L)
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppToWebEducationFilter.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppToWebEducationFilter.kt
index feee6ed..e272b54 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppToWebEducationFilter.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppToWebEducationFilter.kt
@@ -30,39 +30,41 @@
 /** Filters incoming App-to-Web education triggers based on set conditions. */
 class AppToWebEducationFilter(
     private val context: Context,
-    private val appToWebEducationDatastoreRepository: AppToWebEducationDatastoreRepository
+    private val appToWebEducationDatastoreRepository: AppToWebEducationDatastoreRepository,
 ) {
 
     /** Returns true if conditions to show App-to-web education are met, returns false otherwise. */
     suspend fun shouldShowAppToWebEducation(captionState: CaptionState): Boolean {
-        val (taskInfo: RunningTaskInfo, isCapturedLinkAvailable: Boolean) = when (captionState) {
-            is CaptionState.AppHandle ->
-                Pair(captionState.runningTaskInfo, captionState.isCapturedLinkAvailable)
-            is CaptionState.AppHeader ->
-                Pair(captionState.runningTaskInfo, captionState.isCapturedLinkAvailable)
-            else -> return false
-        }
+        val (taskInfo: RunningTaskInfo, isCapturedLinkAvailable: Boolean) =
+            when (captionState) {
+                is CaptionState.AppHandle ->
+                    Pair(captionState.runningTaskInfo, captionState.isCapturedLinkAvailable)
+                is CaptionState.AppHeader ->
+                    Pair(captionState.runningTaskInfo, captionState.isCapturedLinkAvailable)
+                else -> return false
+            }
 
         val focusAppPackageName = taskInfo.topActivityInfo?.packageName ?: return false
         val windowingEducationProto = appToWebEducationDatastoreRepository.windowingEducationProto()
 
         return !isOtherEducationShowing() &&
-                !isEducationViewLimitReached(windowingEducationProto) &&
-                hasSufficientTimeSinceSetup() &&
-                !isFeatureUsedBefore(windowingEducationProto) &&
-                isCapturedLinkAvailable &&
-                isFocusAppInAllowlist(focusAppPackageName)
+            !isEducationViewLimitReached(windowingEducationProto) &&
+            hasSufficientTimeSinceSetup() &&
+            !isFeatureUsedBefore(windowingEducationProto) &&
+            isCapturedLinkAvailable &&
+            isFocusAppInAllowlist(focusAppPackageName)
     }
 
     private fun isFocusAppInAllowlist(focusAppPackageName: String): Boolean =
         focusAppPackageName in
-                context.resources.getStringArray(
-                    R.array.desktop_windowing_app_to_web_education_allowlist_apps)
+            context.resources.getStringArray(
+                R.array.desktop_windowing_app_to_web_education_allowlist_apps
+            )
 
     // TODO: b/350953004 - Add checks based on App compat
     // TODO: b/350951797 - Add checks based on PKT tips education
-    private fun isOtherEducationShowing(): Boolean = isTaskbarEducationShowing() ||
-            isCompatUiEducationShowing()
+    private fun isOtherEducationShowing(): Boolean =
+        isTaskbarEducationShowing() || isCompatUiEducationShowing()
 
     private fun isTaskbarEducationShowing(): Boolean =
         Secure.getInt(context.contentResolver, Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING, 0) == 1
@@ -72,13 +74,14 @@
 
     private fun hasSufficientTimeSinceSetup(): Boolean =
         Duration.ofMillis(SystemClock.elapsedRealtime()) >
-                convertIntegerResourceToDuration(
-                    R.integer.desktop_windowing_education_required_time_since_setup_seconds)
+            convertIntegerResourceToDuration(
+                R.integer.desktop_windowing_education_required_time_since_setup_seconds
+            )
 
     /** Returns true if education is viewed maximum amount of times it should be shown. */
     fun isEducationViewLimitReached(windowingEducationProto: WindowingEducationProto): Boolean =
         windowingEducationProto.getAppToWebEducation().getEducationShownCount() >=
-                MAXIMUM_TIMES_EDUCATION_SHOWN
+            MAXIMUM_TIMES_EDUCATION_SHOWN
 
     private fun isFeatureUsedBefore(windowingEducationProto: WindowingEducationProto): Boolean =
         windowingEducationProto.hasFeatureUsedTimestampMillis()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt
index d21b208..3e120b0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt
@@ -42,101 +42,109 @@
 class AppHandleEducationDatastoreRepository
 @VisibleForTesting
 constructor(private val dataStore: DataStore<WindowingEducationProto>) {
-  constructor(
-      context: Context
-  ) : this(
-      DataStoreFactory.create(
-          serializer = WindowingEducationProtoSerializer,
-          produceFile = { context.dataStoreFile(APP_HANDLE_EDUCATION_DATASTORE_FILEPATH) }))
+    constructor(
+        context: Context
+    ) : this(
+        DataStoreFactory.create(
+            serializer = WindowingEducationProtoSerializer,
+            produceFile = { context.dataStoreFile(APP_HANDLE_EDUCATION_DATASTORE_FILEPATH) },
+        )
+    )
 
-  /** Provides dataStore.data flow and handles exceptions thrown during collection */
-  val dataStoreFlow: Flow<WindowingEducationProto> =
-      dataStore.data.catch { exception ->
-        // dataStore.data throws an IOException when an error is encountered when reading data
-        if (exception is IOException) {
-          Log.e(
-              TAG,
-              "Error in reading app handle education related data from datastore, data is " +
-                  "stored in a file named $APP_HANDLE_EDUCATION_DATASTORE_FILEPATH",
-              exception)
-        } else {
-          throw exception
+    /** Provides dataStore.data flow and handles exceptions thrown during collection */
+    val dataStoreFlow: Flow<WindowingEducationProto> =
+        dataStore.data.catch { exception ->
+            // dataStore.data throws an IOException when an error is encountered when reading data
+            if (exception is IOException) {
+                Log.e(
+                    TAG,
+                    "Error in reading app handle education related data from datastore, data is " +
+                        "stored in a file named $APP_HANDLE_EDUCATION_DATASTORE_FILEPATH",
+                    exception,
+                )
+            } else {
+                throw exception
+            }
         }
-      }
 
-  /**
-   * Reads and returns the [WindowingEducationProto] Proto object from the DataStore. If the
-   * DataStore is empty or there's an error reading, it returns the default value of Proto.
-   */
-  suspend fun windowingEducationProto(): WindowingEducationProto = dataStoreFlow.first()
+    /**
+     * Reads and returns the [WindowingEducationProto] Proto object from the DataStore. If the
+     * DataStore is empty or there's an error reading, it returns the default value of Proto.
+     */
+    suspend fun windowingEducationProto(): WindowingEducationProto = dataStoreFlow.first()
 
-  /**
-   * Updates [WindowingEducationProto.educationViewedTimestampMillis_] field in datastore with
-   * current timestamp if [isViewed] is true, if not then clears the field.
-   */
-  suspend fun updateEducationViewedTimestampMillis(isViewed: Boolean) {
-    dataStore.updateData { preferences ->
-      if (isViewed) {
-        preferences
-            .toBuilder()
-            .setEducationViewedTimestampMillis(System.currentTimeMillis())
-            .build()
-      } else {
-        preferences.toBuilder().clearEducationViewedTimestampMillis().build()
-      }
+    /**
+     * Updates [WindowingEducationProto.appHandleHintViewedTimestampMillis_] field in datastore with
+     * current timestamp if [isViewed] is true, if not then clears the field.
+     */
+    suspend fun updateAppHandleHintViewedTimestampMillis(isViewed: Boolean) {
+        dataStore.updateData { preferences ->
+            if (isViewed) {
+                preferences
+                    .toBuilder()
+                    .setAppHandleHintViewedTimestampMillis(System.currentTimeMillis())
+                    .build()
+            } else {
+                preferences.toBuilder().clearAppHandleHintViewedTimestampMillis().build()
+            }
+        }
     }
-  }
 
-  /**
-   * Updates [WindowingEducationProto.featureUsedTimestampMillis_] field in datastore with current
-   * timestamp if [isViewed] is true, if not then clears the field.
-   */
-  suspend fun updateFeatureUsedTimestampMillis(isViewed: Boolean) {
-    dataStore.updateData { preferences ->
-      if (isViewed) {
-        preferences.toBuilder().setFeatureUsedTimestampMillis(System.currentTimeMillis()).build()
-      } else {
-        preferences.toBuilder().clearFeatureUsedTimestampMillis().build()
-      }
+    /**
+     * Updates [WindowingEducationProto.appHandleHintUsedTimestampMillis_] field in datastore with
+     * current timestamp if [isViewed] is true, if not then clears the field.
+     */
+    suspend fun updateAppHandleHintUsedTimestampMillis(isViewed: Boolean) {
+        dataStore.updateData { preferences ->
+            if (isViewed) {
+                preferences
+                    .toBuilder()
+                    .setAppHandleHintUsedTimestampMillis(System.currentTimeMillis())
+                    .build()
+            } else {
+                preferences.toBuilder().clearAppHandleHintUsedTimestampMillis().build()
+            }
+        }
     }
-  }
 
-  /**
-   * Updates [AppHandleEducation.appUsageStats] and
-   * [AppHandleEducation.appUsageStatsLastUpdateTimestampMillis] fields in datastore with
-   * [appUsageStats] and [appUsageStatsLastUpdateTimestamp].
-   */
-  suspend fun updateAppUsageStats(
-      appUsageStats: Map<String, Int>,
-      appUsageStatsLastUpdateTimestamp: Duration
-  ) {
-    val currentAppHandleProto = windowingEducationProto().appHandleEducation.toBuilder()
-    currentAppHandleProto
-        .putAllAppUsageStats(appUsageStats)
-        .setAppUsageStatsLastUpdateTimestampMillis(appUsageStatsLastUpdateTimestamp.toMillis())
-    dataStore.updateData { preferences: WindowingEducationProto ->
-      preferences.toBuilder().setAppHandleEducation(currentAppHandleProto).build()
+    /**
+     * Updates [AppHandleEducation.appUsageStats] and
+     * [AppHandleEducation.appUsageStatsLastUpdateTimestampMillis] fields in datastore with
+     * [appUsageStats] and [appUsageStatsLastUpdateTimestamp].
+     */
+    suspend fun updateAppUsageStats(
+        appUsageStats: Map<String, Int>,
+        appUsageStatsLastUpdateTimestamp: Duration,
+    ) {
+        val currentAppHandleProto = windowingEducationProto().appHandleEducation.toBuilder()
+        currentAppHandleProto
+            .putAllAppUsageStats(appUsageStats)
+            .setAppUsageStatsLastUpdateTimestampMillis(appUsageStatsLastUpdateTimestamp.toMillis())
+        dataStore.updateData { preferences: WindowingEducationProto ->
+            preferences.toBuilder().setAppHandleEducation(currentAppHandleProto).build()
+        }
     }
-  }
 
-  companion object {
-    private const val TAG = "AppHandleEducationDatastoreRepository"
-    private const val APP_HANDLE_EDUCATION_DATASTORE_FILEPATH = "app_handle_education.pb"
+    companion object {
+        private const val TAG = "AppHandleEducationDatastoreRepository"
+        private const val APP_HANDLE_EDUCATION_DATASTORE_FILEPATH = "app_handle_education.pb"
 
-    object WindowingEducationProtoSerializer : Serializer<WindowingEducationProto> {
+        object WindowingEducationProtoSerializer : Serializer<WindowingEducationProto> {
 
-      override val defaultValue: WindowingEducationProto =
-          WindowingEducationProto.getDefaultInstance()
+            override val defaultValue: WindowingEducationProto =
+                WindowingEducationProto.getDefaultInstance()
 
-      override suspend fun readFrom(input: InputStream): WindowingEducationProto =
-          try {
-            WindowingEducationProto.parseFrom(input)
-          } catch (exception: InvalidProtocolBufferException) {
-            throw CorruptionException("Cannot read proto.", exception)
-          }
+            override suspend fun readFrom(input: InputStream): WindowingEducationProto =
+                try {
+                    WindowingEducationProto.parseFrom(input)
+                } catch (exception: InvalidProtocolBufferException) {
+                    throw CorruptionException("Cannot read proto.", exception)
+                }
 
-      override suspend fun writeTo(windowingProto: WindowingEducationProto, output: OutputStream) =
-          windowingProto.writeTo(output)
+            override suspend fun writeTo(
+                windowingProto: WindowingEducationProto,
+                output: OutputStream,
+            ) = windowingProto.writeTo(output)
+        }
     }
-  }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppToWebEducationDatastoreRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppToWebEducationDatastoreRepository.kt
index 8be6e6d..e5ad901 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppToWebEducationDatastoreRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppToWebEducationDatastoreRepository.kt
@@ -25,12 +25,12 @@
 import androidx.datastore.dataStoreFile
 import com.android.framework.protobuf.InvalidProtocolBufferException
 import com.android.internal.annotations.VisibleForTesting
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.flow.first
 import java.io.IOException
 import java.io.InputStream
 import java.io.OutputStream
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.first
 
 /** Updates data in App-to-Web's education datastore. */
 class AppToWebEducationDatastoreRepository
@@ -41,7 +41,9 @@
     ) : this(
         DataStoreFactory.create(
             serializer = WindowingEducationProtoSerializer,
-            produceFile = { context.dataStoreFile(APP_TO_WEB_EDUCATION_DATASTORE_FILEPATH) }))
+            produceFile = { context.dataStoreFile(APP_TO_WEB_EDUCATION_DATASTORE_FILEPATH) },
+        )
+    )
 
     /** Provides dataStore.data flow and handles exceptions thrown during collection */
     val dataStoreFlow: Flow<WindowingEducationProto> =
@@ -51,8 +53,10 @@
                 Slog.e(
                     TAG,
                     "Error in reading App-to-Web education related data from datastore," +
-                            "data is stored in a file named" +
-                            "$APP_TO_WEB_EDUCATION_DATASTORE_FILEPATH", exception)
+                        "data is stored in a file named" +
+                        "$APP_TO_WEB_EDUCATION_DATASTORE_FILEPATH",
+                    exception,
+                )
             } else {
                 throw exception
             }
@@ -72,26 +76,26 @@
         dataStore.updateData { preferences ->
             if (isViewed) {
                 preferences
-                    .toBuilder().setFeatureUsedTimestampMillis(System.currentTimeMillis()).build()
+                    .toBuilder()
+                    .setFeatureUsedTimestampMillis(System.currentTimeMillis())
+                    .build()
             } else {
                 preferences.toBuilder().clearFeatureUsedTimestampMillis().build()
             }
         }
     }
 
-    /**
-     * Increases [AppToWebEducation.educationShownCount] field by one.
-     */
+    /** Increases [AppToWebEducation.educationShownCount] field by one. */
     suspend fun updateEducationShownCount() {
         val currentAppHandleProto = windowingEducationProto().appToWebEducation.toBuilder()
-        currentAppHandleProto
-            .setEducationShownCount(currentAppHandleProto.getEducationShownCount() + 1)
+        currentAppHandleProto.setEducationShownCount(
+            currentAppHandleProto.getEducationShownCount() + 1
+        )
         dataStore.updateData { preferences ->
             preferences.toBuilder().setAppToWebEducation(currentAppHandleProto).build()
         }
     }
 
-
     companion object {
         private const val TAG = "AppToWebEducationDatastoreRepository"
         private const val APP_TO_WEB_EDUCATION_DATASTORE_FILEPATH = "app_to_web_education.pb"
@@ -110,7 +114,7 @@
 
             override suspend fun writeTo(
                 windowingProto: WindowingEducationProto,
-                output: OutputStream
+                output: OutputStream,
             ) = windowingProto.writeTo(output)
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/proto/windowing_education.proto b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/proto/windowing_education.proto
index 4cddd01..0c4d562 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/proto/windowing_education.proto
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/proto/windowing_education.proto
@@ -22,9 +22,19 @@
 // Desktop Windowing education data
 message WindowingEducationProto {
   // Timestamp in milliseconds of when the education was last viewed.
-  optional int64 education_viewed_timestamp_millis = 1;
+  optional int64 education_viewed_timestamp_millis = 1 [deprecated=true];
   // Timestamp in milliseconds of when the feature was last used.
-  optional int64 feature_used_timestamp_millis = 2;
+  optional int64 feature_used_timestamp_millis = 2 [deprecated=true];
+
+  // Timestamp in milliseconds of when the app handle hint was last viewed.
+  optional int64 app_handle_hint_viewed_timestamp_millis = 5;
+  // Timestamp in milliseconds of when the app handle hint was last used.
+  optional int64 app_handle_hint_used_timestamp_millis = 6;
+  // Timestamp in milliseconds of when the enter desktop mode hint was last viewed.
+  optional int64 enter_desktop_mode_hint_viewed_timestamp_millis = 7;
+  // Timestamp in milliseconds of when the exit desktop mode hint was last viewed.
+  optional int64 exit_desktop_mode_hint_viewed_timestamp_millis = 8;
+
   oneof education_data {
     // Fields specific to app handle education
     AppHandleEducation app_handle_education = 3;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index e4f8333..4c316de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -64,6 +64,7 @@
 import com.android.wm.shell.sysui.KeyguardChangeListener;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.transition.FocusTransitionObserver;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.transition.Transitions.TransitionFinishCallback;
 
@@ -89,6 +90,7 @@
 
     private final ArrayMap<IBinder, StartedTransition> mStartedTransitions = new ArrayMap<>();
     private final TaskStackListenerImpl mTaskStackListener;
+    private final FocusTransitionObserver mFocusTransitionObserver;
 
     /**
      * Local IRemoteTransition implementations registered by the keyguard service.
@@ -129,7 +131,8 @@
             @NonNull Transitions transitions,
             @NonNull TaskStackListenerImpl taskStackListener,
             @NonNull Handler mainHandler,
-            @NonNull ShellExecutor mainExecutor) {
+            @NonNull ShellExecutor mainExecutor,
+            @NonNull FocusTransitionObserver focusTransitionObserver) {
         mTransitions = transitions;
         mShellController = shellController;
         mDisplayController = displayController;
@@ -137,6 +140,7 @@
         mMainExecutor = mainExecutor;
         mTaskStackListener = taskStackListener;
         shellInit.addInitCallback(this::onInit, this);
+        mFocusTransitionObserver = focusTransitionObserver;
     }
 
     private void onInit() {
@@ -396,7 +400,8 @@
             final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
             if (taskInfo != null && taskInfo.taskId != INVALID_TASK_ID
                     && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
-                    && taskInfo.isFocused && change.getContainer() != null) {
+                    && mFocusTransitionObserver.hasGlobalFocus(taskInfo)
+                    && change.getContainer() != null) {
                 wct.setWindowingMode(change.getContainer(), WINDOWING_MODE_FULLSCREEN);
                 wct.setBounds(change.getContainer(), null);
                 return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 5276d9d..55e90e7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -324,6 +324,8 @@
         private final @AnimationType int mAnimationType;
         private final Rect mDestinationBounds = new Rect();
 
+        private final Point mLeashOffset = new Point();
+
         private T mBaseValue;
         protected T mCurrentValue;
         protected T mStartValue;
@@ -338,13 +340,22 @@
         // Flag to avoid double-end
         private boolean mHasRequestedEnd;
 
-        private PipTransitionAnimator(TaskInfo taskInfo, SurfaceControl leash,
-                @AnimationType int animationType,
-                Rect destinationBounds, T baseValue, T startValue, T endValue) {
+        private PipTransitionAnimator(@NonNull TaskInfo taskInfo, @NonNull SurfaceControl leash,
+                @AnimationType int animationType, @NonNull Rect destinationBounds,
+                @NonNull T baseValue, @NonNull T startValue, @NonNull T endValue) {
+            this(taskInfo, leash, animationType, destinationBounds, new Point(), baseValue,
+                    startValue, endValue);
+        }
+
+        private PipTransitionAnimator(@NonNull TaskInfo taskInfo, @NonNull SurfaceControl leash,
+                @AnimationType int animationType, @NonNull Rect destinationBounds,
+                @NonNull Point leashOffset, @NonNull T baseValue, @NonNull T startValue,
+                @NonNull T endValue) {
             mTaskInfo = taskInfo;
             mLeash = leash;
             mAnimationType = animationType;
             mDestinationBounds.set(destinationBounds);
+            mLeashOffset.set(leashOffset);
             mBaseValue = baseValue;
             mStartValue = startValue;
             mEndValue = endValue;
@@ -496,6 +507,15 @@
             }
         }
 
+        /**
+         * Returns the offset of the {@link #mLeash}.
+         */
+        @NonNull
+        Point getLeashOffset() {
+            // Use copy to prevent the leash to be modified unexpectedly.
+            return new Point(mLeashOffset);
+        }
+
         void setCurrentValue(T value) {
             mCurrentValue = value;
         }
@@ -692,8 +712,8 @@
             final Rect zeroInsets = new Rect(0, 0, 0, 0);
 
             // construct new Rect instances in case they are recycled
-            return new PipTransitionAnimator<Rect>(taskInfo, leash, ANIM_TYPE_BOUNDS,
-                    endBounds, new Rect(baseBounds), new Rect(startBounds), new Rect(endBounds)) {
+            return new PipTransitionAnimator<Rect>(taskInfo, leash, ANIM_TYPE_BOUNDS, endBounds,
+                    leashOffset, new Rect(baseBounds), new Rect(startBounds), new Rect(endBounds)) {
                 private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
                 private final RectEvaluator mInsetsEvaluator = new RectEvaluator(new Rect());
 
@@ -720,6 +740,7 @@
                             // Use the bounds relative to the task leash in case the leash does not
                             // start from (0, 0).
                             final Rect relativeEndBounds = new Rect(end);
+                            final Point leashOffset = getLeashOffset();
                             relativeEndBounds.offset(-leashOffset.x, -leashOffset.y);
                             getSurfaceTransactionHelper()
                                     .crop(tx, leash, relativeEndBounds)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 30f1948..fb4afe4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -26,6 +26,8 @@
 
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP;
 import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;
+import static com.android.wm.shell.desktopmode.DesktopModeUtils.calculateInitialBounds;
+import static com.android.wm.shell.desktopmode.DesktopTasksController.DESKTOP_MODE_INITIAL_BOUNDS_SCALE;
 import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA;
 import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_BOUNDS;
 import static com.android.wm.shell.pip.PipAnimationController.FRACTION_START;
@@ -152,6 +154,7 @@
     @Nullable private final PipPerfHintController mPipPerfHintController;
     private final Optional<DesktopRepository> mDesktopRepositoryOptional;
     private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
+    private final DisplayController mDisplayController;
     protected final ShellTaskOrganizer mTaskOrganizer;
     protected final ShellExecutor mMainExecutor;
 
@@ -425,6 +428,7 @@
         mPipPerfHintController = pipPerfHintControllerOptional.orElse(null);
         mDesktopRepositoryOptional = desktopRepositoryOptional;
         mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+        mDisplayController = displayController;
         mTaskOrganizer = shellTaskOrganizer;
         mMainExecutor = mainExecutor;
 
@@ -754,19 +758,30 @@
     /** Returns the bounds to restore to when exiting PIP mode. */
     // TODO(b/377581840): Instead of manually tracking bounds, use bounds from Core.
     public Rect getExitDestinationBounds() {
-        if (isPipLaunchedInDesktopMode()) {
-            final Rect freeformBounds = mDesktopRepositoryOptional.get().removeBoundsBeforeMinimize(
+        if (isPipExitingToDesktopMode()) {
+            // If we are exiting PiP while device is in Desktop mode:
+            // 1) If PiP was entered via Desktop minimize (e.g. via minimize button), restore to the
+            //    previous freeform bounds that is saved in DesktopRepository.
+            // 2) If PiP was entered through other means (e.g. user swipe up), exit to initial
+            //    freeform bounds. Note that this case has a flicker at the moment (b/379984108).
+            Rect freeformBounds = mDesktopRepositoryOptional.get().removeBoundsBeforeMinimize(
                     mTaskInfo.taskId);
-            return Objects.requireNonNullElseGet(freeformBounds, mPipBoundsState::getDisplayBounds);
+            return freeformBounds != null
+                    ? freeformBounds
+                    : calculateInitialBounds(
+                            mDisplayController.getDisplayLayout(mTaskInfo.displayId),
+                            mTaskInfo,
+                            DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
         }
         return mPipBoundsState.getDisplayBounds();
     }
 
-    /** Returns whether PiP was launched while in desktop mode. */
-    // TODO(377581840): Update this check to include non-minimized cases, e.g. split to PiP etc.
-    private boolean isPipLaunchedInDesktopMode() {
+    /** Returns whether PiP is exiting while we're in desktop mode. */
+    // TODO(b/377581840): Update this check to include non-minimized cases, e.g. split to PiP etc.
+    private boolean isPipExitingToDesktopMode() {
         return Flags.enableDesktopWindowingPip() && mDesktopRepositoryOptional.isPresent()
-                && mDesktopRepositoryOptional.get().isMinimizedTask(mTaskInfo.taskId);
+                && (mDesktopRepositoryOptional.get().getVisibleTaskCount(mTaskInfo.displayId) > 0
+                    || isDisplayInFreeform());
     }
 
     private void exitLaunchIntoPipTask(WindowContainerTransaction wct) {
@@ -1827,23 +1842,28 @@
                 == SPLIT_POSITION_TOP_OR_LEFT;
     }
 
+    private boolean isDisplayInFreeform() {
+        final DisplayAreaInfo tdaInfo = mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(
+                mTaskInfo.displayId);
+        if (tdaInfo != null) {
+            return tdaInfo.configuration.windowConfiguration.getWindowingMode()
+                    == WINDOWING_MODE_FREEFORM;
+        }
+        return false;
+    }
+
     /**
      * The windowing mode to restore to when resizing out of PIP direction. Defaults to undefined
      * and can be overridden to restore to an alternate windowing mode.
      */
     public int getOutPipWindowingMode() {
-        final DisplayAreaInfo tdaInfo = mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(
-                mTaskInfo.displayId);
-
-        // If PiP was launched while in desktop mode (we should return the task to freeform
-        // windowing mode):
+        // If we are exiting PiP while the device is in Desktop mode (the task should expand to
+        // freeform windowing mode):
         // 1) If the display windowing mode is freeform, set windowing mode to undefined so it will
         //    resolve the windowing mode to the display's windowing mode.
         // 2) If the display windowing mode is not freeform, set windowing mode to freeform.
-        if (tdaInfo != null && isPipLaunchedInDesktopMode()) {
-            final int displayWindowingMode =
-                    tdaInfo.configuration.windowConfiguration.getWindowingMode();
-            if (displayWindowingMode == WINDOWING_MODE_FREEFORM) {
+        if (isPipExitingToDesktopMode()) {
+            if (isDisplayInFreeform()) {
                 return WINDOWING_MODE_UNDEFINED;
             } else {
                 return WINDOWING_MODE_FREEFORM;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index f7aed44..0042ec9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -73,6 +73,7 @@
 import com.android.wm.shell.common.pip.PipDisplayLayoutState;
 import com.android.wm.shell.common.pip.PipMenuController;
 import com.android.wm.shell.common.pip.PipUtils;
+import com.android.wm.shell.common.split.SplitScreenUtils;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.shared.TransitionUtil;
 import com.android.wm.shell.shared.pip.PipContentOverlay;
@@ -506,8 +507,8 @@
     }
 
     @Override
-    public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds,
-            @PipAnimationController.TransitionDirection int direction,
+    public void onFinishResize(@NonNull TaskInfo taskInfo, @NonNull Rect destinationBounds,
+            @NonNull Point leashOffset, @PipAnimationController.TransitionDirection int direction,
             @NonNull SurfaceControl.Transaction tx) {
         final boolean enteringPip = isInPipDirection(direction);
         if (enteringPip) {
@@ -530,12 +531,16 @@
                 if (mFixedRotationState != FIXED_ROTATION_TRANSITION
                         && mFinishTransaction != null) {
                     mFinishTransaction.merge(tx);
-                    // Set window crop and position to destination bounds to avoid flickering.
+                    // Set crop and position to destination bounds to avoid flickering.
                     if (hasValidLeash) {
-                        mFinishTransaction.setWindowCrop(leash, destinationBounds.width(),
-                                destinationBounds.height());
-                        mFinishTransaction.setPosition(leash, destinationBounds.left,
-                                destinationBounds.top);
+                        final Rect relativeDestinationBounds = new Rect(destinationBounds);
+                        relativeDestinationBounds.offset(-leashOffset.x, -leashOffset.y);
+                        mFinishTransaction
+                                .setCrop(leash, relativeDestinationBounds)
+                                // Note that we should set the position to the start position of
+                                // leash then the visible region will be at the same place even if
+                                // the crop region doesn't start at (0, 0).
+                                .setPosition(leash, leashOffset.x, leashOffset.y);
                     }
                 }
             } else {
@@ -1266,7 +1271,8 @@
 
         mPipBoundsState.setBounds(destinationBounds);
         final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
-        onFinishResize(pipTaskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, tx);
+        onFinishResize(pipTaskInfo, destinationBounds, animator.getLeashOffset(),
+                TRANSITION_DIRECTION_TO_PIP, tx);
         sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
         if (swipePipToHomeOverlay != null) {
             mPipOrganizer.fadeOutAndRemoveOverlay(swipePipToHomeOverlay,
@@ -1346,6 +1352,13 @@
         return true;
     }
 
+    @Override
+    public boolean isPackageActiveInPip(@Nullable String packageName) {
+        final TaskInfo inPipTask = mPipOrganizer.getTaskInfo();
+        return packageName != null && inPipTask != null && mPipOrganizer.isInPip()
+                && packageName.equals(SplitScreenUtils.getPackageName(inPipTask.baseIntent));
+    }
+
     private void updatePipForUnhandledTransition(@NonNull TransitionInfo.Change pipChange,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 79a9ce5..6129651 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -31,6 +31,7 @@
 import android.app.TaskInfo;
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -92,7 +93,8 @@
                         mPipOrganizer.fadeOutAndRemoveOverlay(mPipOrganizer.mPipOverlay,
                                 null /* callback */, true /* withStartDelay*/);
                     }
-                    onFinishResize(taskInfo, animator.getDestinationBounds(), direction, tx);
+                    onFinishResize(taskInfo, animator.getDestinationBounds(),
+                            animator.getLeashOffset(), direction, tx);
                     sendOnPipTransitionFinished(direction);
                 }
 
@@ -112,9 +114,9 @@
      * Called when transition is about to finish. This is usually for performing tasks such as
      * applying WindowContainerTransaction to finalize the PiP bounds and send to the framework.
      */
-    public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds,
-            @PipAnimationController.TransitionDirection int direction,
-            SurfaceControl.Transaction tx) {
+    public void onFinishResize(@NonNull TaskInfo taskInfo, @NonNull Rect destinationBounds,
+            @NonNull Point leashOffset, @PipAnimationController.TransitionDirection int direction,
+            @NonNull SurfaceControl.Transaction tx) {
     }
 
     /**
@@ -312,9 +314,8 @@
 
     /** Whether a particular package is same as current pip package. */
     public boolean isPackageActiveInPip(@Nullable String packageName) {
-        return packageName != null
-                && mPipBoundsState.getLastPipComponentName() != null
-                && packageName.equals(mPipBoundsState.getLastPipComponentName().getPackageName());
+        // No-op, to be handled differently in PIP1 and PIP2
+        return false;
     }
 
     /** Add PiP-related changes to `outWCT` for the given request. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index 6d2df95..2c5d346 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -254,6 +254,7 @@
     @Override
     public void onConfigurationChanged(Configuration newConfiguration) {
         mPipDisplayLayoutState.onConfigurationChanged();
+        mPipTouchHandler.onConfigurationChanged();
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
index 65972fb..44cc563 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -363,12 +363,10 @@
         mMotionHelper.synchronizePinnedStackBounds();
         reloadResources();
 
-        /*
-        if (mPipTaskOrganizer.isInPip()) {
+        if (mPipTransitionState.isInPip()) {
             // Recreate the dismiss target for the new orientation.
             mPipDismissTargetHandler.createOrUpdateDismissTarget();
         }
-         */
     }
 
     void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 08e6727..8f02c1b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -31,9 +31,11 @@
 import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP;
 import static com.android.wm.shell.transition.Transitions.TRANSIT_RESIZE_PIP;
 
+import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.PictureInPictureParams;
+import android.app.TaskInfo;
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -56,6 +58,7 @@
 import com.android.wm.shell.common.pip.PipDisplayLayoutState;
 import com.android.wm.shell.common.pip.PipMenuController;
 import com.android.wm.shell.common.pip.PipUtils;
+import com.android.wm.shell.common.split.SplitScreenUtils;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
 import com.android.wm.shell.pip2.animation.PipEnterAnimator;
@@ -73,8 +76,8 @@
     private static final String TAG = PipTransition.class.getSimpleName();
 
     // Used when for ENTERING_PIP state update.
-    private static final String PIP_TASK_TOKEN = "pip_task_token";
     private static final String PIP_TASK_LEASH = "pip_task_leash";
+    private static final String PIP_TASK_INFO = "pip_task_info";
 
     // Used for PiP CHANGING_BOUNDS state update.
     static final String PIP_START_TX = "pip_start_tx";
@@ -120,6 +123,8 @@
     @Nullable
     private Transitions.TransitionFinishCallback mFinishCallback;
 
+    private ValueAnimator mTransitionAnimator;
+
     public PipTransition(
             Context context,
             @NonNull ShellInit shellInit,
@@ -209,7 +214,12 @@
     @Override
     public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
-            @NonNull Transitions.TransitionFinishCallback finishCallback) {}
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        // Just jump-cut the current animation if any, but do not merge.
+        if (info.getType() == TRANSIT_EXIT_PIP) {
+            end();
+        }
+    }
 
     @Override
     public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted,
@@ -237,8 +247,8 @@
 
             // Update the PipTransitionState while supplying the PiP leash and token to be cached.
             Bundle extra = new Bundle();
-            extra.putParcelable(PIP_TASK_TOKEN, pipChange.getContainer());
             extra.putParcelable(PIP_TASK_LEASH, pipChange.getLeash());
+            extra.putParcelable(PIP_TASK_INFO, pipChange.getTaskInfo());
             mPipTransitionState.setState(PipTransitionState.ENTERING_PIP, extra);
 
             if (isInSwipePipToHomeTransition()) {
@@ -271,6 +281,14 @@
         return false;
     }
 
+    @Override
+    public void end() {
+        if (mTransitionAnimator != null && mTransitionAnimator.isRunning()) {
+            mTransitionAnimator.end();
+            mTransitionAnimator = null;
+        }
+    }
+
     //
     // Animation schedulers and entry points
     //
@@ -355,7 +373,9 @@
 
         // Update the src-rect-hint in params in place, to set up initial animator transform.
         Rect sourceRectHint = getAdjustedSourceRectHint(info, pipChange, pipActivityChange);
-        pipChange.getTaskInfo().pictureInPictureParams.getSourceRectHint().set(sourceRectHint);
+        final PictureInPictureParams params = getPipParams(pipChange);
+        params.copyOnlySet(
+                new PictureInPictureParams.Builder().setSourceRectHint(sourceRectHint).build());
 
         // Config-at-end transitions need to have their activities transformed before starting
         // the animation; this makes the buffer seem like it's been updated to final size.
@@ -400,7 +420,7 @@
         final SurfaceControl pipLeash = getLeash(pipChange);
         final Rect startBounds = pipChange.getStartAbsBounds();
         final Rect endBounds = pipChange.getEndAbsBounds();
-        final PictureInPictureParams params = pipChange.getTaskInfo().pictureInPictureParams;
+        final PictureInPictureParams params = getPipParams(pipChange);
         final Rect adjustedSourceRectHint = getAdjustedSourceRectHint(info, pipChange,
                 pipActivityChange);
 
@@ -436,7 +456,7 @@
             }
             finishTransition();
         });
-        animator.start();
+        cacheAndStartTransitionAnimator(animator);
         return true;
     }
 
@@ -536,7 +556,7 @@
                 PipAlphaAnimator.FADE_IN);
         // This should update the pip transition state accordingly after we stop playing.
         animator.setAnimationEndCallback(this::finishTransition);
-        animator.start();
+        cacheAndStartTransitionAnimator(animator);
         return true;
     }
 
@@ -580,10 +600,10 @@
         PictureInPictureParams params = null;
         if (pipChange.getTaskInfo() != null) {
             // single activity
-            params = pipChange.getTaskInfo().pictureInPictureParams;
+            params = getPipParams(pipChange);
         } else if (parentBeforePip != null && parentBeforePip.getTaskInfo() != null) {
             // multi activity
-            params = parentBeforePip.getTaskInfo().pictureInPictureParams;
+            params = getPipParams(parentBeforePip);
         }
         final Rect sourceRectHint = PipBoundsAlgorithm.getValidSourceHintRect(params, endBounds,
                 startBounds);
@@ -606,7 +626,7 @@
             }
             finishTransition();
         });
-        animator.start();
+        cacheAndStartTransitionAnimator(animator);
         return true;
     }
 
@@ -824,9 +844,20 @@
                     initActivityPos.y);
         }
     }
+    void cacheAndStartTransitionAnimator(@NonNull ValueAnimator animator) {
+        mTransitionAnimator = animator;
+        mTransitionAnimator.start();
+    }
 
     @NonNull
-    private SurfaceControl getLeash(TransitionInfo.Change change) {
+    private static PictureInPictureParams getPipParams(@NonNull TransitionInfo.Change pipChange) {
+        return pipChange.getTaskInfo().pictureInPictureParams != null
+                ? pipChange.getTaskInfo().pictureInPictureParams
+                : new PictureInPictureParams.Builder().build();
+    }
+
+    @NonNull
+    private static SurfaceControl getLeash(TransitionInfo.Change change) {
         SurfaceControl leash = change.getLeash();
         Preconditions.checkNotNull(leash, "Leash is null for change=" + change);
         return leash;
@@ -838,11 +869,6 @@
 
     @Override
     public void finishTransition() {
-        if (mFinishCallback != null) {
-            mFinishCallback.onTransitionFinished(null /* finishWct */);
-            mFinishCallback = null;
-        }
-
         final int currentState = mPipTransitionState.getState();
         int nextState = PipTransitionState.UNDEFINED;
         switch (currentState) {
@@ -857,6 +883,14 @@
                 break;
         }
         mPipTransitionState.setState(nextState);
+
+        if (mFinishCallback != null) {
+            // Need to unset mFinishCallback first because onTransitionFinished can re-enter this
+            // handler if there is a pending PiP animation.
+            final Transitions.TransitionFinishCallback finishCallback = mFinishCallback;
+            mFinishCallback = null;
+            finishCallback.onTransitionFinished(null /* finishWct */);
+        }
     }
 
     @Override
@@ -867,10 +901,10 @@
                 Preconditions.checkState(extra != null,
                         "No extra bundle for " + mPipTransitionState);
 
-                mPipTransitionState.setPipTaskToken(extra.getParcelable(
-                        PIP_TASK_TOKEN, WindowContainerToken.class));
                 mPipTransitionState.setPinnedTaskLeash(extra.getParcelable(
                         PIP_TASK_LEASH, SurfaceControl.class));
+                mPipTransitionState.setPipTaskInfo(extra.getParcelable(
+                        PIP_TASK_INFO, TaskInfo.class));
                 boolean hasValidTokenAndLeash = mPipTransitionState.getPipTaskToken() != null
                         && mPipTransitionState.getPinnedTaskLeash() != null;
 
@@ -878,9 +912,21 @@
                         "Unexpected bundle for " + mPipTransitionState);
                 break;
             case PipTransitionState.EXITED_PIP:
-                mPipTransitionState.setPipTaskToken(null);
+                // Save the PiP bounds in case, we re-enter the PiP with the same component.
+                float snapFraction = mPipBoundsAlgorithm.getSnapFraction(
+                        mPipBoundsState.getBounds());
+                mPipBoundsState.saveReentryState(snapFraction);
+
                 mPipTransitionState.setPinnedTaskLeash(null);
+                mPipTransitionState.setPipTaskInfo(null);
                 break;
         }
     }
+
+    @Override
+    public boolean isPackageActiveInPip(@Nullable String packageName) {
+        final TaskInfo inPipTask = mPipTransitionState.getPipTaskInfo();
+        return packageName != null && inPipTask != null && mPipTransitionState.isInPip()
+                && packageName.equals(SplitScreenUtils.getPackageName(inPipTask.baseIntent));
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
index 8e90bfe..6f9f40a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
@@ -17,6 +17,7 @@
 package com.android.wm.shell.pip2.phone;
 
 import android.annotation.IntDef;
+import android.app.TaskInfo;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Handler;
@@ -133,17 +134,17 @@
     private final Rect mSwipePipToHomeAppBounds = new Rect();
 
     //
-    // Tokens and leashes
+    // Task related caches
     //
 
-    // pinned PiP task's WC token
-    @Nullable
-    private WindowContainerToken mPipTaskToken;
-
     // pinned PiP task's leash
     @Nullable
     private SurfaceControl mPinnedTaskLeash;
 
+    // pinned PiP task info
+    @Nullable
+    private TaskInfo mPipTaskInfo;
+
     // Overlay leash potentially used during swipe PiP to home transition;
     // if null while mInSwipePipToHomeTransition is true, then srcRectHint was invalid.
     @Nullable
@@ -305,11 +306,7 @@
     }
 
     @Nullable WindowContainerToken getPipTaskToken() {
-        return mPipTaskToken;
-    }
-
-    public void setPipTaskToken(@Nullable WindowContainerToken token) {
-        mPipTaskToken = token;
+        return mPipTaskInfo != null ? mPipTaskInfo.getToken() : null;
     }
 
     @Nullable SurfaceControl getPinnedTaskLeash() {
@@ -320,6 +317,14 @@
         mPinnedTaskLeash = leash;
     }
 
+    @Nullable TaskInfo getPipTaskInfo() {
+        return mPipTaskInfo;
+    }
+
+    void setPipTaskInfo(@Nullable TaskInfo pipTaskInfo) {
+        mPipTaskInfo = pipTaskInfo;
+    }
+
     /**
      * @return true if either in swipe or button-nav fixed rotation.
      */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 6da4f51..363c95f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -19,8 +19,10 @@
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.content.pm.PackageManager.FEATURE_PC;
+import static android.view.Display.INVALID_DISPLAY;
 
 import static com.android.wm.shell.Flags.enableShellTopTaskTracking;
+import static com.android.wm.shell.desktopmode.DesktopWallpaperActivity.isWallpaperTask;
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_OBSERVER;
 import static com.android.wm.shell.shared.ShellSharedConstants.KEY_EXTRA_SHELL_RECENT_TASKS;
 
@@ -53,6 +55,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.protolog.ProtoLog;
+import com.android.launcher3.Flags;
 import com.android.wm.shell.common.ExternalInterfaceBinder;
 import com.android.wm.shell.common.RemoteCallable;
 import com.android.wm.shell.common.ShellExecutor;
@@ -282,6 +285,17 @@
         notifyRecentTasksChanged();
     }
 
+    /**
+     * This method only gets notified when a task is removed from recents as a result of another
+     * task being added to recent tasks.
+     */
+    @Override
+    public void onRecentTaskRemovedForAddTask(int taskId) {
+        mDesktopRepository.ifPresent(
+                repo -> repo.removeFreeformTask(INVALID_DISPLAY, taskId)
+        );
+    }
+
     public void onTaskAdded(RunningTaskInfo taskInfo) {
         notifyRunningTaskAppeared(taskInfo);
     }
@@ -530,6 +544,10 @@
                 groupedTasks.add(GroupedTaskInfo.forSplitTasks(taskInfo, pairedTaskInfo,
                         mTaskSplitBoundsMap.get(pairedTaskId)));
             } else {
+                if (Flags.enableRefactorTaskThumbnail() && isWallpaperTask(taskInfo)) {
+                    // Don't add the wallpaper task as an entry in grouped tasks
+                    continue;
+                }
                 // TODO(346588978): Consolidate multiple visible fullscreen tasks into the same
                 //  grouped task
                 groupedTasks.add(GroupedTaskInfo.forFullscreenTasks(taskInfo));
@@ -665,8 +683,10 @@
                 }
                 mTransitionHandler.addTransitionStateListener(new RecentsTransitionStateListener() {
                     @Override
-                    public void onAnimationStateChanged(boolean running) {
-                        executor.execute(() -> listener.accept(running));
+                    public void onTransitionStateChanged(@RecentsTransitionState int state) {
+                        executor.execute(() -> {
+                            listener.accept(RecentsTransitionStateListener.isAnimating(state));
+                        });
                     }
                 });
             });
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 1c58dbb..032dac9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -32,6 +32,9 @@
 import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED;
 import static com.android.wm.shell.shared.ShellSharedConstants.KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION;
 import static com.android.wm.shell.shared.split.SplitBounds.KEY_EXTRA_SPLIT_BOUNDS;
 import static com.android.wm.shell.transition.Transitions.TRANSIT_END_RECENTS_TRANSITION;
@@ -166,13 +169,19 @@
         // only care about latest one.
         mAnimApp = appThread;
 
-        // TODO(b/366021931): Formalize this later
-        final boolean isSyntheticRequest = options.containsKey("is_synthetic_recents_transition");
-        if (isSyntheticRequest) {
-            return startSyntheticRecentsTransition(listener);
-        } else {
-            return startRealRecentsTransition(intent, fillIn, options, listener);
+        for (int i = 0; i < mStateListeners.size(); i++) {
+            mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_REQUESTED);
         }
+        // TODO(b/366021931): Formalize this later
+        final boolean isSyntheticRequest = options.getBoolean(
+                "is_synthetic_recents_transition", /* defaultValue= */ false);
+        final IBinder transition;
+        if (isSyntheticRequest) {
+            transition = startSyntheticRecentsTransition(listener);
+        } else {
+            transition = startRealRecentsTransition(intent, fillIn, options, listener);
+        }
+        return transition;
     }
 
     /**
@@ -542,7 +551,7 @@
             mPendingFinishTransition = null;
             mControllers.remove(this);
             for (int i = 0; i < mStateListeners.size(); i++) {
-                mStateListeners.get(i).onAnimationStateChanged(false);
+                mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_NOT_RUNNING);
             }
         }
 
@@ -578,7 +587,7 @@
                         new RemoteAnimationTarget[0],
                         new Rect(0, 0, 0, 0), new Rect(), new Bundle());
                 for (int i = 0; i < mStateListeners.size(); i++) {
-                    mStateListeners.get(i).onAnimationStateChanged(true);
+                    mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING);
                 }
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error starting recents animation", e);
@@ -809,7 +818,7 @@
                         wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]),
                         new Rect(0, 0, 0, 0), new Rect(), b);
                 for (int i = 0; i < mStateListeners.size(); i++) {
-                    mStateListeners.get(i).onAnimationStateChanged(true);
+                    mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING);
                 }
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error starting recents animation", e);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionStateListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionStateListener.java
index 95874c8..ea7cfd3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionStateListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionStateListener.java
@@ -16,12 +16,47 @@
 
 package com.android.wm.shell.recents;
 
-import android.os.IBinder;
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /** The listener for the events from {@link RecentsTransitionHandler}. */
 public interface RecentsTransitionStateListener {
 
-    /** Notifies whether the recents animation is running. */
-    default void onAnimationStateChanged(boolean running) {
+    @IntDef(prefix = { "TRANSITION_STATE_" }, value = {
+            TRANSITION_STATE_NOT_RUNNING,
+            TRANSITION_STATE_REQUESTED,
+            TRANSITION_STATE_ANIMATING,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface RecentsTransitionState {}
+
+    int TRANSITION_STATE_NOT_RUNNING = 1;
+    int TRANSITION_STATE_REQUESTED = 2;
+    int TRANSITION_STATE_ANIMATING = 3;
+
+    /** Notifies whether the recents transition state changes. */
+    default void onTransitionStateChanged(@RecentsTransitionState int state) {
+    }
+
+    /** Returns whether the recents transition is running. */
+    static boolean isRunning(@RecentsTransitionState int state) {
+        return state >= TRANSITION_STATE_REQUESTED;
+    }
+
+    /** Returns whether the recents transition is animating. */
+    static boolean isAnimating(@RecentsTransitionState int state) {
+        return state >= TRANSITION_STATE_ANIMATING;
+    }
+
+    /** Returns a string representation of the given state. */
+    static String stateToString(@RecentsTransitionState int state) {
+        return switch (state) {
+            case TRANSITION_STATE_NOT_RUNNING -> "TRANSITION_STATE_NOT_RUNNING";
+            case TRANSITION_STATE_REQUESTED -> "TRANSITION_STATE_REQUESTED";
+            case TRANSITION_STATE_ANIMATING -> "TRANSITION_STATE_ANIMATING";
+            default -> "UNKNOWN";
+        };
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 4f0f676..6e0e696 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -582,6 +582,7 @@
             @Nullable WindowContainerToken hideTaskToken) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                 "Legacy startTask does not support hide task token");
+        if (isTaskInSplitScreenForeground(taskId)) return;
         final int[] result = new int[1];
         IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
             @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 45ecfa9..88a9566 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -35,13 +35,11 @@
 
 import static com.android.wm.shell.Flags.enableFlexibleSplit;
 import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
-import static com.android.wm.shell.common.split.SplitScreenUtils.isPartiallyOffscreen;
 import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
 import static com.android.wm.shell.common.split.SplitScreenUtils.splitFailureMessage;
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
 import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
 import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
-import static com.android.wm.shell.shared.TransitionUtil.isOrderOnly;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_10_90;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
@@ -137,6 +135,7 @@
 import com.android.wm.shell.common.LaunchAdjacentController;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.split.OffscreenTouchZone;
 import com.android.wm.shell.common.split.SplitDecorManager;
 import com.android.wm.shell.common.split.SplitLayout;
 import com.android.wm.shell.common.split.SplitScreenUtils;
@@ -322,6 +321,20 @@
                         mSyncQueue.runInSync(t -> applyDividerVisibility(t));
                     }
                 }
+
+                @Override
+                public void inflateOnStageRoot(OffscreenTouchZone touchZone) {
+                    SurfaceControl topLeftLeash =
+                            mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
+                                    ? mMainStage.mRootLeash : mSideStage.mRootLeash;
+                    SurfaceControl bottomRightLeash =
+                            mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
+                                    ? mSideStage.mRootLeash : mMainStage.mRootLeash;
+                    touchZone.inflate(
+                            mContext.createConfigurationContext(mRootTaskInfo.configuration),
+                            mRootTaskInfo.configuration, mSyncQueue,
+                            touchZone.isTopLeft() ? topLeftLeash : bottomRightLeash);
+                }
             };
 
     protected StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
@@ -494,8 +507,15 @@
         if (enableFlexibleSplit()) {
             StageTaskListener stageToDeactivate = mStageOrderOperator.getAllStages().stream()
                     .filter(stage -> stage.getId() == stageToTop)
-                    .findFirst().orElseThrow();
-            stageToDeactivate.deactivate(wct, true /*toTop*/);
+                    .findFirst().orElse(null);
+            if (stageToDeactivate != null) {
+                stageToDeactivate.deactivate(wct, true /*toTop*/);
+            } else {
+                // If no one stage is meant to go to the top, deactivate all stages to move any
+                // child tasks out from under their respective stage root tasks.
+                mStageOrderOperator.getAllStages().forEach(stage ->
+                        stage.deactivate(wct, false /*reparentTasksToTop*/));
+            }
             mStageOrderOperator.onExitingSplit();
         } else {
             mMainStage.deactivate(wct, stageToTop == STAGE_TYPE_MAIN);
@@ -1835,13 +1855,21 @@
         }
         if (present) {
             updateRecentTasksSplitPair();
-        } else if (mMainStage.getChildCount() == 0 && mSideStage.getChildCount() == 0) {
-            mRecentTasks.ifPresent(recentTasks -> {
-                // remove the split pair mapping from recentTasks, and disable further updates
-                // to splits in the recents until we enter split again.
-                recentTasks.removeSplitPair(taskId);
-            });
-            dismissSplitScreen(-1, EXIT_REASON_ROOT_TASK_VANISHED);
+        } else {
+            // TODO (b/349828130): Test b/333270112 for flex split (launch adjacent for flex
+            //  currently not working)
+            boolean allRootsEmpty = enableFlexibleSplit()
+                    ? runForActiveStagesAllMatch(stageTaskListener ->
+                        stageTaskListener.getChildCount() == 0)
+                    : mMainStage.getChildCount() == 0 && mSideStage.getChildCount() == 0;
+            if (allRootsEmpty) {
+                mRecentTasks.ifPresent(recentTasks -> {
+                    // remove the split pair mapping from recentTasks, and disable further updates
+                    // to splits in the recents until we enter split again.
+                    recentTasks.removeSplitPair(taskId);
+                });
+                dismissSplitScreen(INVALID_TASK_ID, EXIT_REASON_ROOT_TASK_VANISHED);
+            }
         }
 
         for (int i = mListeners.size() - 1; i >= 0; --i) {
@@ -2164,11 +2192,9 @@
             mDividerFadeInAnimator.cancel();
         }
 
-        mSplitLayout.getRefDividerBounds(mTempRect1);
         if (t != null) {
+            updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
             t.setVisibility(dividerLeash, mDividerVisible);
-            t.setLayer(dividerLeash, Integer.MAX_VALUE);
-            t.setPosition(dividerLeash, mTempRect1.left, mTempRect1.top);
         } else if (mDividerVisible) {
             final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
             mDividerFadeInAnimator = ValueAnimator.ofFloat(0f, 1f);
@@ -2188,11 +2214,9 @@
                         mDividerFadeInAnimator.cancel();
                         return;
                     }
-                    mSplitLayout.getRefDividerBounds(mTempRect1);
+                    updateSurfaceBounds(mSplitLayout, transaction, false /* applyResizingOffset */);
                     transaction.show(dividerLeash);
                     transaction.setAlpha(dividerLeash, 0);
-                    transaction.setLayer(dividerLeash, Integer.MAX_VALUE);
-                    transaction.setPosition(dividerLeash, mTempRect1.left, mTempRect1.top);
                     transaction.apply();
                 }
 
@@ -2348,6 +2372,7 @@
             mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed");
         }, (finishWct, t) -> {
             mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish");
+            mSplitLayout.populateTouchZones();
         }, mainDecor, sideDecor, decorManagers);
 
         if (Flags.enableFlexibleTwoAppSplit()) {
@@ -2911,26 +2936,6 @@
                         mTaskOrganizer.applyTransaction(wct);
                     }
                     continue;
-                } else if (Flags.enableFlexibleTwoAppSplit() && isOrderOnly(change)) {
-                    int focusedStageIndex = SPLIT_INDEX_UNDEFINED;
-                    if (taskInfo.token.equals(mMainStage.mRootTaskInfo.token)) {
-                        focusedStageIndex = mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
-                                ? SPLIT_INDEX_0 : SPLIT_INDEX_1;
-                    } else if (taskInfo.token.equals(mSideStage.mRootTaskInfo.token)) {
-                        focusedStageIndex = mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
-                                ? SPLIT_INDEX_1 : SPLIT_INDEX_0;
-                    }
-
-                    if (focusedStageIndex != SPLIT_INDEX_UNDEFINED) {
-                        @PersistentSnapPosition int currentSnapPosition =
-                                mSplitLayout.calculateCurrentSnapPosition();
-                        boolean offscreenTaskFocused =
-                                isPartiallyOffscreen(focusedStageIndex, currentSnapPosition);
-
-                        if (offscreenTaskFocused) {
-                            mSplitLayout.flingDividerToOtherSide(currentSnapPosition);
-                        }
-                    }
                 }
                 final StageTaskListener stage = getStageOfTask(taskInfo);
                 if (stage == null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
index 7b71e41..4d95cde 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
@@ -23,7 +23,8 @@
 import android.view.WindowManager
 import android.window.TaskSnapshot
 import androidx.compose.ui.graphics.toArgb
-import com.android.wm.shell.shared.desktopmode.ManageWindowsViewContainer
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
+import com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer
 import com.android.wm.shell.shared.split.SplitScreenConstants
 import com.android.wm.shell.splitscreen.SplitScreenController
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
@@ -101,6 +102,7 @@
             flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                     WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
             view = menuView.rootView,
+            ignoreCutouts = DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context),
         )
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt
index dd68105..101467d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt
@@ -33,7 +33,7 @@
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.desktopmode.DesktopRepository
-import com.android.wm.shell.shared.desktopmode.ManageWindowsViewContainer
+import com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 6f33399..04ef7c1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -33,12 +33,13 @@
 import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU;
 import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions;
 import static com.android.wm.shell.compatui.AppCompatUtils.isTopActivityExemptFromDesktopWindowing;
+import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod;
 import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR;
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
-import static com.android.wm.shell.shared.desktopmode.ManageWindowsViewContainer.MANAGE_WINDOWS_MINIMUM_INSTANCES;
+import static com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer.MANAGE_WINDOWS_MINIMUM_INSTANCES;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -106,7 +107,10 @@
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.compatui.CompatUIController;
 import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler;
+import com.android.wm.shell.desktopmode.DesktopImmersiveController;
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger;
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum;
 import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator;
 import com.android.wm.shell.desktopmode.DesktopRepository;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -171,6 +175,7 @@
     private final DisplayController mDisplayController;
     private final SyncTransactionQueue mSyncQueue;
     private final DesktopTasksController mDesktopTasksController;
+    private final DesktopImmersiveController mDesktopImmersiveController;
     private final InputManager mInputManager;
     private final InteractionJankMonitor mInteractionJankMonitor;
     private final MultiInstanceHelper mMultiInstanceHelper;
@@ -227,6 +232,7 @@
     private final TaskPositionerFactory mTaskPositionerFactory;
     private final FocusTransitionObserver mFocusTransitionObserver;
     private final DesktopModeEventLogger mDesktopModeEventLogger;
+    private final DesktopModeUiEventLogger mDesktopModeUiEventLogger;
 
     public DesktopModeWindowDecorViewModel(
             Context context,
@@ -245,6 +251,7 @@
             SyncTransactionQueue syncQueue,
             Transitions transitions,
             Optional<DesktopTasksController> desktopTasksController,
+            DesktopImmersiveController desktopImmersiveController,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
             InteractionJankMonitor interactionJankMonitor,
             AppToWebGenericLinksParser genericLinksParser,
@@ -256,7 +263,8 @@
             WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
             Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
             FocusTransitionObserver focusTransitionObserver,
-            DesktopModeEventLogger desktopModeEventLogger) {
+            DesktopModeEventLogger desktopModeEventLogger,
+            DesktopModeUiEventLogger desktopModeUiEventLogger) {
         this(
                 context,
                 shellExecutor,
@@ -274,6 +282,7 @@
                 syncQueue,
                 transitions,
                 desktopTasksController,
+                desktopImmersiveController,
                 genericLinksParser,
                 assistContentRequester,
                 multiInstanceHelper,
@@ -291,7 +300,8 @@
                 activityOrientationChangeHandler,
                 new TaskPositionerFactory(),
                 focusTransitionObserver,
-                desktopModeEventLogger);
+                desktopModeEventLogger,
+                desktopModeUiEventLogger);
     }
 
     @VisibleForTesting
@@ -312,6 +322,7 @@
             SyncTransactionQueue syncQueue,
             Transitions transitions,
             Optional<DesktopTasksController> desktopTasksController,
+            DesktopImmersiveController desktopImmersiveController,
             AppToWebGenericLinksParser genericLinksParser,
             AssistContentRequester assistContentRequester,
             MultiInstanceHelper multiInstanceHelper,
@@ -329,7 +340,8 @@
             Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
             TaskPositionerFactory taskPositionerFactory,
             FocusTransitionObserver focusTransitionObserver,
-            DesktopModeEventLogger desktopModeEventLogger) {
+            DesktopModeEventLogger desktopModeEventLogger,
+            DesktopModeUiEventLogger desktopModeUiEventLogger) {
         mContext = context;
         mMainExecutor = shellExecutor;
         mMainHandler = mainHandler;
@@ -344,6 +356,7 @@
         mSyncQueue = syncQueue;
         mTransitions = transitions;
         mDesktopTasksController = desktopTasksController.get();
+        mDesktopImmersiveController = desktopImmersiveController;
         mMultiInstanceHelper = multiInstanceHelper;
         mShellCommandHandler = shellCommandHandler;
         mWindowManager = windowManager;
@@ -392,6 +405,7 @@
         mTaskPositionerFactory = taskPositionerFactory;
         mFocusTransitionObserver = focusTransitionObserver;
         mDesktopModeEventLogger = desktopModeEventLogger;
+        mDesktopModeUiEventLogger = desktopModeUiEventLogger;
 
         shellInit.addInitCallback(this::onInit, this);
     }
@@ -572,11 +586,18 @@
         if (decoration == null) {
             return;
         }
-        mInteractionJankMonitor.begin(
-                decoration.mTaskSurface, mContext, mMainHandler,
-                Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, source);
         mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo, resizeTrigger,
-                motionEvent);
+                DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent), () -> {
+                    mInteractionJankMonitor.begin(
+                            decoration.mTaskSurface, mContext, mMainHandler,
+                            Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, source);
+                    return null;
+                }, () -> {
+                    mInteractionJankMonitor.begin(
+                            decoration.mTaskSurface, mContext, mMainHandler,
+                            Cuj.CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW, source);
+                    return null;
+                });
         decoration.closeHandleMenu();
         decoration.closeMaximizeMenu();
     }
@@ -586,23 +607,40 @@
         if (decoration == null) {
             return;
         }
-        mDesktopTasksController.toggleDesktopTaskFullImmersiveState(decoration.mTaskInfo);
+        if (mDesktopRepository.isTaskInFullImmersiveState(taskId)) {
+            mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+                    DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_RESTORE);
+            mDesktopImmersiveController.moveTaskToNonImmersive(
+                    decoration.mTaskInfo, DesktopImmersiveController.ExitReason.USER_INTERACTION);
+        } else {
+            mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+                    DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_IMMERSIVE);
+            mDesktopImmersiveController.moveTaskToImmersive(decoration.mTaskInfo);
+        }
         decoration.closeMaximizeMenu();
     }
 
-    public void onSnapResize(int taskId, boolean left, @Nullable MotionEvent motionEvent) {
+    /** Snap-resize a task to the left or right side of the desktop. */
+    public void onSnapResize(int taskId, boolean left, InputMethod inputMethod, boolean fromMenu) {
         final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
         if (decoration == null) {
             return;
         }
 
+        if (fromMenu) {
+            final DesktopModeUiEventLogger.DesktopUiEventEnum event = left
+                    ? DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_TILE_TO_LEFT
+                    : DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_MENU_TAP_TO_TILE_TO_RIGHT;
+            mDesktopModeUiEventLogger.log(decoration.mTaskInfo, event);
+        }
+
         mInteractionJankMonitor.begin(decoration.mTaskSurface, mContext, mMainHandler,
                 Cuj.CUJ_DESKTOP_MODE_SNAP_RESIZE, "maximize_menu_resizable");
         mDesktopTasksController.handleInstantSnapResizingTask(
                 decoration.mTaskInfo,
                 left ? SnapPosition.LEFT : SnapPosition.RIGHT,
                 left ? ResizeTrigger.SNAP_LEFT_MENU : ResizeTrigger.SNAP_RIGHT_MENU,
-                motionEvent,
+                inputMethod,
                 decoration);
 
         decoration.closeHandleMenu();
@@ -636,6 +674,11 @@
         decoration.addCaptionInset(wct);
         mDesktopTasksController.moveTaskToDesktop(taskId, wct, source);
         decoration.closeHandleMenu();
+
+        if (source == DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON) {
+            mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+                    DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_DESKTOP_MODE);
+        }
     }
 
     private void onToFullscreen(int taskId) {
@@ -651,6 +694,8 @@
             mDesktopTasksController.moveToFullscreen(taskId,
                     DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON);
         }
+        mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+                DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_FULL_SCREEN);
     }
 
     private void onToSplitScreen(int taskId) {
@@ -663,6 +708,8 @@
         // we shouldn't receive input for it any longer.
         decoration.disposeStatusBarInputLayer();
         mDesktopTasksController.requestSplit(decoration.mTaskInfo, false /* leftOrTop */);
+        mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+                DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_SPLIT_SCREEN);
     }
 
     private void onNewWindow(int taskId) {
@@ -802,6 +849,11 @@
             } else if (id == R.id.back_button) {
                 mTaskOperations.injectBackKey(mDisplayId);
             } else if (id == R.id.caption_handle || id == R.id.open_menu_button) {
+                if (id == R.id.caption_handle && !decoration.mTaskInfo.isFreeform()) {
+                    // Clicking the App Handle.
+                    mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+                            DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_TAP);
+                }
                 if (!decoration.isHandleMenuActive()) {
                     moveTaskToFront(decoration.mTaskInfo);
                     openHandleMenu(mTaskId);
@@ -910,6 +962,8 @@
                     decoration.closeMaximizeMenu();
                 } else {
                     mHasLongClicked = true;
+                    mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+                            DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_REVEAL_MENU);
                     decoration.createMaximizeMenu();
                 }
                 return true;
@@ -1563,11 +1617,15 @@
             return Unit.INSTANCE;
         });
         windowDecoration.setOnLeftSnapClickListener(() -> {
-            onSnapResize(taskInfo.taskId, /* isLeft= */ true, touchEventListener.mMotionEvent);
+            onSnapResize(taskInfo.taskId, /* isLeft= */ true,
+                    DesktopModeEventLogger.getInputMethodFromMotionEvent(
+                            touchEventListener.mMotionEvent), /* fromMenu= */ true);
             return Unit.INSTANCE;
         });
         windowDecoration.setOnRightSnapClickListener(() -> {
-            onSnapResize(taskInfo.taskId, /* isLeft= */ false, touchEventListener.mMotionEvent);
+            onSnapResize(taskInfo.taskId, /* isLeft= */ false,
+                    DesktopModeEventLogger.getInputMethodFromMotionEvent(
+                            touchEventListener.mMotionEvent), /* fromMenu= */ true);
             return Unit.INSTANCE;
         });
         windowDecoration.setOnToDesktopClickListener(desktopModeTransitionSource -> {
@@ -1596,6 +1654,14 @@
             CompatUIController.launchUserAspectRatioSettings(mContext, taskInfo);
             return Unit.INSTANCE;
         });
+        windowDecoration.setOnMaximizeHoverListener(() -> {
+            if (!windowDecoration.isMaximizeMenuActive()) {
+                mDesktopModeUiEventLogger.log(taskInfo,
+                        DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_REVEAL_MENU);
+                windowDecoration.createMaximizeMenu();
+            }
+            return Unit.INSTANCE;
+        });
         windowDecoration.setCaptionListeners(
                 touchEventListener, touchEventListener, touchEventListener, touchEventListener);
         windowDecoration.setExclusionRegionListener(mExclusionRegionListener);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 723bbd3..96cc559 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -30,6 +30,7 @@
 
 import static com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT;
 import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopMode;
+import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopModeOrShowAppHandle;
 import static com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.DisabledEdge;
@@ -103,7 +104,7 @@
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource;
-import com.android.wm.shell.shared.desktopmode.ManageWindowsViewContainer;
+import com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
 import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder;
@@ -154,6 +155,7 @@
     private Function0<Unit> mOnNewWindowClickListener;
     private Function0<Unit> mOnManageWindowsClickListener;
     private Function0<Unit> mOnChangeAspectRatioClickListener;
+    private Function0<Unit> mOnMaximizeHoverListener;
     private DragPositioningCallback mDragPositioningCallback;
     private DragResizeInputListener mDragResizeListener;
     private Runnable mCurrentViewHostRunnable = null;
@@ -369,6 +371,11 @@
         mOnChangeAspectRatioClickListener = listener;
     }
 
+    /** Registers a listener to be called when the maximize header button is hovered. */
+    void setOnMaximizeHoverListener(Function0<Unit> listener) {
+        mOnMaximizeHoverListener = listener;
+    }
+
     void setCaptionListeners(
             View.OnClickListener onCaptionButtonClickListener,
             View.OnTouchListener onCaptionTouchListener,
@@ -840,12 +847,7 @@
                     mOnCaptionGenericMotionListener,
                     mAppName,
                     mAppIconBitmap,
-                    () -> {
-                        if (!isMaximizeMenuActive()) {
-                            createMaximizeMenu();
-                        }
-                        return Unit.INSTANCE;
-                    });
+                    mOnMaximizeHoverListener);
         }
         throw new IllegalArgumentException("Unexpected layout resource id");
     }
@@ -1397,10 +1399,11 @@
                 mAppIconBitmap,
                 mAppName,
                 mSplitScreenController,
-                canEnterDesktopMode(mContext),
+                canEnterDesktopModeOrShowAppHandle(mContext),
                 supportsMultiInstance,
                 shouldShowManageWindowsButton,
                 shouldShowChangeAspectRatioButton,
+                canEnterDesktopMode(mContext),
                 isBrowserApp,
                 isBrowserApp ? getAppLink() : getBrowserLink(),
                 mResult.mCaptionWidth,
@@ -1415,7 +1418,6 @@
         mHandleMenu.show(
                 /* onToDesktopClickListener= */ () -> {
                     mOnToDesktopClickListener.accept(APP_HANDLE_MENU_BUTTON);
-                    mOnToDesktopClickListener.accept(APP_HANDLE_MENU_BUTTON);
                     return Unit.INSTANCE;
                 },
                 /* onToFullscreenClickListener= */ mOnToFullscreenClickListener,
@@ -1457,10 +1459,13 @@
             @NonNull Function1<Integer, Unit> onIconClickListener
     ) {
         if (mTaskInfo.isFreeform()) {
+            // The menu uses display-wide coordinates for positioning, so make position the sum
+            // of task position and caption position.
+            final Rect taskBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
             mManageWindowsMenu = new DesktopHeaderManageWindowsMenu(
                     mTaskInfo,
-                    /* x= */ mResult.mCaptionX,
-                    /* y= */ mResult.mCaptionY + mResult.mCaptionTopPadding,
+                    /* x= */ taskBounds.left + mResult.mCaptionX,
+                    /* y= */ taskBounds.top + mResult.mCaptionY + mResult.mCaptionTopPadding,
                     mDisplayController,
                     mRootTaskDisplayAreaOrganizer,
                     mContext,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 4204097..a6d503d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -460,7 +460,9 @@
                                 || ctrlType == CTRL_TYPE_RIGHT || ctrlType == CTRL_TYPE_LEFT)
                                 ? ResizeTrigger.EDGE : ResizeTrigger.CORNER;
                         mDesktopModeEventLogger.logTaskResizingStarted(mResizeTrigger,
-                                e, mTaskInfo, /* displayController= */ null,
+                                DesktopModeEventLogger.getInputMethodFromMotionEvent(e),
+                                mTaskInfo, mDragStartTaskBounds.width(),
+                                mDragStartTaskBounds.height(), /* displayController= */ null,
                                 /* displayLayoutSize= */ mDisplayLayoutSizeSupplier.get());
                         // Increase the input sink region to cover the whole screen; this is to
                         // prevent input and focus from going to other tasks during a drag resize.
@@ -512,8 +514,9 @@
                         }
 
                         mDesktopModeEventLogger.logTaskResizingEnded(mResizeTrigger,
-                                mLastMotionEventOnDown, mTaskInfo, taskBounds.height(),
-                                taskBounds.width(),
+                                DesktopModeEventLogger.getInputMethodFromMotionEvent(
+                                        mLastMotionEventOnDown), mTaskInfo, taskBounds.width(),
+                                taskBounds.height(),
                                 /* displayController= */ null,
                                 /* displayLayoutSize= */ mDisplayLayoutSizeSupplier.get());
                     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
index 6f72d34..c8aff78 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
@@ -74,8 +74,7 @@
         mFineTaskCorners = new TaskCorners(mTaskSize, fineCornerSize, disabledEdge);
 
         // Save touch areas for each edge.
-        mTaskEdges = new TaskEdges(mTaskSize, mResizeHandleEdgeOutset, mResizeHandleEdgeInset,
-                mDisabledEdge);
+        mTaskEdges = new TaskEdges(mTaskSize, mResizeHandleEdgeOutset, mDisabledEdge);
     }
 
     /**
@@ -459,7 +458,7 @@
         private final @NonNull DisabledEdge mDisabledEdge;
 
         private TaskEdges(@NonNull Size taskSize, int resizeHandleThickness,
-                int resizeHandleEdgeInset, DisabledEdge disabledEdge) {
+                DisabledEdge disabledEdge) {
             // Save touch areas for each edge.
             mDisabledEdge = disabledEdge;
             // Save touch areas for each edge.
@@ -471,16 +470,16 @@
             mLeftEdgeBounds = new Rect(
                     -resizeHandleThickness,
                     0,
-                    resizeHandleEdgeInset,
+                    resizeHandleThickness,
                     taskSize.getHeight());
             mRightEdgeBounds = new Rect(
-                    taskSize.getWidth() - resizeHandleEdgeInset,
+                    taskSize.getWidth() - resizeHandleThickness,
                     0,
                     taskSize.getWidth() + resizeHandleThickness,
                     taskSize.getHeight());
             mBottomEdgeBounds = new Rect(
                     -resizeHandleThickness,
-                    taskSize.getHeight() - resizeHandleEdgeInset,
+                    taskSize.getHeight() - resizeHandleThickness,
                     taskSize.getWidth() + resizeHandleThickness,
                     taskSize.getHeight() + resizeHandleThickness);
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index 456f2c0..049b8d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -45,6 +45,7 @@
 import androidx.annotation.VisibleForTesting
 import androidx.compose.ui.graphics.toArgb
 import androidx.core.view.isGone
+import com.android.window.flags.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.apptoweb.isBrowserApp
 import com.android.wm.shell.shared.split.SplitScreenConstants
@@ -75,6 +76,7 @@
     private val shouldShowNewWindowButton: Boolean,
     private val shouldShowManageWindowsButton: Boolean,
     private val shouldShowChangeAspectRatioButton: Boolean,
+    private val shouldShowDesktopModeButton: Boolean,
     private val isBrowserApp: Boolean,
     private val openInAppOrBrowserIntent: Intent?,
     private val captionWidth: Int,
@@ -185,6 +187,7 @@
             shouldShowNewWindowButton = shouldShowNewWindowButton,
             shouldShowManageWindowsButton = shouldShowManageWindowsButton,
             shouldShowChangeAspectRatioButton = shouldShowChangeAspectRatioButton,
+            shouldShowDesktopModeButton = shouldShowDesktopModeButton,
             isBrowserApp = isBrowserApp
         ).apply {
             bind(taskInfo, appIconBitmap, appName, shouldShowMoreActionsPill)
@@ -218,7 +221,8 @@
                             WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
                             WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                     view = handleMenuView.rootView,
-                    forciblyShownTypes = if (forceShowSystemBars) { systemBars() } else { 0 }
+                    forciblyShownTypes = if (forceShowSystemBars) { systemBars() } else { 0 },
+                    ignoreCutouts = Flags.showAppHandleLargeScreens()
                 )
             } else {
                 parentDecor.addWindow(
@@ -462,6 +466,7 @@
         private val shouldShowNewWindowButton: Boolean,
         private val shouldShowManageWindowsButton: Boolean,
         private val shouldShowChangeAspectRatioButton: Boolean,
+        private val shouldShowDesktopModeButton: Boolean,
         private val isBrowserApp: Boolean
     ) {
         val rootView = LayoutInflater.from(context)
@@ -658,6 +663,7 @@
             floatingBtn.isSelected = taskInfo.isPinned
             floatingBtn.isEnabled = !taskInfo.isPinned
             floatingBtn.imageTintList = style.windowingButtonColor
+            desktopBtn.isGone = !shouldShowDesktopModeButton
             desktopBtn.isSelected = taskInfo.isFreeform
             desktopBtn.isEnabled = !taskInfo.isFreeform
             desktopBtn.imageTintList = style.windowingButtonColor
@@ -739,6 +745,7 @@
         shouldShowNewWindowButton: Boolean,
         shouldShowManageWindowsButton: Boolean,
         shouldShowChangeAspectRatioButton: Boolean,
+        shouldShowDesktopModeButton: Boolean,
         isBrowserApp: Boolean,
         openInAppOrBrowserIntent: Intent?,
         captionWidth: Int,
@@ -761,6 +768,7 @@
         shouldShowNewWindowButton: Boolean,
         shouldShowManageWindowsButton: Boolean,
         shouldShowChangeAspectRatioButton: Boolean,
+        shouldShowDesktopModeButton: Boolean,
         isBrowserApp: Boolean,
         openInAppOrBrowserIntent: Intent?,
         captionWidth: Int,
@@ -779,6 +787,7 @@
             shouldShowNewWindowButton,
             shouldShowManageWindowsButton,
             shouldShowChangeAspectRatioButton,
+            shouldShowDesktopModeButton,
             isBrowserApp,
             openInAppOrBrowserIntent,
             captionWidth,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
index 8b6aaaf..4a01e8e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
@@ -25,6 +25,7 @@
 import android.view.View
 import android.view.WindowInsets
 import android.view.WindowManager
+import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
 import com.android.wm.shell.windowdecor.WindowManagerWrapper
 
 /**
@@ -40,6 +41,7 @@
     height: Int,
     flags: Int,
     @WindowInsets.Type.InsetsType forciblyShownTypes: Int = 0,
+    ignoreCutouts: Boolean = false,
     override val view: View
 ) : AdditionalViewContainer() {
     val lp: WindowManager.LayoutParams = WindowManager.LayoutParams(
@@ -52,6 +54,10 @@
         gravity = Gravity.LEFT or Gravity.TOP
         setTrustedOverlay()
         this.forciblyShownTypes = forciblyShownTypes
+        if (ignoreCutouts) {
+            fitInsetsTypes = 0
+            layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+        }
     }
 
     constructor(
@@ -63,7 +69,8 @@
         width: Int,
         height: Int,
         flags: Int,
-        @LayoutRes layoutId: Int
+        @LayoutRes layoutId: Int,
+        ignoreCutouts: Boolean = false
     ) : this(
         windowManagerWrapper = windowManagerWrapper,
         taskId = taskId,
@@ -72,7 +79,8 @@
         width = width,
         height = height,
         flags = flags,
-        view = LayoutInflater.from(context).inflate(layoutId, null /* parent */)
+        view = LayoutInflater.from(context).inflate(layoutId, null /* parent */),
+        ignoreCutouts = ignoreCutouts
     )
 
     constructor(
@@ -83,7 +91,8 @@
         y: Int,
         width: Int,
         height: Int,
-        flags: Int
+        flags: Int,
+        ignoreCutouts: Boolean = false
     ) : this(
         windowManagerWrapper = windowManagerWrapper,
         taskId = taskId,
@@ -92,7 +101,8 @@
         width = width,
         height = height,
         flags = flags,
-        view = View(context)
+        view = View(context),
+        ignoreCutouts = ignoreCutouts
     )
 
     init {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
index 6cdc517c..5832822 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
@@ -18,10 +18,12 @@
 
 import android.content.Context
 import android.content.res.Configuration
+import android.graphics.Path
 import android.graphics.PixelFormat
 import android.graphics.Rect
 import android.graphics.Region
 import android.os.Binder
+import android.util.Size
 import android.view.LayoutInflater
 import android.view.MotionEvent
 import android.view.RoundedCorner
@@ -40,7 +42,6 @@
 import android.view.WindowlessWindowManager
 import com.android.wm.shell.R
 import com.android.wm.shell.common.SyncTransactionQueue
-import com.android.wm.shell.desktopmode.DesktopModeEventLogger
 import java.util.function.Supplier
 
 /**
@@ -48,7 +49,7 @@
  * when two tasks are tiled on left and right to resize them simultaneously.
  */
 class DesktopTilingDividerWindowManager(
-    private val config: Configuration,
+    config: Configuration,
     private val windowName: String,
     private val context: Context,
     private val leash: SurfaceControl,
@@ -61,7 +62,11 @@
     private lateinit var viewHost: SurfaceControlViewHost
     private var tilingDividerView: TilingDividerView? = null
     private var dividerShown = false
-    private var handleRegionWidth: Int = -1
+    private var handleRegionSize: Size =
+        Size(
+            context.resources.getDimensionPixelSize(R.dimen.split_divider_handle_region_width),
+            context.resources.getDimensionPixelSize(R.dimen.split_divider_handle_region_height),
+        )
     private var setTouchRegion = true
     private val maxRoundedCornerRadius = getMaxRoundedCornerRadius()
 
@@ -74,9 +79,62 @@
         rect.set(dividerBounds)
     }
 
-    /** Sets the touch region for the SurfaceControlViewHost. */
-    fun setTouchRegion(region: Rect) {
-        setTouchRegion(viewHost.windowToken.asBinder(), Region(region))
+    /**
+     * Sets the touch region for the SurfaceControlViewHost.
+     *
+     * The region includes the area around the handle (for accessibility), the divider itself and
+     * the rounded corners (to prevent click reaching windows behind).
+     */
+    fun setTouchRegion(handle: Rect, divider: Rect, cornerRadius: Float) {
+        val path = Path()
+        path.fillType = Path.FillType.WINDING
+        // The UI starts on the top-left corner, the region will be:
+        //
+        //      cornerLeft     cornerRight
+        // c1Top        +--------+
+        //              |corners |
+        // c1Bottom     +--+  +--+
+        //                 |  |
+        //       handleLeft|  |  handleRight
+        // handleTop  +----+  +----+
+        //            |  handle    |
+        // handleBot  +----+  +----+
+        //                 |  |
+        //                 |  |
+        // c2Top        +--+  +--+
+        //              |corners |
+        // c2Bottom     +--------+
+        val cornerLeft = 0f
+        val centerX = cornerRadius + divider.width() / 2f
+        val centerY = divider.height()
+        val cornerRight = divider.width() + 2 * cornerRadius
+        val handleLeft = centerX - handle.width() / 2f
+        val handleRight = handleLeft + handle.width()
+        val dividerLeft = centerY - divider.width() / 2f
+        val dividerRight = dividerLeft + divider.width()
+
+        val c1Top = 0f
+        val c1Bottom = cornerRadius
+        val handleTop = centerY - handle.height() / 2f
+        val handleBottom = handleTop + handle.height()
+        val c2Top = divider.height() - cornerRadius
+        val c2Bottom = divider.height().toFloat()
+
+        // Top corners
+        path.addRect(cornerLeft, c1Top, cornerRight, c1Bottom, Path.Direction.CCW)
+        // Bottom corners
+        path.addRect(cornerLeft, c1Top, cornerRight, c2Bottom, Path.Direction.CCW)
+        // Handle
+        path.addRect(handleLeft, handleTop, handleRight, handleBottom, Path.Direction.CCW)
+        // Divider
+        path.addRect(dividerLeft, c2Top, dividerRight, c2Bottom, Path.Direction.CCW)
+
+        val clip = Rect(handleLeft.toInt(), c1Top.toInt(), handleRight.toInt(), c2Bottom.toInt())
+
+        val region = Region()
+        region.setPath(path, Region(clip))
+
+        setTouchRegion(viewHost.windowToken.asBinder(), region)
     }
 
     /**
@@ -96,7 +154,7 @@
         surfaceControlViewHost.setView(dividerView, lp)
         val tmpDividerBounds = Rect()
         getDividerBounds(tmpDividerBounds)
-        dividerView.setup(this, tmpDividerBounds)
+        dividerView.setup(this, tmpDividerBounds, handleRegionSize)
         t.setRelativeLayer(leash, relativeLeash, 1)
             .setPosition(
                 leash,
@@ -112,7 +170,7 @@
         viewHost = surfaceControlViewHost
         dividerView.addOnLayoutChangeListener(this)
         tilingDividerView = dividerView
-        handleRegionWidth = dividerView.handleRegionWidth
+        updateTouchRegion()
     }
 
     /** Hides the divider bar. */
@@ -176,8 +234,8 @@
     private fun getWindowManagerParams(): WindowManager.LayoutParams {
         val lp =
             WindowManager.LayoutParams(
-                dividerBounds.width() + 2 * maxRoundedCornerRadius,
-                dividerBounds.height(),
+                /* w= */ dividerBounds.width() + 2 * maxRoundedCornerRadius,
+                /* h= */ dividerBounds.height(),
                 TYPE_DOCK_DIVIDER,
                 FLAG_NOT_FOCUSABLE or
                     FLAG_NOT_TOUCH_MODAL or
@@ -216,13 +274,16 @@
     ) {
         if (!setTouchRegion) return
 
-        val startX = (dividerBounds.width() - handleRegionWidth) / 2
-        val startY = 0
-        val tempRect = Rect(startX, startY, startX + handleRegionWidth, dividerBounds.height())
-        setTouchRegion(tempRect)
+        updateTouchRegion()
         setTouchRegion = false
     }
 
+    private fun updateTouchRegion() {
+        val startX = -handleRegionSize.width / 2
+        val handle = Rect(startX, 0, startX + handleRegionSize.width, dividerBounds.height())
+        setTouchRegion(handle, dividerBounds, maxRoundedCornerRadius.toFloat())
+    }
+
     private fun setSlippery(slippery: Boolean) {
         val lp = tilingDividerView?.layoutParams as WindowManager.LayoutParams
         val isSlippery = (lp.flags and FLAG_SLIPPERY) != 0
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index 418b8ec..3b5c6ca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -225,18 +225,23 @@
     fun onDividerHandleDragStart(motionEvent: MotionEvent) {
         val leftTiledTask = leftTaskResizingHelper ?: return
         val rightTiledTask = rightTaskResizingHelper ?: return
+        val inputMethod = DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent)
 
         desktopModeEventLogger.logTaskResizingStarted(
             ResizeTrigger.TILING_DIVIDER,
-            motionEvent,
+            inputMethod,
             leftTiledTask.taskInfo,
+            leftTiledTask.bounds.width(),
+            leftTiledTask.bounds.height(),
             displayController,
         )
 
         desktopModeEventLogger.logTaskResizingStarted(
             ResizeTrigger.TILING_DIVIDER,
-            motionEvent,
+            inputMethod,
             rightTiledTask.taskInfo,
+            rightTiledTask.bounds.width(),
+            rightTiledTask.bounds.height(),
             displayController,
         )
     }
@@ -296,22 +301,23 @@
     ) {
         val leftTiledTask = leftTaskResizingHelper ?: return
         val rightTiledTask = rightTaskResizingHelper ?: return
+        val inputMethod = DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent)
 
         desktopModeEventLogger.logTaskResizingEnded(
             ResizeTrigger.TILING_DIVIDER,
-            motionEvent,
+            inputMethod,
             leftTiledTask.taskInfo,
-            leftTiledTask.newBounds.height(),
             leftTiledTask.newBounds.width(),
+            leftTiledTask.newBounds.height(),
             displayController,
         )
 
         desktopModeEventLogger.logTaskResizingEnded(
             ResizeTrigger.TILING_DIVIDER,
-            motionEvent,
+            inputMethod,
             rightTiledTask.taskInfo,
-            rightTiledTask.newBounds.height(),
             rightTiledTask.newBounds.width(),
+            rightTiledTask.newBounds.height(),
             displayController,
         )
 
@@ -486,9 +492,8 @@
 
     // Only called if [taskInfo] relates to a focused task
     private fun isTilingRefocused(taskInfo: RunningTaskInfo): Boolean {
-        return !isTilingFocused &&
-            (taskInfo.taskId == leftTaskResizingHelper?.taskInfo?.taskId ||
-                taskInfo.taskId == rightTaskResizingHelper?.taskInfo?.taskId)
+        return taskInfo.taskId == leftTaskResizingHelper?.taskInfo?.taskId ||
+                taskInfo.taskId == rightTaskResizingHelper?.taskInfo?.taskId
     }
 
     private fun buildTiledTasksMoveToFront(leftOnTop: Boolean): WindowContainerTransaction {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
index 111e28e..b8e3b0f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
@@ -21,8 +21,10 @@
 import android.graphics.Rect
 import android.provider.DeviceConfig
 import android.util.AttributeSet
+import android.util.Size
 import android.view.MotionEvent
 import android.view.PointerIcon
+import android.view.RoundedCorner
 import android.view.View
 import android.view.ViewConfiguration
 import android.widget.FrameLayout
@@ -42,6 +44,7 @@
     private lateinit var callback: DividerMoveCallback
     private lateinit var handle: DividerHandleView
     private lateinit var corners: DividerRoundedCorner
+    private var cornersRadius: Int = 0
     private var touchElevation = 0
 
     private var moving = false
@@ -49,8 +52,7 @@
     var handleRegionWidth: Int = 0
     private var handleRegionHeight = 0
     private var lastAcceptedPos = 0
-    @VisibleForTesting var handleStartY = 0
-    @VisibleForTesting var handleEndY = 0
+    @VisibleForTesting var handleY: IntRange = 0..0
     private var canResize = false
     private var resized = false
     /**
@@ -79,16 +81,19 @@
     ) : super(context, attrs, defStyleAttr, defStyleRes)
 
     /** Sets up essential dependencies of the divider bar. */
-    fun setup(dividerMoveCallback: DividerMoveCallback, dividerBounds: Rect) {
+    fun setup(
+        dividerMoveCallback: DividerMoveCallback,
+        dividerBounds: Rect,
+        handleRegionSize: Size,
+    ) {
         callback = dividerMoveCallback
         this.dividerBounds.set(dividerBounds)
         handle.setIsLeftRightSplit(true)
         corners.setIsLeftRightSplit(true)
-        handleRegionHeight =
-            resources.getDimensionPixelSize(R.dimen.split_divider_handle_region_width)
-
-        handleRegionWidth =
-            resources.getDimensionPixelSize(R.dimen.split_divider_handle_region_height)
+        handleRegionHeight = handleRegionSize.height
+        handleRegionWidth = handleRegionSize.width
+        cornersRadius =
+            context.display.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT)?.radius ?: 0
         initHandleYCoordinates()
         dragDetector =
             DragDetector(
@@ -241,17 +246,17 @@
         return true
     }
 
-    private fun isWithinHandleRegion(touchYPos: Int): Boolean {
-        return touchYPos in handleStartY..handleEndY
-    }
+    private fun isWithinHandleRegion(touchYPos: Int): Boolean = touchYPos in handleY
 
     private fun initHandleYCoordinates() {
-        handleStartY = (dividerBounds.height() - handleRegionHeight) / 2
-        handleEndY = handleStartY + handleRegionHeight
+        val handleStartY = (dividerBounds.height() - handleRegionHeight) / 2
+        val handleEndY = handleStartY + handleRegionHeight
+        handleY = handleStartY..handleEndY
     }
 
     companion object {
         const val TOUCH_ANIMATION_DURATION: Long = 150
         const val TOUCH_RELEASE_ANIMATION_DURATION: Long = 200
+        private val TAG = TilingDividerView::class.java.simpleName
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
index 5f25f42..3f65d93 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
@@ -38,6 +38,7 @@
 import androidx.core.view.ViewCompat
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
 import com.android.internal.policy.SystemBarUtils
+import com.android.window.flags.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.shared.animation.Interpolators
 import com.android.wm.shell.windowdecor.WindowManagerWrapper
@@ -143,7 +144,8 @@
         if (!DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue()) return
         statusBarInputLayer = AdditionalSystemViewContainer(context, windowManagerWrapper,
             taskInfo.taskId, handlePosition.x, handlePosition.y, handleWidth, handleHeight,
-            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+            ignoreCutouts = Flags.showAppHandleLargeScreens()
         )
         val view = statusBarInputLayer?.view ?: error("Unable to find statusBarInputLayer View")
         val lp = statusBarInputLayer?.lp ?: error("Unable to find statusBarInputLayer " +
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
index 0cc8b0c..d9c36cc 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
@@ -25,6 +25,7 @@
 import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAtStart
 import android.tools.flicker.assertors.assertions.AppWindowAlignsWithOnlyOneDisplayCornerAtEnd
 import android.tools.flicker.assertors.assertions.AppWindowBecomesInvisible
+import android.tools.flicker.assertors.assertions.AppWindowBecomesPinned
 import android.tools.flicker.assertors.assertions.AppWindowBecomesTopWindow
 import android.tools.flicker.assertors.assertions.AppWindowBecomesVisible
 import android.tools.flicker.assertors.assertions.AppWindowCoversLeftHalfScreenAtEnd
@@ -465,5 +466,25 @@
                             AppWindowIsVisibleAlways(SIMPLE_APP)
                         ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
             )
+
+        val MINIMIZE_AUTO_PIP_APP =
+            FlickerConfigEntry(
+                scenarioId = ScenarioId("MINIMIZE_AUTO_PIP_APP"),
+                extractor =
+                ShellTransitionScenarioExtractor(
+                    transitionMatcher =
+                    object : ITransitionMatcher {
+                        override fun findAll(
+                            transitions: Collection<Transition>
+                        ): Collection<Transition> =
+                            transitions.filter { it.type == TransitionType.PIP }
+                    }
+                ),
+                assertions =
+                AssertionTemplates.COMMON_ASSERTIONS +
+                    listOf(
+                        AppWindowBecomesPinned(DESKTOP_MODE_APP),
+                    ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING })
+            )
     }
 }
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/MinimizeAutoPipAppWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/MinimizeAutoPipAppWindow.kt
new file mode 100644
index 0000000..b10db68
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/MinimizeAutoPipAppWindow.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.MINIMIZE_AUTO_PIP_APP
+import com.android.wm.shell.scenarios.MinimizeAutoPipAppWindow
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class MinimizeAutoPipAppWindow : MinimizeAutoPipAppWindow() {
+    @ExpectedScenarios(["MINIMIZE_AUTO_PIP_APP"])
+    @Test
+    override fun minimizePipAppWindow() = super.minimizePipAppWindow()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(MINIMIZE_AUTO_PIP_APP)
+    }
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnmaximizeAppWindowTest.kt
similarity index 61%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnmaximizeAppWindowTest.kt
index 5a04169..7a71d4b 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/UnmaximizeAppWindowTest.kt
@@ -14,8 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.wm.shell.functional
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.UnmaximizeAppWindow
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [UnmaximizeAppWindow]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class UnmaximizeAppWindowTest : UnmaximizeAppWindow()
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindowAndPip.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindowAndPip.kt
index c43a575..bb812ad 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindowAndPip.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindowAndPip.kt
@@ -45,9 +45,9 @@
     @Before
     fun setup() {
         Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+        testApp.enterDesktopMode(wmHelper, device)
         // Set string extra to ensure the app is on PiP mode at launch
         pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = mapOf("enter_pip" to "true"))
-        testApp.enterDesktopMode(wmHelper, device)
         mailApp.launchViaIntent(wmHelper)
         newTasksApp.launchViaIntent(wmHelper)
         imeApp.launchViaIntent(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindowAndPip.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindowAndPip.kt
index 0226eb3..41452c3 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindowAndPip.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindowAndPip.kt
@@ -63,9 +63,9 @@
         Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
         tapl.setEnableRotation(true)
         tapl.setExpectedRotation(rotation.value)
+        testApp.enterDesktopMode(wmHelper, device)
         // Set string extra to ensure the app is on PiP mode at launch
         pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = mapOf("enter_pip" to "true"))
-        testApp.enterDesktopMode(wmHelper, device)
         mailApp.launchViaIntent(wmHelper)
         newTasksApp.launchViaIntent(wmHelper)
         imeApp.launchViaIntent(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnmaximizeAppWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnmaximizeAppWindow.kt
new file mode 100644
index 0000000..7411250
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/UnmaximizeAppWindow.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+/**
+ * Testing "unmaximizing" a window e.g. making it get out of/exit a window that was already
+ * maximized.
+ */
+@Ignore("Test Base Class")
+abstract class UnmaximizeAppWindow
+constructor(private val rotation: Rotation = Rotation.ROTATION_0, isResizable: Boolean = true) {
+
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val device = UiDevice.getInstance(instrumentation)
+    private val testApp = if (isResizable) {
+        DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+    } else {
+        DesktopModeAppHelper(NonResizeableAppHelper(instrumentation))
+    }
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+    @Before
+    fun setup() {
+        Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+        tapl.setEnableRotation(true)
+        tapl.setExpectedRotation(rotation.value)
+        ChangeDisplayOrientationRule.setRotation(rotation)
+        testApp.enterDesktopMode(wmHelper, device)
+        // Press the buttonn once to setup app window to be maximized already
+        testApp.maximiseDesktopApp(wmHelper, device)
+    }
+
+    @Test
+    open fun unmaximizeAppWindow() {
+        // Re-press button to exit maximized state
+        testApp.maximiseDesktopApp(wmHelper, device)
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
index 176020f..6d12b00 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
@@ -49,6 +49,7 @@
         "wm-flicker-common-assertions",
         "launcher-helper-lib",
         "launcher-aosp-tapl",
+        "com_android_wm_shell_flags_lib",
     ],
 }
 
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index 6d396ea..9c71510 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
@@ -17,12 +17,16 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
 import android.tools.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.flicker.legacy.FlickerBuilder
 import android.tools.flicker.legacy.LegacyFlickerTest
 import android.tools.flicker.legacy.LegacyFlickerTestFactory
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.Flags
 import com.android.wm.shell.flicker.splitscreen.benchmark.DismissSplitScreenByGoHomeBenchmark
 import com.android.wm.shell.flicker.utils.ICommonAssertions
 import com.android.wm.shell.flicker.utils.appWindowBecomesInvisible
@@ -30,6 +34,7 @@
 import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesInvisible
 import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesInvisible
 import org.junit.FixMethodOrder
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
@@ -44,8 +49,13 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
 class DismissSplitScreenByGoHome(override val flicker: LegacyFlickerTest) :
     DismissSplitScreenByGoHomeBenchmark(flicker), ICommonAssertions {
+    @JvmField
+    @Rule
+    val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             defaultSetup(this)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
index f935ac7..310c2d7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
@@ -26,6 +26,7 @@
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.WindowConfiguration;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -42,9 +43,12 @@
     private int mParentTaskId = INVALID_TASK_ID;
     private int mUid = INVALID_TASK_ID;
     private int mTaskId = INVALID_TASK_ID;
+    private int mUserId = -1;
     private Intent mBaseIntent = new Intent();
+    private ComponentName mBaseActivity = null;
     private @WindowConfiguration.ActivityType int mActivityType = ACTIVITY_TYPE_STANDARD;
     private @WindowConfiguration.WindowingMode int mWindowingMode = WINDOWING_MODE_UNDEFINED;
+    private @WindowConfiguration.ActivityType int mTopActivityType = ACTIVITY_TYPE_STANDARD;
     private int mDisplayId = Display.DEFAULT_DISPLAY;
     private ActivityManager.TaskDescription.Builder mTaskDescriptionBuilder = null;
     private final Point mPositionInParent = new Point();
@@ -87,6 +91,12 @@
         return this;
     }
 
+    /** Sets the task info's user id. */
+    public TestRunningTaskInfoBuilder setUserId(int userId) {
+        mUserId = userId;
+        return this;
+    }
+
     /**
      * Set {@link ActivityManager.RunningTaskInfo#baseIntent} for the task info, by default
      * an empty intent is assigned
@@ -96,12 +106,26 @@
         return this;
     }
 
+    /**
+     * Set {@link ActivityManager.RunningTaskInfo#baseActivity} for the task info.
+     */
+    public TestRunningTaskInfoBuilder setBaseActivity(@NonNull ComponentName activity) {
+        mBaseActivity = activity;
+        return this;
+    }
+
     public TestRunningTaskInfoBuilder setActivityType(
             @WindowConfiguration.ActivityType int activityType) {
         mActivityType = activityType;
         return this;
     }
 
+    public TestRunningTaskInfoBuilder setTopActivityType(
+            @WindowConfiguration.ActivityType int activityType) {
+        mTopActivityType = activityType;
+        return this;
+    }
+
     public TestRunningTaskInfoBuilder setWindowingMode(
             @WindowConfiguration.WindowingMode int windowingMode) {
         mWindowingMode = windowingMode;
@@ -154,6 +178,7 @@
         info.configuration.windowConfiguration.setBounds(mBounds);
         info.configuration.windowConfiguration.setActivityType(mActivityType);
         info.configuration.windowConfiguration.setWindowingMode(mWindowingMode);
+        info.topActivityType = mTopActivityType;
         info.token = mToken;
         info.isResizeable = true;
         info.supportsMultiWindow = true;
@@ -164,6 +189,8 @@
         info.isTopActivityTransparent = mIsTopActivityTransparent;
         info.numActivities = mNumActivities;
         info.lastActiveTime = mLastActiveTime;
+        info.userId = mUserId;
+        info.baseActivity = mBaseActivity;
         return info;
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 13a8518..c3e3965 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -57,6 +57,8 @@
 import android.os.IBinder;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableContentResolver;
@@ -91,6 +93,7 @@
 import com.android.wm.shell.transition.Transitions;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -140,6 +143,8 @@
     private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
     @Mock
     private Handler mHandler;
+    @Mock
+    private Transitions.TransitionHandler mTakeoverHandler;
 
     private BackAnimationController mController;
     private TestableContentResolver mContentResolver;
@@ -152,6 +157,9 @@
 
     private BackAnimationController.BackTransitionHandler mBackTransitionHandler;
 
+    @Rule
+    public SetFlagsRule mSetflagsRule = new SetFlagsRule();
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -605,6 +613,51 @@
         verify(mAnimatorCallback, never()).onBackInvoked();
     }
 
+    @EnableFlags({com.android.systemui.shared.Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LIBRARY,
+            com.android.systemui.shared.Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LONG_LIVED,
+            com.android.window.flags.Flags.FLAG_UNIFY_BACK_NAVIGATION_TRANSITION})
+    @Test
+    public void appCallback_receivesTakeoverHandler_whenAvailable() throws RemoteException {
+        registerAnimation(BackNavigationInfo.TYPE_CROSS_TASK);
+        mBackTransitionHandler.mTakeoverHandler = mTakeoverHandler;
+
+        final int type = BackNavigationInfo.TYPE_CALLBACK;
+        final ResultListener result = new ResultListener();
+        createNavigationInfo(new BackNavigationInfo.Builder()
+                .setType(type)
+                .setOnBackInvokedCallback(mAppCallback)
+                .setOnBackNavigationDone(new RemoteCallback(result))
+                .setTouchableRegion(mTouchableRegion)
+                .setAppProgressAllowed(true));
+
+        triggerBackGesture();
+        mShellExecutor.flushAll();
+        releaseBackGesture();
+        mShellExecutor.flushAll();
+
+        verify(mAppCallback).setHandoffHandler(any());
+    }
+
+    @Test
+    public void appCallback_doesNotReceiveTakeoverHandler_whenUnavailable() throws RemoteException {
+        registerAnimation(BackNavigationInfo.TYPE_CROSS_TASK);
+
+        final int type = BackNavigationInfo.TYPE_CALLBACK;
+        final ResultListener result = new ResultListener();
+        createNavigationInfo(new BackNavigationInfo.Builder()
+                .setType(type)
+                .setOnBackInvokedCallback(mAppCallback)
+                .setOnBackNavigationDone(new RemoteCallback(result))
+                .setTouchableRegion(mTouchableRegion)
+                .setAppProgressAllowed(true));
+        triggerBackGesture();
+        mShellExecutor.flushAll();
+        releaseBackGesture();
+        mShellExecutor.flushAll();
+
+        verify(mAppCallback, never()).setHandoffHandler(any());
+    }
+
     @Test
     public void skipsCancelWithoutStart() throws RemoteException {
         final int type = BackNavigationInfo.TYPE_CALLBACK;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
index 2ed7d07..bf54e79 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
@@ -63,6 +63,7 @@
     @Before
     public void setUp() throws Exception {
         mTargetProgressCalled = new CountDownLatch(1);
+        mTargetProgress = 0.5f;
         mMainThreadHandler = new Handler(Looper.getMainLooper());
         final BackMotionEvent backEvent = backMotionEventFrom(0, 0);
         mMainThreadHandler.post(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransitionStateHolderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransitionStateHolderTest.kt
new file mode 100644
index 0000000..7b1d27a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransitionStateHolderTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.common.transition
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.server.testutils.any
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.recents.RecentsTransitionHandler
+import com.android.wm.shell.recents.RecentsTransitionStateListener
+import com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING
+import com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING
+import com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED
+import com.android.wm.shell.sysui.ShellInit
+import kotlin.test.assertNotNull
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.never
+
+/**
+ * Test class for {@link TransitionStateHolder}
+ *
+ * Usage: atest WMShellUnitTests:TransitionStateHolderTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class TransitionStateHolderTest {
+
+    lateinit var recentTransitionHandler: RecentsTransitionHandler
+    lateinit var shellInit: ShellInit
+
+    @Before
+    fun before() {
+        recentTransitionHandler = mock(RecentsTransitionHandler::class.java)
+        shellInit = ShellInit(TestShellExecutor())
+    }
+
+    @Test
+    fun `No TransitionStateHolder listeners before initialization`() {
+        TransitionStateHolder(shellInit, recentTransitionHandler)
+        verify(recentTransitionHandler, never()).addTransitionStateListener(any())
+    }
+
+    @Test
+    fun `When TransitionStateHolder initialized a listener has been registered `() {
+        TransitionStateHolder(shellInit, recentTransitionHandler)
+        shellInit.init()
+        assertNotNull(recentsTransitionStateListener)
+    }
+
+    @Test
+    fun `When TransitionStateHolder is created  no recent animation running`() {
+        val holder = TransitionStateHolder(shellInit, recentTransitionHandler)
+        shellInit.init()
+        assertFalse(holder.isRecentsTransitionRunning())
+    }
+
+    @Test
+    fun `Recent animation running updates after callback value`() {
+        val holder = TransitionStateHolder(shellInit, recentTransitionHandler)
+        shellInit.init()
+
+        assertFalse(holder.isRecentsTransitionRunning())
+
+        recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_NOT_RUNNING)
+        assertFalse(holder.isRecentsTransitionRunning())
+
+        recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_REQUESTED)
+        assertTrue(holder.isRecentsTransitionRunning())
+
+        recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_ANIMATING)
+        assertTrue(holder.isRecentsTransitionRunning())
+    }
+
+    private val recentsTransitionStateListener: RecentsTransitionStateListener
+        get() = ArgumentCaptor.forClass(RecentsTransitionStateListener::class.java).run {
+            verify(recentTransitionHandler).addTransitionStateListener(capture())
+            value
+        }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
index 803e5d4..1d39000 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
@@ -21,7 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.R
 import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxSurfaceBuilderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxSurfaceBuilderTest.kt
new file mode 100644
index 0000000..68d9bf9
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxSurfaceBuilderTest.kt
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.letterbox
+
+import android.content.Context
+import android.testing.AndroidTestingRunner
+import android.view.SurfaceControl
+import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn
+import com.android.wm.shell.ShellTestCase
+import java.util.function.Consumer
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.anyOrNull
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.verification.VerificationMode
+
+/**
+ * Tests for [LetterboxSurfaceBuilder].
+ *
+ * Build/Install/Run:
+ *  atest WMShellUnitTests:LetterboxSurfaceBuilderTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class LetterboxSurfaceBuilderTest : ShellTestCase() {
+
+    @Test
+    fun `When surface is created mandatory methods are invoked`() {
+        runTestScenario { r ->
+            r.invokeBuilder()
+
+            r.checkNameIsSet(expected = true)
+            r.checkCallSiteIsSet(expected = true)
+            r.checkSurfaceIsHidden(invoked = true, isHidden = true)
+            r.checkColorLayerIsSet(expected = true)
+            r.checkParentLeashIsSet(expected = true)
+            r.checkSetLayerIsInvoked(expected = true)
+            r.checkColorSpaceAgnosticIsSet(expected = true, value = true)
+            r.checkColorIsSetFromLetterboxConfiguration(expected = true)
+        }
+    }
+
+    /**
+     * Runs a test scenario providing a Robot.
+     */
+    fun runTestScenario(consumer: Consumer<LetterboxSurfaceBuilderRobotTest>) {
+        val robot = LetterboxSurfaceBuilderRobotTest(mContext)
+        consumer.accept(robot)
+    }
+
+    class LetterboxSurfaceBuilderRobotTest(val ctx: Context) {
+
+        private val letterboxConfiguration: LetterboxConfiguration
+        private val letterboxSurfaceBuilder: LetterboxSurfaceBuilder
+        private val tx: SurfaceControl.Transaction
+        private val parentLeash: SurfaceControl
+        private val surfaceBuilder: SurfaceControl.Builder
+
+        companion object {
+            @JvmStatic
+            val TEST_SURFACE_NAME = "SurfaceForTest"
+
+            @JvmStatic
+            val TEST_SURFACE_CALL_SITE = "CallSiteForTest"
+        }
+
+        init {
+            letterboxConfiguration = LetterboxConfiguration(ctx)
+            letterboxSurfaceBuilder = LetterboxSurfaceBuilder(letterboxConfiguration)
+            tx = org.mockito.kotlin.mock<SurfaceControl.Transaction>()
+            doReturn(tx).`when`(tx).setLayer(anyOrNull(), anyOrNull())
+            doReturn(tx).`when`(tx).setColorSpaceAgnostic(anyOrNull(), anyOrNull())
+            parentLeash = org.mockito.kotlin.mock<SurfaceControl>()
+            surfaceBuilder = SurfaceControl.Builder()
+            spyOn(surfaceBuilder)
+        }
+
+        fun invokeBuilder() {
+            letterboxSurfaceBuilder.createSurface(
+                tx,
+                parentLeash,
+                TEST_SURFACE_NAME,
+                TEST_SURFACE_CALL_SITE,
+                surfaceBuilder
+            )
+        }
+
+        fun checkNameIsSet(expected: Boolean) {
+            verify(surfaceBuilder, expected.asMode())
+                .setName(TEST_SURFACE_NAME)
+        }
+
+        fun checkCallSiteIsSet(expected: Boolean) {
+            verify(surfaceBuilder, expected.asMode())
+                .setCallsite(TEST_SURFACE_CALL_SITE)
+        }
+
+        fun checkSurfaceIsHidden(invoked: Boolean, isHidden: Boolean) {
+            verify(surfaceBuilder, invoked.asMode())
+                .setHidden(isHidden)
+        }
+
+        fun checkColorLayerIsSet(expected: Boolean) {
+            verify(surfaceBuilder, expected.asMode()).setColorLayer()
+        }
+
+        fun checkParentLeashIsSet(expected: Boolean) {
+            verify(surfaceBuilder, expected.asMode()).setParent(parentLeash)
+        }
+
+        fun checkSetLayerIsInvoked(expected: Boolean) {
+            verify(tx, expected.asMode()).setLayer(anyOrNull(), ArgumentMatchers.anyInt())
+        }
+
+        fun checkColorSpaceAgnosticIsSet(expected: Boolean, value: Boolean) {
+            verify(tx, expected.asMode()).setColorSpaceAgnostic(anyOrNull(), eq(value))
+        }
+
+        fun checkColorIsSetFromLetterboxConfiguration(expected: Boolean) {
+            val components = letterboxConfiguration.getBackgroundColorRgbArray()
+            verify(tx, expected.asMode()).setColor(anyOrNull(), eq(components))
+        }
+
+        private fun Boolean.asMode(): VerificationMode = if (this) times(1) else never()
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserverTest.kt
index 1ae1c3f..9c6afcb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTransitionObserverTest.kt
@@ -16,10 +16,13 @@
 
 package com.android.wm.shell.compatui.letterbox
 
+import android.graphics.Point
+import android.graphics.Rect
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.platform.test.flag.junit.SetFlagsRule
 import android.testing.AndroidTestingRunner
+import android.view.SurfaceControl
 import android.view.WindowManager.TRANSIT_CLOSE
 import androidx.test.filters.SmallTest
 import com.android.window.flags.Flags
@@ -33,12 +36,12 @@
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mockito
 import org.mockito.kotlin.any
 import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
 import org.mockito.kotlin.times
-import org.mockito.kotlin.anyOrNull
+import org.mockito.kotlin.verify
 import org.mockito.verification.VerificationMode
 
 /**
@@ -93,7 +96,7 @@
                     r.creationEventDetected(expected = false)
                     r.visibilityEventDetected(expected = false)
                     r.destroyEventDetected(expected = false)
-                    r.boundsEventDetected(expected = false)
+                    r.updateSurfaceBoundsEventDetected(expected = false)
                 }
             }
         }
@@ -107,14 +110,23 @@
 
                 inputBuilder {
                     buildTransitionInfo()
-                    r.createTopActivityChange(inputBuilder = this, isLetterboxed = true)
+                    r.createTopActivityChange(
+                        inputBuilder = this,
+                        isLetterboxed = true,
+                        taskPosition = Point(20, 30),
+                        taskWidth = 200,
+                        taskHeight = 300
+                    )
                 }
 
                 validateOutput {
                     r.creationEventDetected(expected = true)
                     r.visibilityEventDetected(expected = true, visible = true)
                     r.destroyEventDetected(expected = false)
-                    r.boundsEventDetected(expected = true)
+                    r.updateSurfaceBoundsEventDetected(
+                        expected = true,
+                        taskBounds = Rect(20, 30, 200, 300)
+                    )
                 }
             }
         }
@@ -135,7 +147,7 @@
                     r.creationEventDetected(expected = false)
                     r.visibilityEventDetected(expected = true, visible = false)
                     r.destroyEventDetected(expected = false)
-                    r.boundsEventDetected(expected = false)
+                    r.updateSurfaceBoundsEventDetected(expected = false)
                 }
             }
         }
@@ -156,7 +168,7 @@
                     r.destroyEventDetected(expected = true)
                     r.creationEventDetected(expected = false)
                     r.visibilityEventDetected(expected = false, visible = false)
-                    r.boundsEventDetected(expected = false)
+                    r.updateSurfaceBoundsEventDetected(expected = false)
                 }
             }
         }
@@ -189,10 +201,10 @@
         val observerFactory: () -> LetterboxTransitionObserver
 
         init {
-            executor = Mockito.mock(ShellExecutor::class.java)
+            executor = mock<ShellExecutor>()
             shellInit = ShellInit(executor)
-            transitions = Mockito.mock(Transitions::class.java)
-            letterboxController = Mockito.mock(LetterboxController::class.java)
+            transitions = mock<Transitions>()
+            letterboxController = mock<LetterboxController>()
             letterboxObserver =
                 LetterboxTransitionObserver(shellInit, transitions, letterboxController)
             observerFactory = { letterboxObserver }
@@ -203,67 +215,78 @@
         fun observer() = letterboxObserver
 
         fun checkObservableIsRegistered(expected: Boolean) {
-            Mockito.verify(transitions, expected.asMode()).registerObserver(observer())
+            verify(transitions, expected.asMode()).registerObserver(observer())
         }
 
         fun creationEventDetected(
             expected: Boolean,
             displayId: Int = DISPLAY_ID,
             taskId: Int = TASK_ID
-        ) {
-            Mockito.verify(letterboxController, expected.asMode()).createLetterboxSurface(
-                toLetterboxKeyMatcher(displayId, taskId),
-                anyOrNull(),
-                anyOrNull()
-            )
-        }
+        ) = verify(
+            letterboxController,
+            expected.asMode()
+        ).createLetterboxSurface(
+            eq(LetterboxKey(displayId, taskId)),
+            any<SurfaceControl.Transaction>(),
+            any<SurfaceControl>()
+        )
 
         fun visibilityEventDetected(
             expected: Boolean,
+            visible: Boolean = true,
             displayId: Int = DISPLAY_ID,
-            taskId: Int = TASK_ID,
-            visible: Boolean? = null
-        ) {
-            Mockito.verify(letterboxController, expected.asMode()).updateLetterboxSurfaceVisibility(
-                toLetterboxKeyMatcher(displayId, taskId),
-                anyOrNull(),
-                visible.asMatcher()
-            )
-        }
+            taskId: Int = TASK_ID
+        ) = verify(letterboxController, expected.asMode()).updateLetterboxSurfaceVisibility(
+            eq(LetterboxKey(displayId, taskId)),
+            any<SurfaceControl.Transaction>(),
+            eq(visible)
+        )
 
         fun destroyEventDetected(
             expected: Boolean,
             displayId: Int = DISPLAY_ID,
             taskId: Int = TASK_ID
-        ) {
-            Mockito.verify(letterboxController, expected.asMode()).destroyLetterboxSurface(
-                toLetterboxKeyMatcher(displayId, taskId),
-                anyOrNull()
-            )
-        }
+        ) = verify(
+            letterboxController,
+            expected.asMode()
+        ).destroyLetterboxSurface(
+            eq(LetterboxKey(displayId, taskId)),
+            any<SurfaceControl.Transaction>()
+        )
 
-        fun boundsEventDetected(
+        fun updateSurfaceBoundsEventDetected(
             expected: Boolean,
             displayId: Int = DISPLAY_ID,
-            taskId: Int = TASK_ID
-        ) {
-            Mockito.verify(letterboxController, expected.asMode()).updateLetterboxSurfaceBounds(
-                toLetterboxKeyMatcher(displayId, taskId),
-                anyOrNull(),
-                anyOrNull()
-            )
-        }
+            taskId: Int = TASK_ID,
+            taskBounds: Rect = Rect()
+        ) = verify(
+            letterboxController,
+            expected.asMode()
+        ).updateLetterboxSurfaceBounds(
+            eq(LetterboxKey(displayId, taskId)),
+            any<SurfaceControl.Transaction>(),
+            eq(taskBounds)
+        )
 
         fun createTopActivityChange(
             inputBuilder: TransitionObserverInputBuilder,
             isLetterboxed: Boolean = true,
             displayId: Int = DISPLAY_ID,
-            taskId: Int = TASK_ID
+            taskId: Int = TASK_ID,
+            taskPosition: Point = Point(),
+            taskWidth: Int = 0,
+            taskHeight: Int = 0
         ) {
-            inputBuilder.addChange(changeTaskInfo = inputBuilder.createTaskInfo().apply {
-                appCompatTaskInfo.isTopActivityLetterboxed = isLetterboxed
-                this.taskId = taskId
-                this.displayId = displayId
+            inputBuilder.addChange(inputBuilder.createChange(
+                changeTaskInfo = inputBuilder.createTaskInfo().apply {
+                    appCompatTaskInfo.isTopActivityLetterboxed = isLetterboxed
+                    this.taskId = taskId
+                    this.displayId = displayId
+                }
+            ).apply {
+                endRelOffset.x = taskPosition.x
+                endRelOffset.y = taskPosition.y
+                endAbsBounds.set(Rect(0, 0, taskWidth, taskHeight))
             })
         }
 
@@ -279,16 +302,5 @@
         }
 
         private fun Boolean.asMode(): VerificationMode = if (this) times(1) else never()
-
-        private fun Boolean?.asMatcher(): Boolean =
-            if (this != null) eq(this) else any()
-
-        private fun toLetterboxKeyMatcher(displayId: Int, taskId: Int): LetterboxKey {
-            if (displayId < 0 || taskId < 0) {
-                return any()
-            } else {
-                return eq(LetterboxKey(displayId, taskId))
-            }
-        }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
index aabd973..2ea0379 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
@@ -39,8 +39,8 @@
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.common.TaskStackListenerImpl
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
 import com.android.wm.shell.desktopmode.persistence.Desktop
 import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
 import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
index a4f4d05..b57c55c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
@@ -42,7 +42,8 @@
 import com.android.wm.shell.TestShellExecutor
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayLayout
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopImmersiveController.ExitReason.USER_INTERACTION
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.util.StubTransaction
@@ -168,7 +169,7 @@
             immersive = true
         )
 
-        controller.moveTaskToNonImmersive(task)
+        controller.moveTaskToNonImmersive(task, USER_INTERACTION)
         controller.onTransitionReady(
             transition = mockBinder,
             info = createTransitionInfo(
@@ -195,7 +196,7 @@
         )
         desktopRepository.saveBoundsBeforeFullImmersive(task.taskId, Rect(100, 100, 600, 600))
 
-        controller.moveTaskToNonImmersive(task)
+        controller.moveTaskToNonImmersive(task, USER_INTERACTION)
         controller.onTransitionReady(
             transition = mockBinder,
             info = createTransitionInfo(
@@ -252,8 +253,8 @@
         whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
             .thenReturn(mockBinder)
 
-        controller.moveTaskToNonImmersive(task)
-        controller.moveTaskToNonImmersive(task)
+        controller.moveTaskToNonImmersive(task, USER_INTERACTION)
+        controller.moveTaskToNonImmersive(task, USER_INTERACTION)
 
         verify(mockTransitions, times(1))
             .startTransition(eq(TRANSIT_CHANGE), any(), eq(controller))
@@ -272,7 +273,7 @@
             immersive = true
         )
 
-        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
         assertThat(controller.pendingExternalExitTransitions.any { exit ->
             exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
@@ -293,7 +294,7 @@
             immersive = false
         )
 
-        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
         assertThat(controller.pendingExternalExitTransitions.any { exit ->
             exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
@@ -314,7 +315,7 @@
             immersive = true
         )
 
-        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
         assertThat(wct.hasBoundsChange(task.token)).isTrue()
     }
@@ -332,7 +333,7 @@
             immersive = false
         )
 
-        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
         assertThat(wct.hasBoundsChange(task.token)).isFalse()
     }
@@ -353,7 +354,8 @@
         controller.exitImmersiveIfApplicable(
             wct = wct,
             displayId = DEFAULT_DISPLAY,
-            excludeTaskId = task.taskId
+            excludeTaskId = task.taskId,
+            reason = USER_INTERACTION,
         ).asExit()?.runOnTransitionStart?.invoke(transition)
 
         assertThat(controller.pendingExternalExitTransitions.any { exit ->
@@ -374,7 +376,7 @@
             immersive = true
         )
 
-        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task, reason = USER_INTERACTION)
 
         assertThat(wct.hasBoundsChange(task.token)).isTrue()
     }
@@ -391,7 +393,7 @@
             immersive = false
         )
 
-        controller.exitImmersiveIfApplicable(wct, task)
+        controller.exitImmersiveIfApplicable(wct, task, USER_INTERACTION)
 
         assertThat(wct.hasBoundsChange(task.token)).isFalse()
     }
@@ -409,7 +411,7 @@
             immersive = true
         )
 
-        controller.exitImmersiveIfApplicable(wct, task)
+        controller.exitImmersiveIfApplicable(wct, task, USER_INTERACTION)
             .asExit()?.runOnTransitionStart?.invoke(transition)
 
         assertThat(controller.pendingExternalExitTransitions.any { exit ->
@@ -430,7 +432,7 @@
             immersive = false
         )
 
-        val result = controller.exitImmersiveIfApplicable(wct, task)
+        val result = controller.exitImmersiveIfApplicable(wct, task, USER_INTERACTION)
 
         assertThat(result).isEqualTo(DesktopImmersiveController.ExitResult.NoExit)
     }
@@ -447,7 +449,8 @@
             immersive = false
         )
 
-        val result = controller.exitImmersiveIfApplicable(wct, task.displayId)
+        val result = controller.exitImmersiveIfApplicable(
+            wct, task.displayId, excludeTaskId = null, USER_INTERACTION)
 
         assertThat(result).isEqualTo(DesktopImmersiveController.ExitResult.NoExit)
     }
@@ -464,7 +467,7 @@
             taskId = task.taskId,
             immersive = true
         )
-        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
         controller.onTransitionReady(
             transition = transition,
@@ -495,7 +498,7 @@
             taskId = task.taskId,
             immersive = true
         )
-        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
         controller.onTransitionReady(
             transition = transition,
@@ -530,7 +533,7 @@
             taskId = task.taskId,
             immersive = true
         )
-        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
         controller.onTransitionReady(
             transition = transition,
@@ -560,7 +563,7 @@
             immersive = true
         )
         desktopRepository.saveBoundsBeforeFullImmersive(task.taskId, Rect(100, 100, 600, 600))
-        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
         controller.onTransitionReady(
             transition = transition,
@@ -587,7 +590,7 @@
             immersive = true
         )
 
-        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task, reason = USER_INTERACTION)
 
         assertThat(
             wct.hasBoundsChange(task.token, calculateMaximizeBounds(mockDisplayLayout, task))
@@ -611,7 +614,7 @@
         val preImmersiveBounds = Rect(100, 100, 500, 500)
         desktopRepository.saveBoundsBeforeFullImmersive(task.taskId, preImmersiveBounds)
 
-        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task, reason = USER_INTERACTION)
 
         assertThat(
             wct.hasBoundsChange(task.token, preImmersiveBounds)
@@ -634,7 +637,7 @@
             immersive = true
         )
 
-        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task, reason = USER_INTERACTION)
 
         assertThat(
             wct.hasBoundsChange(task.token, calculateInitialBounds(mockDisplayLayout, task))
@@ -652,10 +655,10 @@
             taskId = task.taskId,
             immersive = true
         )
-        controller.exitImmersiveIfApplicable(wct, task)
+        controller.exitImmersiveIfApplicable(wct, task, USER_INTERACTION)
             .asExit()?.runOnTransitionStart?.invoke(Binder())
 
-        controller.moveTaskToNonImmersive(task)
+        controller.moveTaskToNonImmersive(task, USER_INTERACTION)
 
         verify(mockTransitions, never()).startTransition(any(), any(), any())
     }
@@ -674,7 +677,7 @@
             immersive = true
         )
 
-        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
         assertThat(controller.isImmersiveChange(transition, change)).isTrue()
     }
@@ -692,7 +695,7 @@
             immersive = true
         )
 
-        controller.moveTaskToNonImmersive(task)
+        controller.moveTaskToNonImmersive(task, USER_INTERACTION)
 
         controller.animateResizeChange(
             change = TransitionInfo.Change(task.token, SurfaceControl()).apply {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
index 2a82e6e..2f225f2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
@@ -487,7 +487,7 @@
     @Test
     fun logTaskResizingStarted_noOngoingSession_doesNotLog() {
         desktopModeEventLogger.logTaskResizingStarted(ResizeTrigger.CORNER,
-            null, createTaskInfo())
+            InputMethod.UNKNOWN_INPUT_METHOD, createTaskInfo())
 
         verifyZeroInteractions(staticMockMarker(FrameworkStatsLog::class.java))
         verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -499,7 +499,8 @@
         val sessionId = startDesktopModeSession()
 
         desktopModeEventLogger.logTaskResizingStarted(ResizeTrigger.CORNER,
-            null, createTaskInfo(), displayController)
+            InputMethod.UNKNOWN_INPUT_METHOD, createTaskInfo(), TASK_SIZE_UPDATE.taskWidth,
+            TASK_SIZE_UPDATE.taskHeight, displayController)
 
         verify {
             FrameworkStatsLog.write(
@@ -516,10 +517,10 @@
                 eq(TASK_SIZE_UPDATE.instanceId),
                 /* uid */
                 eq(TASK_SIZE_UPDATE.uid),
-                /* task_height */
-                eq(TASK_SIZE_UPDATE.taskHeight),
                 /* task_width */
                 eq(TASK_SIZE_UPDATE.taskWidth),
+                /* task_height */
+                eq(TASK_SIZE_UPDATE.taskHeight),
                 /* display_area */
                 eq(DISPLAY_AREA),
             )
@@ -530,7 +531,7 @@
     @Test
     fun logTaskResizingEnded_noOngoingSession_doesNotLog() {
         desktopModeEventLogger.logTaskResizingEnded(ResizeTrigger.CORNER,
-            null, createTaskInfo())
+            InputMethod.UNKNOWN_INPUT_METHOD, createTaskInfo())
 
         verifyZeroInteractions(staticMockMarker(FrameworkStatsLog::class.java))
         verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -542,7 +543,7 @@
         val sessionId = startDesktopModeSession()
 
         desktopModeEventLogger.logTaskResizingEnded(ResizeTrigger.CORNER,
-            null, createTaskInfo(), displayController = displayController)
+            InputMethod.UNKNOWN_INPUT_METHOD, createTaskInfo(), displayController = displayController)
 
         verify {
             FrameworkStatsLog.write(
@@ -559,10 +560,10 @@
                 eq(TASK_SIZE_UPDATE.instanceId),
                 /* uid */
                 eq(TASK_SIZE_UPDATE.uid),
-                /* task_height */
-                eq(TASK_SIZE_UPDATE.taskHeight),
                 /* task_width */
                 eq(TASK_SIZE_UPDATE.taskWidth),
+                /* task_height */
+                eq(TASK_SIZE_UPDATE.taskHeight),
                 /* display_area */
                 eq(DISPLAY_AREA),
             )
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
index 9e63a6d..d4682c1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
@@ -38,7 +38,7 @@
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import com.android.wm.shell.transition.FocusTransitionObserver
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -134,6 +134,12 @@
             null
         }.whenever(inputManager).registerKeyGestureEventHandler(any())
         shellInit.init()
+
+        desktopModeKeyGestureHandler = DesktopModeKeyGestureHandler(
+            context,
+            Optional.of(desktopModeWindowDecorViewModel), Optional.of(desktopTasksController),
+            inputManager, shellTaskOrganizer, focusTransitionObserver, testExecutor
+        )
     }
 
     @After
@@ -151,11 +157,6 @@
         FLAG_USE_KEY_GESTURE_EVENT_HANDLER
     )
     fun keyGestureMoveToNextDisplay_shouldMoveToNextDisplay() {
-        desktopModeKeyGestureHandler = DesktopModeKeyGestureHandler(
-            context,
-            Optional.of(desktopModeWindowDecorViewModel), Optional.of(desktopTasksController),
-            inputManager, shellTaskOrganizer, focusTransitionObserver
-        )
         // Set up two display ids
         whenever(rootTaskDisplayAreaOrganizer.displayIds)
             .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY))
@@ -187,11 +188,6 @@
         FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS
     )
     fun keyGestureSnapLeft_shouldSnapResizeTaskToLeft() {
-        desktopModeKeyGestureHandler = DesktopModeKeyGestureHandler(
-            context,
-            Optional.of(desktopModeWindowDecorViewModel), Optional.of(desktopTasksController),
-            inputManager, shellTaskOrganizer, focusTransitionObserver
-        )
         val task = setUpFreeformTask()
         task.isFocused = true
         whenever(shellTaskOrganizer.getRunningTasks()).thenReturn(arrayListOf(task))
@@ -205,7 +201,12 @@
         val result = keyGestureEventHandler.handleKeyGestureEvent(event, null)
 
         assertThat(result).isTrue()
-        verify(desktopModeWindowDecorViewModel).onSnapResize(task.taskId, true, null)
+        verify(desktopModeWindowDecorViewModel).onSnapResize(
+            task.taskId,
+            true,
+            DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
+            /* fromMenu= */ false
+        )
     }
 
     @Test
@@ -214,11 +215,6 @@
         FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS
     )
     fun keyGestureSnapRight_shouldSnapResizeTaskToRight() {
-        desktopModeKeyGestureHandler = DesktopModeKeyGestureHandler(
-            context,
-            Optional.of(desktopModeWindowDecorViewModel), Optional.of(desktopTasksController),
-            inputManager, shellTaskOrganizer, focusTransitionObserver
-        )
         val task = setUpFreeformTask()
         task.isFocused = true
         whenever(shellTaskOrganizer.getRunningTasks()).thenReturn(arrayListOf(task))
@@ -232,7 +228,12 @@
         val result = keyGestureEventHandler.handleKeyGestureEvent(event, null)
 
         assertThat(result).isTrue()
-        verify(desktopModeWindowDecorViewModel).onSnapResize(task.taskId, false, null)
+        verify(desktopModeWindowDecorViewModel).onSnapResize(
+            task.taskId,
+            false,
+            DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
+            /* fromMenu= */ false
+        )
     }
 
     @Test
@@ -241,11 +242,6 @@
         FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS
     )
     fun keyGestureToggleFreeformWindowSize_shouldToggleTaskSize() {
-        desktopModeKeyGestureHandler = DesktopModeKeyGestureHandler(
-            context,
-            Optional.of(desktopModeWindowDecorViewModel), Optional.of(desktopTasksController),
-            inputManager, shellTaskOrganizer, focusTransitionObserver
-        )
         val task = setUpFreeformTask()
         task.isFocused = true
         whenever(shellTaskOrganizer.getRunningTasks()).thenReturn(arrayListOf(task))
@@ -262,7 +258,7 @@
         verify(desktopTasksController).toggleDesktopTaskSize(
             task,
             ResizeTrigger.MAXIMIZE_MENU,
-            null
+            DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
         )
     }
 
@@ -272,11 +268,6 @@
         FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS
     )
     fun keyGestureMinimizeFreeformWindow_shouldMinimizeTask() {
-        desktopModeKeyGestureHandler = DesktopModeKeyGestureHandler(
-            context,
-            Optional.of(desktopModeWindowDecorViewModel), Optional.of(desktopTasksController),
-            inputManager, shellTaskOrganizer, focusTransitionObserver
-        )
         val task = setUpFreeformTask()
         task.isFocused = true
         whenever(shellTaskOrganizer.getRunningTasks()).thenReturn(arrayListOf(task))
@@ -290,7 +281,6 @@
         val result = keyGestureEventHandler.handleKeyGestureEvent(event, null)
 
         assertThat(result).isTrue()
-        verify(desktopTasksController).minimizeTask(task)
     }
 
     private fun setUpFreeformTask(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt
index 51b291c0..94698e2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt
@@ -17,17 +17,22 @@
 package com.android.wm.shell.desktopmode
 
 
+import android.content.ComponentName
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
-import com.android.internal.logging.InstanceIdSequence
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.Companion.DesktopUiEventEnum.DESKTOP_WINDOW_EDGE_DRAG_RESIZE
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.DESKTOP_WINDOW_EDGE_DRAG_RESIZE
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 
 /**
  * Test class for [DesktopModeUiEventLogger]
@@ -39,13 +44,13 @@
 class DesktopModeUiEventLoggerTest : ShellTestCase() {
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
     private lateinit var logger: DesktopModeUiEventLogger
-    private val instanceIdSequence = InstanceIdSequence(/* instanceIdMax */ 1 shl 20)
 
+    private val mockPackageManager: PackageManager = mock<PackageManager>()
 
     @Before
     fun setUp() {
         uiEventLoggerFake = UiEventLoggerFake()
-        logger = DesktopModeUiEventLogger(uiEventLoggerFake, instanceIdSequence)
+        logger = DesktopModeUiEventLogger(uiEventLoggerFake, mockPackageManager)
     }
 
     @Test
@@ -102,10 +107,28 @@
         assertThat(uiEventLoggerFake[0].packageName).isEqualTo(PACKAGE_NAME)
     }
 
+    @Test
+    fun logWithTaskInfo_eventLogged() {
+        val event =
+            DESKTOP_WINDOW_EDGE_DRAG_RESIZE
+        val taskInfo = TestRunningTaskInfoBuilder()
+            .setUserId(USER_ID)
+            .setBaseActivity(ComponentName(PACKAGE_NAME, "test"))
+            .build()
+        whenever(mockPackageManager.getApplicationInfoAsUser(PACKAGE_NAME, /* flags= */ 0, USER_ID))
+            .thenReturn(ApplicationInfo().apply { uid = UID })
+        logger.log(taskInfo, event)
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(event.id)
+        assertThat(uiEventLoggerFake[0].instanceId).isNull()
+        assertThat(uiEventLoggerFake[0].uid).isEqualTo(UID)
+        assertThat(uiEventLoggerFake[0].packageName).isEqualTo(PACKAGE_NAME)
+    }
 
     companion object {
         private val INSTANCE_ID = InstanceId.fakeInstanceId(0)
         private const val UID = 10
+        private const val USER_ID = 2
         private const val PACKAGE_NAME = "com.foo"
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
index e977966..8e323ac 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
@@ -23,8 +23,8 @@
 import androidx.test.filters.SmallTest
 import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
 import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
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 5df3957..5c00272 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
@@ -94,14 +94,15 @@
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.common.SyncTransactionQueue
 import com.android.wm.shell.desktopmode.DesktopImmersiveController.ExitResult
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
 import com.android.wm.shell.desktopmode.DesktopTasksController.DesktopModeEntryExitTransitionListener
 import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
 import com.android.wm.shell.desktopmode.DesktopTasksController.TaskbarDesktopTaskListener
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createSplitScreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createHomeTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createSplitScreenTask
 import com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION
 import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler.FULLSCREEN_ANIMATION_DURATION
 import com.android.wm.shell.desktopmode.minimize.DesktopWindowLimitRemoteHandler
@@ -113,6 +114,8 @@
 import com.android.wm.shell.recents.RecentTasksController
 import com.android.wm.shell.recents.RecentsTransitionHandler
 import com.android.wm.shell.recents.RecentsTransitionStateListener
+import com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING
+import com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource.UNKNOWN
 import com.android.wm.shell.shared.split.SplitScreenConstants
@@ -217,6 +220,7 @@
   @Mock private lateinit var freeformTaskTransitionStarter: FreeformTaskTransitionStarter
   @Mock private lateinit var mockHandler: Handler
   @Mock private lateinit var desktopModeEventLogger: DesktopModeEventLogger
+  @Mock private lateinit var desktopModeUiEventLogger: DesktopModeUiEventLogger
   @Mock lateinit var persistentRepository: DesktopPersistentRepository
   @Mock lateinit var motionEvent: MotionEvent
   @Mock lateinit var repositoryInitializer: DesktopRepositoryInitializer
@@ -291,10 +295,10 @@
     tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
     whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)).thenReturn(tda)
     whenever(mMockDesktopImmersiveController
-      .exitImmersiveIfApplicable(any(), any<RunningTaskInfo>()))
+      .exitImmersiveIfApplicable(any(), any<RunningTaskInfo>(), any()))
       .thenReturn(ExitResult.NoExit)
     whenever(mMockDesktopImmersiveController
-      .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull()))
+      .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull(), any()))
       .thenReturn(ExitResult.NoExit)
 
     controller = createController()
@@ -343,6 +347,7 @@
         mockInteractionJankMonitor,
         mockHandler,
         desktopModeEventLogger,
+        desktopModeUiEventLogger,
         desktopTilingDecorViewModel,
       )
   }
@@ -372,15 +377,15 @@
     val task1 = setUpFreeformTask()
 
     val argumentCaptor = ArgumentCaptor.forClass(Boolean::class.java)
-    controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
 
     verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.MAXIMIZE_BUTTON,
-      motionEvent,
+      InputMethod.TOUCH,
       task1,
-      STABLE_BOUNDS.height(),
       STABLE_BOUNDS.width(),
+      STABLE_BOUNDS.height(),
       displayController
     )
     assertThat(argumentCaptor.value).isTrue()
@@ -399,12 +404,12 @@
     val task1 = setUpFreeformTask(bounds = stableBounds, active = true)
 
     val argumentCaptor = ArgumentCaptor.forClass(Boolean::class.java)
-    controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
 
     verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.MAXIMIZE_BUTTON,
-      motionEvent,
+      InputMethod.TOUCH,
       task1,
       0,
       0,
@@ -1793,7 +1798,7 @@
 
     controller.minimizeTask(task)
 
-    verify(mMockDesktopImmersiveController).exitImmersiveIfApplicable(any(), eq(task))
+    verify(mMockDesktopImmersiveController).exitImmersiveIfApplicable(any(), eq(task), any())
   }
 
   @Test
@@ -1803,7 +1808,7 @@
     val runOnTransit = RunOnStartTransitionCallback()
     whenever(freeformTaskTransitionStarter.startMinimizedModeTransition(any()))
       .thenReturn(transition)
-    whenever(mMockDesktopImmersiveController.exitImmersiveIfApplicable(any(), eq(task)))
+    whenever(mMockDesktopImmersiveController.exitImmersiveIfApplicable(any(), eq(task), any()))
       .thenReturn(
         ExitResult.Exit(
         exitingTask = task.taskId,
@@ -1920,6 +1925,7 @@
   }
 
   @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
   fun handleRequest_fullscreenTask_noTasks_enforceDesktop_freeformDisplay_returnFreeformWCT() {
     whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
     val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
@@ -1931,8 +1937,13 @@
     assertNotNull(wct, "should handle request")
     assertThat(wct.changes[fullscreenTask.token.asBinder()]?.windowingMode)
         .isEqualTo(WINDOWING_MODE_UNDEFINED)
-    assertThat(wct.hierarchyOps).hasSize(1)
-    wct.assertReorderAt(0, fullscreenTask, toTop = true)
+    assertThat(wct.hierarchyOps).hasSize(3)
+    // There are 3 hops that are happening in this case:
+    // 1. Moving the fullscreen task to top as we add moveToDesktop() changes
+    // 2. Pending intent for the wallpaper
+    // 3. Bringing the fullscreen task back at the top
+    wct.assertPendingIntentAt(1, desktopWallpaperIntent)
+    wct.assertReorderAt(2, fullscreenTask, toTop = true)
   }
 
   @Test
@@ -2192,7 +2203,7 @@
     markTaskVisible(freeformTask)
 
     // Mark recents animation running
-    recentsTransitionStateListener.onAnimationStateChanged(true)
+    recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_ANIMATING)
 
     // Open a fullscreen task, check that it does not result in a WCT with changes to it
     val fullscreenTask = createFullscreenTask()
@@ -2206,7 +2217,7 @@
     markTaskVisible(freeformTask)
 
     // Mark recents animation running
-    recentsTransitionStateListener.onAnimationStateChanged(true)
+    recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_ANIMATING)
 
     // Should become undefined as the TDA is set to fullscreen. It will inherit from the TDA.
     val result = controller.handleRequest(Binder(), createTransition(freeformTask))
@@ -3013,16 +3024,18 @@
     // Assert event is properly logged
     verify(desktopModeEventLogger, times(1)).logTaskResizingStarted(
       ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER,
-      motionEvent,
+      InputMethod.UNKNOWN_INPUT_METHOD,
       task,
+      task.configuration.windowConfiguration.bounds.width(),
+      task.configuration.windowConfiguration.bounds.height(),
       displayController
     )
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER,
-      motionEvent,
+      InputMethod.UNKNOWN_INPUT_METHOD,
       task,
-      STABLE_BOUNDS.height(),
       STABLE_BOUNDS.width(),
+      STABLE_BOUNDS.height(),
       displayController
     )
   }
@@ -3071,7 +3084,7 @@
     )
     // Assert no event is logged
     verify(desktopModeEventLogger, never()).logTaskResizingStarted(
-      any(), any(), any(), any(), any()
+      any(), any(), any(), any(), any(), any(), any()
     )
     verify(desktopModeEventLogger, never()).logTaskResizingEnded(
       any(), any(), any(), any(), any(), any(), any()
@@ -3189,7 +3202,7 @@
     val wctCaptor = argumentCaptor<WindowContainerTransaction>()
     val transition = Binder()
     whenever(mMockDesktopImmersiveController
-      .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull()))
+      .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull(), any()))
       .thenReturn(ExitResult.NoExit)
     whenever(desktopMixedTransitionHandler
       .startLaunchTransition(anyInt(), any(), anyOrNull(), anyOrNull(), anyOrNull()))
@@ -3212,7 +3225,7 @@
     val runOnStart = RunOnStartTransitionCallback()
     val transition = Binder()
     whenever(mMockDesktopImmersiveController
-      .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull()))
+      .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull(), any()))
       .thenReturn(ExitResult.Exit(immersiveTask.taskId, runOnStart))
     whenever(desktopMixedTransitionHandler
       .startLaunchTransition(anyInt(), any(), anyOrNull(), anyOrNull(), anyOrNull()))
@@ -3315,7 +3328,8 @@
     whenever(transitions.startTransition(eq(TRANSIT_OPEN), any(), anyOrNull()))
       .thenReturn(transition)
     whenever(mMockDesktopImmersiveController
-      .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId)))
+      .exitImmersiveIfApplicable(
+        any(), eq(immersiveTask.displayId), eq(freeformTask.taskId), any()))
       .thenReturn(
         ExitResult.Exit(
         exitingTask = immersiveTask.taskId,
@@ -3325,7 +3339,7 @@
     runOpenInstance(immersiveTask, freeformTask.taskId)
 
     verify(mMockDesktopImmersiveController)
-      .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId))
+      .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId), any())
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3345,17 +3359,17 @@
     val bounds = Rect(0, 0, 100, 100)
     val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
 
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
 
     // Assert bounds set to stable bounds
     val wct = getLatestToggleResizeDesktopTaskWct()
     assertThat(findBoundsChange(wct, task)).isEqualTo(STABLE_BOUNDS)
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.MAXIMIZE_BUTTON,
-      motionEvent,
+      InputMethod.TOUCH,
       task,
-      STABLE_BOUNDS.height(),
       STABLE_BOUNDS.width(),
+      STABLE_BOUNDS.height(),
       displayController
     )
   }
@@ -3378,16 +3392,16 @@
     )
 
     controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT,
-      ResizeTrigger.SNAP_LEFT_MENU, motionEvent, desktopWindowDecoration)
+      ResizeTrigger.SNAP_LEFT_MENU, InputMethod.TOUCH, desktopWindowDecoration)
     // Assert bounds set to stable bounds
     val wct = getLatestToggleResizeDesktopTaskWct(currentDragBounds)
     assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.SNAP_LEFT_MENU,
-      motionEvent,
+      InputMethod.TOUCH,
       task,
-      expectedBounds.height(),
       expectedBounds.width(),
+      expectedBounds.height(),
       displayController
     )
   }
@@ -3410,7 +3424,7 @@
     // Attempt to snap left again
     val currentDragBounds = Rect(bounds).apply { offset(-100, 0) }
     controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT,
-      ResizeTrigger.SNAP_LEFT_MENU, motionEvent, desktopWindowDecoration)
+      ResizeTrigger.SNAP_LEFT_MENU, InputMethod.TOUCH, desktopWindowDecoration)
     // Assert that task is NOT updated via WCT
     verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
 
@@ -3424,10 +3438,10 @@
     )
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.SNAP_LEFT_MENU,
-      motionEvent,
+      InputMethod.TOUCH,
       task,
-      bounds.height(),
       bounds.width(),
+      bounds.height(),
       displayController
     )
   }
@@ -3454,8 +3468,10 @@
     )
     verify(desktopModeEventLogger, times(1)).logTaskResizingStarted(
       ResizeTrigger.DRAG_LEFT,
-      motionEvent,
+      InputMethod.UNKNOWN_INPUT_METHOD,
       task,
+      preDragBounds.width(),
+      preDragBounds.height(),
       displayController
     )
   }
@@ -3484,6 +3500,8 @@
       any(),
       any(),
       any(),
+      any(),
+      any(),
       any()
     )
   }
@@ -3499,7 +3517,12 @@
     }
 
     controller.handleInstantSnapResizingTask(
-      task, SnapPosition.LEFT, ResizeTrigger.SNAP_LEFT_MENU, motionEvent, desktopWindowDecoration)
+      task,
+      SnapPosition.LEFT,
+      ResizeTrigger.SNAP_LEFT_MENU,
+      InputMethod.MOUSE,
+      desktopWindowDecoration
+    )
 
     // Assert that task is NOT updated via WCT
     verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
@@ -3519,7 +3542,9 @@
     )
 
     controller.handleInstantSnapResizingTask(
-      task, SnapPosition.LEFT, ResizeTrigger.SNAP_LEFT_MENU, motionEvent, desktopWindowDecoration)
+      task, SnapPosition.LEFT, ResizeTrigger.SNAP_LEFT_MENU, InputMethod.MOUSE,
+      desktopWindowDecoration
+    )
 
     // Assert bounds set to half of the stable bounds
     val wct = getLatestToggleResizeDesktopTaskWct(taskBounds)
@@ -3527,16 +3552,18 @@
     verify(mockToast, never()).show()
     verify(desktopModeEventLogger, times(1)).logTaskResizingStarted(
       ResizeTrigger.SNAP_LEFT_MENU,
-      motionEvent,
+      InputMethod.MOUSE,
       task,
+      taskBounds.width(),
+      taskBounds.height(),
       displayController
     )
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.SNAP_LEFT_MENU,
-      motionEvent,
+      InputMethod.MOUSE,
       task,
-      expectedBounds.height(),
       expectedBounds.width(),
+      expectedBounds.height(),
       displayController
     )
   }
@@ -3557,17 +3584,17 @@
     // Bounds should be 1000 x 500, vertically centered in the 1000 x 1000 stable bounds
     val expectedBounds = Rect(STABLE_BOUNDS.left, 250, STABLE_BOUNDS.right, 750)
 
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
 
     // Assert bounds set to stable bounds
     val wct = getLatestToggleResizeDesktopTaskWct()
     assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.MAXIMIZE_BUTTON,
-      motionEvent,
+      InputMethod.TOUCH,
       task,
-      expectedBounds.height(),
       expectedBounds.width(),
+      expectedBounds.height(),
       displayController
     )
   }
@@ -3577,7 +3604,7 @@
     val bounds = Rect(0, 0, 100, 100)
     val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
 
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
     assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isEqualTo(bounds)
     verify(desktopModeEventLogger, never()).logTaskResizingEnded(
       any(), any(), any(), any(),
@@ -3591,21 +3618,21 @@
     val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
 
     // Maximize
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
     task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
 
     // Restore
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
 
     // Assert bounds set to last bounds before maximize
     val wct = getLatestToggleResizeDesktopTaskWct()
     assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.MAXIMIZE_BUTTON,
-      motionEvent,
+      InputMethod.TOUCH,
       task,
-      boundsBeforeMaximize.height(),
       boundsBeforeMaximize.width(),
+      boundsBeforeMaximize.height(),
       displayController
     )
   }
@@ -3618,22 +3645,22 @@
     }
 
     // Maximize
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
     task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS.left,
       boundsBeforeMaximize.top, STABLE_BOUNDS.right, boundsBeforeMaximize.bottom)
 
     // Restore
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
 
     // Assert bounds set to last bounds before maximize
     val wct = getLatestToggleResizeDesktopTaskWct()
     assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.MAXIMIZE_BUTTON,
-      motionEvent,
+      InputMethod.TOUCH,
       task,
-      boundsBeforeMaximize.height(),
       boundsBeforeMaximize.width(),
+      boundsBeforeMaximize.height(),
       displayController
     )
   }
@@ -3646,22 +3673,22 @@
     }
 
     // Maximize
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
     task.configuration.windowConfiguration.bounds.set(boundsBeforeMaximize.left,
       STABLE_BOUNDS.top, boundsBeforeMaximize.right, STABLE_BOUNDS.bottom)
 
     // Restore
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
 
     // Assert bounds set to last bounds before maximize
     val wct = getLatestToggleResizeDesktopTaskWct()
     assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.MAXIMIZE_BUTTON,
-      motionEvent,
+      InputMethod.TOUCH,
       task,
-      boundsBeforeMaximize.height(),
       boundsBeforeMaximize.width(),
+      boundsBeforeMaximize.height(),
       displayController
     )
   }
@@ -3672,20 +3699,20 @@
     val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
 
     // Maximize
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
     task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
 
     // Restore
-    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+    controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
 
     // Assert last bounds before maximize removed after use
     assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.MAXIMIZE_BUTTON,
-      motionEvent,
+      InputMethod.TOUCH,
       task,
-      boundsBeforeMaximize.height(),
       boundsBeforeMaximize.width(),
+      boundsBeforeMaximize.height(),
       displayController
     )
   }
@@ -3724,26 +3751,6 @@
   }
 
   @Test
-  fun toggleImmersive_enter_movesToImmersive() {
-    val task = setUpFreeformTask(DEFAULT_DISPLAY)
-    taskRepository.setTaskInFullImmersiveState(DEFAULT_DISPLAY, task.taskId, false /* immersive */)
-
-    controller.toggleDesktopTaskFullImmersiveState(task)
-
-    verify(mMockDesktopImmersiveController).moveTaskToImmersive(task)
-  }
-
-  @Test
-  fun toggleImmersive_exit_movesToNonImmersive() {
-    val task = setUpFreeformTask(DEFAULT_DISPLAY)
-    taskRepository.setTaskInFullImmersiveState(DEFAULT_DISPLAY, task.taskId, true /* immersive */)
-
-    controller.toggleDesktopTaskFullImmersiveState(task)
-
-    verify(mMockDesktopImmersiveController).moveTaskToNonImmersive(task)
-  }
-
-  @Test
   @EnableFlags(FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
   fun onTaskInfoChanged_inImmersiveUnrequestsImmersive_exits() {
     val task = setUpFreeformTask(DEFAULT_DISPLAY)
@@ -3752,7 +3759,7 @@
     task.requestedVisibleTypes = WindowInsets.Type.statusBars()
     controller.onTaskInfoChanged(task)
 
-    verify(mMockDesktopImmersiveController).moveTaskToNonImmersive(task)
+    verify(mMockDesktopImmersiveController).moveTaskToNonImmersive(eq(task), any())
   }
 
   @Test
@@ -3764,7 +3771,20 @@
     task.requestedVisibleTypes = WindowInsets.Type.statusBars()
     controller.onTaskInfoChanged(task)
 
-    verify(mMockDesktopImmersiveController, never()).moveTaskToNonImmersive(task)
+    verify(mMockDesktopImmersiveController, never()).moveTaskToNonImmersive(eq(task), any())
+  }
+
+  @Test
+  @EnableFlags(FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+  fun onTaskInfoChanged_inImmersiveUnrequestsImmersive_inRecentsTransition_noExit() {
+    val task = setUpFreeformTask(DEFAULT_DISPLAY)
+    taskRepository.setTaskInFullImmersiveState(DEFAULT_DISPLAY, task.taskId, immersive = true)
+    recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_REQUESTED)
+
+    task.requestedVisibleTypes = WindowInsets.Type.statusBars()
+    controller.onTaskInfoChanged(task)
+
+    verify(mMockDesktopImmersiveController, never()).moveTaskToNonImmersive(eq(task), any())
   }
 
   @Test
@@ -3774,7 +3794,7 @@
     val runOnStartTransit = RunOnStartTransitionCallback()
     val transition = Binder()
     whenever(mMockDesktopImmersiveController
-      .exitImmersiveIfApplicable(wct, task.displayId, task.taskId))
+      .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any()))
       .thenReturn(
         ExitResult.Exit(
         exitingTask = 5,
@@ -3785,7 +3805,7 @@
     controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN)
 
     verify(mMockDesktopImmersiveController)
-      .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)
+      .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any())
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3796,7 +3816,7 @@
     val runOnStartTransit = RunOnStartTransitionCallback()
     val transition = Binder()
     whenever(mMockDesktopImmersiveController
-      .exitImmersiveIfApplicable(wct, task.displayId, task.taskId))
+      .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any()))
       .thenReturn(
         ExitResult.Exit(
         exitingTask = 5,
@@ -3807,7 +3827,7 @@
     controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN)
 
     verify(mMockDesktopImmersiveController)
-      .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)
+      .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any())
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3817,7 +3837,7 @@
     val runOnStartTransit = RunOnStartTransitionCallback()
     val transition = Binder()
     whenever(mMockDesktopImmersiveController
-      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)))
+      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId), any()))
       .thenReturn(
         ExitResult.Exit(
         exitingTask = 5,
@@ -3830,7 +3850,7 @@
     controller.moveTaskToFront(task.taskId, remoteTransition = null)
 
     verify(mMockDesktopImmersiveController)
-      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))
+      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId), any())
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3840,7 +3860,7 @@
     val runOnStartTransit = RunOnStartTransitionCallback()
     val transition = Binder()
     whenever(mMockDesktopImmersiveController
-      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)))
+      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId), any()))
       .thenReturn(
         ExitResult.Exit(
         exitingTask = 5,
@@ -3853,7 +3873,7 @@
     controller.moveTaskToFront(task.taskId, remoteTransition = null)
 
     verify(mMockDesktopImmersiveController)
-      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))
+      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId), any())
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3867,7 +3887,7 @@
     controller.handleRequest(binder, createTransition(task))
 
     verify(mMockDesktopImmersiveController)
-      .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId))
+      .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId), any())
   }
 
   @Test
@@ -3879,7 +3899,7 @@
     controller.handleRequest(binder, createTransition(task))
 
     verify(mMockDesktopImmersiveController)
-      .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId))
+      .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId), any())
   }
 
   @Test
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 456b50d..797b125 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
@@ -42,7 +42,7 @@
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.ShellExecutor
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
 import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
index 52da7fb..866d1b3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
@@ -27,62 +27,56 @@
 import com.android.wm.shell.MockToken
 import com.android.wm.shell.TestRunningTaskInfoBuilder
 
-class DesktopTestHelpers {
-    companion object {
-        /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */
-        @JvmStatic
-        @JvmOverloads
-        fun createFreeformTask(
-                displayId: Int = DEFAULT_DISPLAY,
-                bounds: Rect? = null
-        ): RunningTaskInfo {
-            return TestRunningTaskInfoBuilder()
-                    .setDisplayId(displayId)
-                    .setToken(MockToken().token())
-                    .setActivityType(ACTIVITY_TYPE_STANDARD)
-                    .setWindowingMode(WINDOWING_MODE_FREEFORM)
-                    .setLastActiveTime(100)
-                    .apply { bounds?.let { setBounds(it) }}
-                    .build()
-        }
+object DesktopTestHelpers {
+    /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */
+    fun createFreeformTask(
+        displayId: Int = DEFAULT_DISPLAY,
+        bounds: Rect? = null,
+    ): RunningTaskInfo =
+        TestRunningTaskInfoBuilder()
+            .setDisplayId(displayId)
+            .setToken(MockToken().token())
+            .setActivityType(ACTIVITY_TYPE_STANDARD)
+            .setWindowingMode(WINDOWING_MODE_FREEFORM)
+            .setLastActiveTime(100)
+            .apply { bounds?.let { setBounds(it) } }
+            .build()
 
-        /** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
-        @JvmStatic
-        @JvmOverloads
-        fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
-            return TestRunningTaskInfoBuilder()
-                .setDisplayId(displayId)
-                .setToken(MockToken().token())
-                .setActivityType(ACTIVITY_TYPE_STANDARD)
-                .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
-                .setLastActiveTime(100)
-                .build()
-        }
+    fun createFullscreenTaskBuilder(displayId: Int = DEFAULT_DISPLAY): TestRunningTaskInfoBuilder =
+        TestRunningTaskInfoBuilder()
+            .setDisplayId(displayId)
+            .setToken(MockToken().token())
+            .setActivityType(ACTIVITY_TYPE_STANDARD)
+            .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+            .setLastActiveTime(100)
 
-        /** Create a task that has windowing mode set to [WINDOWING_MODE_MULTI_WINDOW] */
-        @JvmStatic
-        @JvmOverloads
-        fun createSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
-            return TestRunningTaskInfoBuilder()
-                .setDisplayId(displayId)
-                .setToken(MockToken().token())
-                .setActivityType(ACTIVITY_TYPE_STANDARD)
-                .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW)
-                .setLastActiveTime(100)
-                .build()
-        }
+    /** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
+    fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo =
+        createFullscreenTaskBuilder(displayId).build()
 
-        /** Create a new home task */
-        @JvmStatic
-        @JvmOverloads
-        fun createHomeTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
-            return TestRunningTaskInfoBuilder()
-                    .setDisplayId(displayId)
-                    .setToken(MockToken().token())
-                    .setActivityType(ACTIVITY_TYPE_HOME)
-                    .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
-                    .setLastActiveTime(100)
-                    .build()
-        }
-    }
-}
\ No newline at end of file
+    /** Create a task that has windowing mode set to [WINDOWING_MODE_MULTI_WINDOW] */
+    fun createSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo =
+        TestRunningTaskInfoBuilder()
+            .setDisplayId(displayId)
+            .setToken(MockToken().token())
+            .setActivityType(ACTIVITY_TYPE_STANDARD)
+            .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW)
+            .setLastActiveTime(100)
+            .build()
+
+    fun createHomeTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo =
+        TestRunningTaskInfoBuilder()
+            .setDisplayId(displayId)
+            .setToken(MockToken().token())
+            .setActivityType(ACTIVITY_TYPE_HOME)
+            .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+            .setLastActiveTime(100)
+            .build()
+
+    /** Create a new System Modal task, i.e. a task with a single transparent activity. */
+    fun createSystemModalTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo =
+        createFullscreenTaskBuilder(displayId)
+            .setTopActivityTransparent(true)
+            .setNumActivities(1)
+            .build()
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
new file mode 100644
index 0000000..226e974
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode.compatui
+
+import android.os.Binder
+import android.testing.AndroidTestingRunner
+import android.view.SurfaceControl
+import android.view.WindowManager.TRANSIT_CHANGE
+import android.view.WindowManager.TRANSIT_CLOSE
+import android.view.WindowManager.TRANSIT_OPEN
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTaskBuilder
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createSystemModalTask
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.transition.TransitionInfoBuilder
+import com.android.wm.shell.transition.Transitions
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SystemModalsTransitionHandlerTest : ShellTestCase() {
+    private val mainExecutor = mock<ShellExecutor>()
+    private val animExecutor = mock<ShellExecutor>()
+    private val shellInit = mock<ShellInit>()
+    private val transitions = mock<Transitions>()
+    private val desktopRepository = mock<DesktopRepository>()
+    private val startT = mock<SurfaceControl.Transaction>()
+    private val finishT = mock<SurfaceControl.Transaction>()
+
+    private lateinit var transitionHandler: SystemModalsTransitionHandler
+
+    @Before
+    fun setUp() {
+        // Simulate having one Desktop task so that we see Desktop Mode as active
+        whenever(desktopRepository.getVisibleTaskCount(anyInt())).thenReturn(1)
+        transitionHandler = createTransitionHandler()
+    }
+
+    private fun createTransitionHandler() =
+        SystemModalsTransitionHandler(
+            context,
+            mainExecutor,
+            animExecutor,
+            shellInit,
+            transitions,
+            desktopRepository,
+        )
+
+    @Test
+    fun instantiate_addsInitCallback() {
+        verify(shellInit).addInitCallback(any(), any<SystemModalsTransitionHandler>())
+    }
+
+    @Test
+    fun startAnimation_desktopNotActive_doesNotAnimate() {
+        whenever(desktopRepository.getVisibleTaskCount(anyInt())).thenReturn(1)
+        val info =
+            TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(TRANSIT_OPEN, createSystemModalTask())
+                .build()
+
+        assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isTrue()
+    }
+
+    @Test
+    fun startAnimation_launchingSystemModal_animates() {
+        val info =
+            TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(TRANSIT_OPEN, createSystemModalTask())
+                .build()
+
+        assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isTrue()
+    }
+
+    @Test
+    fun startAnimation_nonLaunchingSystemModal_doesNotAnimate() {
+        val info =
+            TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(TRANSIT_CHANGE, createSystemModalTask())
+                .build()
+
+        assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isFalse()
+    }
+
+    @Test
+    fun startAnimation_launchingFullscreenTask_doesNotAnimate() {
+        val info =
+            TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(TRANSIT_OPEN, createFullscreenTask())
+                .build()
+
+        assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isFalse()
+    }
+
+    @Test
+    fun startAnimation_closingSystemModal_animates() {
+        val info =
+            TransitionInfoBuilder(TRANSIT_CLOSE)
+                .addChange(TRANSIT_CLOSE, createSystemModalTask())
+                .build()
+
+        assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isTrue()
+    }
+
+    @Test
+    fun startAnimation_closingFullscreenTask_doesNotAnimate() {
+        val info =
+            TransitionInfoBuilder(TRANSIT_CLOSE)
+                .addChange(TRANSIT_CLOSE, createFullscreenTask())
+                .build()
+
+        assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isFalse()
+    }
+
+    @Test
+    fun startAnimation_closingPreviouslyLaunchedSystemModal_animates() {
+        val systemModalTask = createSystemModalTask()
+        val nonModalSystemModalTask =
+            createFullscreenTaskBuilder().setTaskId(systemModalTask.taskId).build()
+        val launchInfo =
+            TransitionInfoBuilder(TRANSIT_OPEN).addChange(TRANSIT_OPEN, systemModalTask).build()
+        transitionHandler.startAnimation(Binder(), launchInfo, startT, finishT) {}
+        val closeInfo =
+            TransitionInfoBuilder(TRANSIT_CLOSE)
+                .addChange(TRANSIT_CLOSE, nonModalSystemModalTask)
+                .build()
+
+        assertThat(transitionHandler.startAnimation(Binder(), closeInfo, startT, finishT) {})
+            .isTrue()
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt
index d94186c..9c00c0c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt
@@ -175,13 +175,13 @@
 
   @Test
   @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION)
-  fun init_educationViewedAlready_shouldNotCallShowEducationTooltip() =
+  fun init_appHandleHintViewedAlready_shouldNotCallShowEducationTooltip() =
       testScope.runTest {
-        // App handle is visible but education has been viewed before. Should not show education
-        // tooltip.
-        // Mark education viewed.
+        // App handle is visible but app handle hint has been viewed before,
+        // should not show education tooltip.
+        // Mark app handle hint viewed.
         testDataStoreFlow.value =
-            createWindowingEducationProto(educationViewedTimestampMillis = 123L)
+            createWindowingEducationProto(appHandleHintViewedTimestampMillis = 123L)
         setShouldShowAppHandleEducation(true)
 
         // Simulate app handle visible.
@@ -194,13 +194,14 @@
 
   @Test
   @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION)
-  fun overridePrerequisite_educationViewedAlready_shouldCallShowEducationTooltip() =
+  fun overridePrerequisite_appHandleHintViewedAlready_shouldCallShowEducationTooltip() =
       testScope.runTest {
-        // App handle is visible but education has been viewed before. But as we are overriding
-        // prerequisite conditions, we should show education tooltip.
-        // Mark education viewed.
+        // App handle is visible but app handle hint has been viewed before.
+        // But as we are overriding prerequisite conditions, we should show app
+        // handle tooltip.
+        // Mark app handle hint viewed.
         testDataStoreFlow.value =
-            createWindowingEducationProto(educationViewedTimestampMillis = 123L)
+            createWindowingEducationProto(appHandleHintViewedTimestampMillis = 123L)
         val systemPropertiesKey =
             "persist.desktop_windowing_app_handle_education_override_conditions"
         whenever(SystemProperties.getBoolean(eq(systemPropertiesKey), anyBoolean()))
@@ -217,7 +218,7 @@
 
   @Test
   @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION)
-  fun init_appHandleExpanded_shouldMarkFeatureViewed() =
+  fun init_appHandleExpanded_shouldMarkAppHandleHintUsed() =
       testScope.runTest {
         setShouldShowAppHandleEducation(false)
 
@@ -226,12 +227,12 @@
         // Wait for some time before verifying
         waitForBufferDelay()
 
-        verify(mockDataStoreRepository, times(1)).updateFeatureUsedTimestampMillis(eq(true))
+        verify(mockDataStoreRepository, times(1)).updateAppHandleHintUsedTimestampMillis(eq(true))
       }
 
   @Test
   @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION)
-  fun init_showFirstTooltip_shouldMarkEducationViewed() =
+  fun init_showFirstTooltip_shouldMarkAppHandleHintViewed() =
       testScope.runTest {
         // App handle is visible. Should show education tooltip.
         setShouldShowAppHandleEducation(true)
@@ -241,7 +242,7 @@
         // Wait for first tooltip to showup.
         waitForBufferDelay()
 
-        verify(mockDataStoreRepository, times(1)).updateEducationViewedTimestampMillis(eq(true))
+        verify(mockDataStoreRepository, times(1)).updateAppHandleHintViewedTimestampMillis(eq(true))
       }
 
   @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationDatastoreRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationDatastoreRepositoryTest.kt
index c286544..963890d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationDatastoreRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationDatastoreRepositoryTest.kt
@@ -81,8 +81,8 @@
       runTest(StandardTestDispatcher()) {
         val windowingEducationProto =
             createWindowingEducationProto(
-                educationViewedTimestampMillis = 123L,
-                featureUsedTimestampMillis = 124L,
+                appHandleHintViewedTimestampMillis = 123L,
+                appHandleHintUsedTimestampMillis = 124L,
                 appUsageStats = mapOf(GMAIL_PACKAGE_NAME to 2),
                 appUsageStatsLastUpdateTimestampMillis = 125L)
         testDatastore.updateData { windowingEducationProto }
@@ -110,20 +110,20 @@
       }
 
   @Test
-  fun updateEducationViewedTimestampMillis_updatesDatastoreProto() =
+  fun updateAppHandleHintViewedTimestampMillis_updatesDatastoreProto() =
       runTest(StandardTestDispatcher()) {
-        datastoreRepository.updateEducationViewedTimestampMillis(true)
+        datastoreRepository.updateAppHandleHintViewedTimestampMillis(true)
 
-        val result = testDatastore.data.first().hasEducationViewedTimestampMillis()
+        val result = testDatastore.data.first().hasAppHandleHintViewedTimestampMillis()
         assertThat(result).isEqualTo(true)
       }
 
   @Test
-  fun updateFeatureUsedTimestampMillis_updatesDatastoreProto() =
+  fun updateAppHandleHintUsedTimestampMillis_updatesDatastoreProto() =
       runTest(StandardTestDispatcher()) {
-        datastoreRepository.updateFeatureUsedTimestampMillis(true)
+        datastoreRepository.updateAppHandleHintUsedTimestampMillis(true)
 
-        val result = testDatastore.data.first().hasFeatureUsedTimestampMillis()
+        val result = testDatastore.data.first().hasAppHandleHintUsedTimestampMillis()
         assertThat(result).isEqualTo(true)
       }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilterTest.kt
index a3e74e8..e5edd69 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilterTest.kt
@@ -134,12 +134,12 @@
   }
 
   @Test
-  fun shouldShowAppHandleEducation_educationViewedBefore_returnsFalse() = runTest {
-    // Education has been viewed before, hence #shouldShowAppHandleEducation should return false
+  fun shouldShowAppHandleEducation_appHandleHintViewedBefore_returnsFalse() = runTest {
+    // App handle hint has been viewed before, hence #shouldShowAppHandleEducation should return false
     val windowingEducationProto =
         createWindowingEducationProto(
             appUsageStats = mapOf(GMAIL_PACKAGE_NAME to 4),
-            educationViewedTimestampMillis = 123L,
+            appHandleHintViewedTimestampMillis = 123L,
             appUsageStatsLastUpdateTimestampMillis = Long.MAX_VALUE)
     `when`(datastoreRepository.windowingEducationProto()).thenReturn(windowingEducationProto)
 
@@ -149,12 +149,12 @@
   }
 
   @Test
-  fun shouldShowAppHandleEducation_featureUsedBefore_returnsFalse() = runTest {
-    // Feature has been used before, hence #shouldShowAppHandleEducation should return false
+  fun shouldShowAppHandleEducation_appHandleHintUsedBefore_returnsFalse() = runTest {
+    // App handle hint has been used before, hence #shouldShowAppHandleEducation should return false
     val windowingEducationProto =
         createWindowingEducationProto(
             appUsageStats = mapOf(GMAIL_PACKAGE_NAME to 4),
-            featureUsedTimestampMillis = 123L,
+            appHandleHintUsedTimestampMillis = 123L,
             appUsageStatsLastUpdateTimestampMillis = Long.MAX_VALUE)
     `when`(datastoreRepository.windowingEducationProto()).thenReturn(windowingEducationProto)
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 12c3978..68c8aab 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -22,6 +22,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.launcher3.Flags.FLAG_ENABLE_REFACTOR_TASK_THUMBNAIL;
 import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
 
@@ -51,6 +52,7 @@
 import android.app.KeyguardManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -72,6 +74,7 @@
 import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopWallpaperActivity;
 import com.android.wm.shell.shared.GroupedTaskInfo;
 import com.android.wm.shell.shared.ShellSharedConstants;
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -237,6 +240,19 @@
                 t3.taskId, -1);
     }
 
+    @EnableFlags(FLAG_ENABLE_REFACTOR_TASK_THUMBNAIL)
+    @Test
+    public void testGetRecentTasks_removesDesktopWallpaperActivity() {
+        RecentTaskInfo t1 = makeTaskInfo(1);
+        RecentTaskInfo desktopWallpaperTaskInfo = makeDesktopWallpaperTaskInfo(2);
+        RecentTaskInfo t3 = makeTaskInfo(3);
+        setRawList(t1, desktopWallpaperTaskInfo, t3);
+
+        ArrayList<GroupedTaskInfo> recentTasks =
+                mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+        assertGroupedTasksListEquals(recentTasks, t1.taskId, -1, t3.taskId, -1);
+    }
+
     @Test
     public void testGetRecentTasks_withPairs() {
         RecentTaskInfo t1 = makeTaskInfo(1);
@@ -691,11 +707,25 @@
     private RecentTaskInfo makeTaskInfo(int taskId) {
         RecentTaskInfo info = new RecentTaskInfo();
         info.taskId = taskId;
+
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName("com." + taskId, "Activity" + taskId));
+        info.baseIntent = intent;
+
         info.lastNonFullscreenBounds = new Rect();
         return info;
     }
 
     /**
+     * Helper to create a desktop wallpaper activity with a given task id.
+     */
+    private RecentTaskInfo makeDesktopWallpaperTaskInfo(int taskId) {
+        RecentTaskInfo info = makeTaskInfo(taskId);
+        info.baseIntent.setComponent(DesktopWallpaperActivity.getWallpaperActivityComponent());
+        return info;
+    }
+
+    /**
      * Helper to create a running task with a given task id.
      */
     private ActivityManager.RunningTaskInfo makeRunningTaskInfo(int taskId) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
index 6087763..f0f5fe1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
@@ -16,7 +16,16 @@
 
 package com.android.wm.shell.recents;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_START_RECENTS_TRANSITION;
+
+import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
@@ -27,6 +36,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.IApplicationThread;
 import android.app.KeyguardManager;
@@ -38,7 +48,10 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.platform.test.flag.junit.SetFlagsRule;
+import android.view.SurfaceControl;
+import android.window.TransitionInfo;
 
+import androidx.annotation.NonNull;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -47,6 +60,7 @@
 import com.android.internal.os.IResultReceiver;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestRunningTaskInfoBuilder;
 import com.android.wm.shell.TestShellExecutor;
 import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.TaskStackListenerImpl;
@@ -56,7 +70,9 @@
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.HomeTransitionObserver;
+import com.android.wm.shell.transition.TransitionInfoBuilder;
 import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.util.StubTransaction;
 
 import org.junit.After;
 import org.junit.Before;
@@ -93,6 +109,8 @@
     private IRecentTasksListener mRecentTasksListener;
     @Mock
     private TaskStackTransitionObserver mTaskStackTransitionObserver;
+    @Mock
+    private Transitions mTransitions;
 
     @Rule
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -129,10 +147,9 @@
                 null /* sizeCompatUI */, Optional.empty(), Optional.of(mRecentTasksController),
                 mMainExecutor);
 
-        final Transitions transitions = mock(Transitions.class);
-        doReturn(mMainExecutor).when(transitions).getMainExecutor();
+        doReturn(mMainExecutor).when(mTransitions).getMainExecutor();
         mRecentsTransitionHandler = new RecentsTransitionHandler(mShellInit, mShellTaskOrganizer,
-                transitions, mRecentTasksController, mock(HomeTransitionObserver.class));
+                mTransitions, mRecentTasksController, mock(HomeTransitionObserver.class));
 
         mShellInit.init();
     }
@@ -146,12 +163,8 @@
     public void testStartSyntheticRecentsTransition_callsOnAnimationStartAndFinishCallback() throws Exception {
         final IRecentsAnimationRunner runner = mock(IRecentsAnimationRunner.class);
         final IResultReceiver finishCallback = mock(IResultReceiver.class);
-        doReturn(new Binder()).when(runner).asBinder();
-        Bundle options = new Bundle();
-        options.putBoolean("is_synthetic_recents_transition", true);
-        IBinder transition = mRecentsTransitionHandler.startRecentsTransition(
-                mock(PendingIntent.class), new Intent(), options, mock(IApplicationThread.class),
-                runner);
+
+        final IBinder transition = startRecentsTransition(/* synthetic= */ true, runner);
         verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any());
 
         // Finish and verify no transition remains and that the provided finish callback is called
@@ -165,12 +178,8 @@
     @Test
     public void testStartSyntheticRecentsTransition_callsOnAnimationCancel() throws Exception {
         final IRecentsAnimationRunner runner = mock(IRecentsAnimationRunner.class);
-        doReturn(new Binder()).when(runner).asBinder();
-        Bundle options = new Bundle();
-        options.putBoolean("is_synthetic_recents_transition", true);
-        IBinder transition = mRecentsTransitionHandler.startRecentsTransition(
-                mock(PendingIntent.class), new Intent(), options, mock(IApplicationThread.class),
-                runner);
+
+        final IBinder transition = startRecentsTransition(/* synthetic= */ true, runner);
         verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any());
 
         mRecentsTransitionHandler.findController(transition).cancel("test");
@@ -178,4 +187,137 @@
         verify(runner).onAnimationCanceled(any(), any());
         assertNull(mRecentsTransitionHandler.findController(transition));
     }
+
+    @Test
+    public void testStartTransition_updatesStateListeners() {
+        final TestTransitionStateListener listener = new TestTransitionStateListener();
+        mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+        startRecentsTransition(/* synthetic= */ false);
+        mMainExecutor.flushAll();
+
+        assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_REQUESTED);
+    }
+
+    @Test
+    public void testStartAnimation_updatesStateListeners() {
+        final TestTransitionStateListener listener = new TestTransitionStateListener();
+        mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+        final IBinder transition = startRecentsTransition(/* synthetic= */ false);
+        mRecentsTransitionHandler.startAnimation(
+                transition, createTransitionInfo(), new StubTransaction(), new StubTransaction(),
+                mock(Transitions.TransitionFinishCallback.class));
+        mMainExecutor.flushAll();
+
+        assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_ANIMATING);
+    }
+
+    @Test
+    public void testFinishTransition_updatesStateListeners() {
+        final TestTransitionStateListener listener = new TestTransitionStateListener();
+        mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+        final IBinder transition = startRecentsTransition(/* synthetic= */ false);
+        mRecentsTransitionHandler.startAnimation(
+                transition, createTransitionInfo(), new StubTransaction(), new StubTransaction(),
+                mock(Transitions.TransitionFinishCallback.class));
+        mRecentsTransitionHandler.findController(transition).finish(true /* toHome */,
+                false /* sendUserLeaveHint */, mock(IResultReceiver.class));
+        mMainExecutor.flushAll();
+
+        assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_NOT_RUNNING);
+    }
+
+    @Test
+    public void testCancelTransition_updatesStateListeners() {
+        final TestTransitionStateListener listener = new TestTransitionStateListener();
+        mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+        final IBinder transition = startRecentsTransition(/* synthetic= */ false);
+        mRecentsTransitionHandler.findController(transition).cancel("test");
+        mMainExecutor.flushAll();
+
+        assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_NOT_RUNNING);
+    }
+
+    @Test
+    public void testStartAnimation_synthetic_updatesStateListeners() {
+        final TestTransitionStateListener listener = new TestTransitionStateListener();
+        mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+        startRecentsTransition(/* synthetic= */ true);
+        mMainExecutor.flushAll();
+
+        assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_ANIMATING);
+    }
+
+    @Test
+    public void testFinishTransition_synthetic_updatesStateListeners() {
+        final TestTransitionStateListener listener = new TestTransitionStateListener();
+        mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+        final IBinder transition = startRecentsTransition(/* synthetic= */ true);
+        mRecentsTransitionHandler.findController(transition).finish(true /* toHome */,
+                false /* sendUserLeaveHint */, mock(IResultReceiver.class));
+        mMainExecutor.flushAll();
+
+        assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_NOT_RUNNING);
+    }
+
+    @Test
+    public void testCancelTransition_synthetic_updatesStateListeners() {
+        final TestTransitionStateListener listener = new TestTransitionStateListener();
+        mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+        final IBinder transition = startRecentsTransition(/* synthetic= */ true);
+        mRecentsTransitionHandler.findController(transition).cancel("test");
+        mMainExecutor.flushAll();
+
+        assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_NOT_RUNNING);
+    }
+
+    private IBinder startRecentsTransition(boolean synthetic) {
+        return startRecentsTransition(synthetic, mock(IRecentsAnimationRunner.class));
+    }
+
+    private IBinder startRecentsTransition(boolean synthetic,
+            @NonNull IRecentsAnimationRunner runner) {
+        doReturn(new Binder()).when(runner).asBinder();
+        final Bundle options = new Bundle();
+        options.putBoolean("is_synthetic_recents_transition", synthetic);
+        final IBinder transition = new Binder();
+        when(mTransitions.startTransition(anyInt(), any(), any())).thenReturn(transition);
+        return mRecentsTransitionHandler.startRecentsTransition(
+                mock(PendingIntent.class), new Intent(), options, mock(IApplicationThread.class),
+                runner);
+    }
+
+    private TransitionInfo createTransitionInfo() {
+        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder()
+                .setTopActivityType(ACTIVITY_TYPE_HOME)
+                .build();
+        final TransitionInfo.Change homeChange = new TransitionInfo.Change(
+                task.token, new SurfaceControl());
+        homeChange.setMode(TRANSIT_TO_FRONT);
+        homeChange.setTaskInfo(task);
+        return new TransitionInfoBuilder(TRANSIT_START_RECENTS_TRANSITION)
+                .addChange(homeChange)
+                .build();
+    }
+
+    private static class TestTransitionStateListener implements RecentsTransitionStateListener {
+        @RecentsTransitionState
+        private int mState = TRANSITION_STATE_NOT_RUNNING;
+
+        @Override
+        public void onTransitionStateChanged(int state) {
+            mState = state;
+        }
+
+        @RecentsTransitionState
+        int getState() {
+            return mState;
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 4f6f3c6..1e739cd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -34,6 +34,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -296,7 +297,8 @@
     public void testFinishEnterSplitScreen_applySurfaceLayout() {
         mStageCoordinator.finishEnterSplitScreen(new SurfaceControl.Transaction());
 
-        verify(mSplitLayout).applySurfaceChanges(any(), any(), any(), any(), any(), eq(false));
+        verify(mSplitLayout, atLeastOnce())
+                .applySurfaceChanges(any(), any(), any(), any(), any(), eq(false));
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/TransitionObserverTestUtils.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/TransitionObserverTestUtils.kt
index 3e26ee0..0e15668 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/TransitionObserverTestUtils.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/TransitionObserverTestUtils.kt
@@ -36,7 +36,6 @@
 import android.window.WindowContainerToken
 import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn
 import com.android.wm.shell.transition.Transitions.TransitionObserver
-import org.mockito.Mockito
 import org.mockito.kotlin.mock
 
 @DslMarker
@@ -93,10 +92,10 @@
  */
 class TransitionObserverInputBuilder : TransitionObserverTestStep {
 
-    private val transition = Mockito.mock(IBinder::class.java)
+    private val transition = mock<IBinder>()
     private var transitionInfo: TransitionInfo? = null
-    private val startTransaction = Mockito.mock(Transaction::class.java)
-    private val finishTransaction = Mockito.mock(Transaction::class.java)
+    private val startTransaction = mock<Transaction>()
+    private val finishTransaction = mock<Transaction>()
 
     fun buildTransitionInfo(
         @TransitionType type: Int = TRANSIT_NONE,
@@ -143,7 +142,7 @@
             taskId = id
             displayId = DEFAULT_DISPLAY
             configuration.windowConfiguration.windowingMode = windowingMode
-            token = WindowContainerToken(Mockito.mock(IWindowContainerToken::class.java))
+            token = WindowContainerToken(mock<IWindowContainerToken>())
             baseIntent = Intent().apply {
                 component = ComponentName("package", "component.name")
             }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/WindowingEducationTestUtils.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/WindowingEducationTestUtils.kt
index 99e8295..b9d91e7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/WindowingEducationTestUtils.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/WindowingEducationTestUtils.kt
@@ -78,18 +78,18 @@
  * Any fields without corresponding parameters will retain their default values.
  */
 fun createWindowingEducationProto(
-    educationViewedTimestampMillis: Long? = null,
-    featureUsedTimestampMillis: Long? = null,
+    appHandleHintViewedTimestampMillis: Long? = null,
+    appHandleHintUsedTimestampMillis: Long? = null,
     appUsageStats: Map<String, Int>? = null,
     appUsageStatsLastUpdateTimestampMillis: Long? = null
 ): WindowingEducationProto =
     WindowingEducationProto.newBuilder()
         .apply {
-          if (educationViewedTimestampMillis != null) {
-            setEducationViewedTimestampMillis(educationViewedTimestampMillis)
+          if (appHandleHintViewedTimestampMillis != null) {
+            setAppHandleHintViewedTimestampMillis(appHandleHintViewedTimestampMillis)
           }
-          if (featureUsedTimestampMillis != null) {
-            setFeatureUsedTimestampMillis(featureUsedTimestampMillis)
+          if (appHandleHintUsedTimestampMillis != null) {
+            setAppHandleHintUsedTimestampMillis(appHandleHintUsedTimestampMillis)
           }
           setAppHandleEducation(
               createAppHandleEducationProto(appUsageStats, appUsageStatsLastUpdateTimestampMillis))
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 78fb4b1..153be07 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -59,6 +59,8 @@
 import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
 import com.android.window.flags.Flags
 import com.android.wm.shell.R
+import com.android.wm.shell.desktopmode.DesktopImmersiveController
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
 import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
@@ -396,9 +398,11 @@
         maxOrRestoreListenerCaptor.value.invoke()
 
         verify(mockDesktopTasksController).toggleDesktopTaskSize(
-            decor.mTaskInfo,
-            ResizeTrigger.MAXIMIZE_MENU,
-            null
+            eq(decor.mTaskInfo),
+            eq(ResizeTrigger.MAXIMIZE_MENU),
+            eq(InputMethod.UNKNOWN_INPUT_METHOD),
+            any(),
+            any()
         )
     }
 
@@ -432,7 +436,7 @@
             eq(decor.mTaskInfo),
             eq(SnapPosition.LEFT),
             eq(ResizeTrigger.SNAP_LEFT_MENU),
-            eq(null),
+            eq(InputMethod.UNKNOWN_INPUT_METHOD),
             eq(decor)
         )
     }
@@ -468,7 +472,7 @@
             eq(decor.mTaskInfo),
             eq(SnapPosition.LEFT),
             eq(ResizeTrigger.SNAP_LEFT_MENU),
-            eq(null),
+            eq(InputMethod.UNKNOWN_INPUT_METHOD),
             eq(decor),
         )
     }
@@ -489,7 +493,7 @@
         verify(mockDesktopTasksController, never())
             .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.LEFT),
                 eq(ResizeTrigger.MAXIMIZE_BUTTON),
-                eq(null),
+                eq(InputMethod.UNKNOWN_INPUT_METHOD),
                 eq(decor),
             )
     }
@@ -509,7 +513,7 @@
             eq(decor.mTaskInfo),
             eq(SnapPosition.RIGHT),
             eq(ResizeTrigger.SNAP_RIGHT_MENU),
-            eq(null),
+            eq(InputMethod.UNKNOWN_INPUT_METHOD),
             eq(decor),
         )
     }
@@ -545,7 +549,7 @@
             eq(decor.mTaskInfo),
             eq(SnapPosition.RIGHT),
             eq(ResizeTrigger.SNAP_RIGHT_MENU),
-            eq(null),
+            eq(InputMethod.UNKNOWN_INPUT_METHOD),
             eq(decor),
         )
     }
@@ -566,7 +570,7 @@
         verify(mockDesktopTasksController, never())
             .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.RIGHT),
                 eq(ResizeTrigger.MAXIMIZE_BUTTON),
-                eq(null),
+                eq(InputMethod.UNKNOWN_INPUT_METHOD),
                 eq(decor),
         )
     }
@@ -999,7 +1003,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
-    fun testMaximizeButtonClick_requestingImmersive_togglesDesktopImmersiveState() {
+    fun testImmersiveButtonClick_entersImmersiveMode() {
         val onClickListenerCaptor = forClass(View.OnClickListener::class.java)
                 as ArgumentCaptor<View.OnClickListener>
         val decor = createOpenTaskDecoration(
@@ -1009,11 +1013,35 @@
         )
         val view = mock(View::class.java)
         whenever(view.id).thenReturn(R.id.maximize_window)
+        whenever(mockDesktopRepository.isTaskInFullImmersiveState(decor.mTaskInfo.taskId))
+            .thenReturn(false)
 
         onClickListenerCaptor.value.onClick(view)
 
-        verify(mockDesktopTasksController)
-            .toggleDesktopTaskFullImmersiveState(decor.mTaskInfo)
+        verify(mockDesktopImmersiveController).moveTaskToImmersive(decor.mTaskInfo)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+    fun testImmersiveRestoreButtonClick_exitsImmersiveMode() {
+        val onClickListenerCaptor = forClass(View.OnClickListener::class.java)
+                as ArgumentCaptor<View.OnClickListener>
+        val decor = createOpenTaskDecoration(
+            windowingMode = WINDOWING_MODE_FREEFORM,
+            onCaptionButtonClickListener = onClickListenerCaptor,
+            requestingImmersive = true,
+        )
+        val view = mock(View::class.java)
+        whenever(view.id).thenReturn(R.id.maximize_window)
+        whenever(mockDesktopRepository.isTaskInFullImmersiveState(decor.mTaskInfo.taskId))
+            .thenReturn(true)
+
+        onClickListenerCaptor.value.onClick(view)
+
+        verify(mockDesktopImmersiveController).moveTaskToNonImmersive(
+            decor.mTaskInfo,
+            DesktopImmersiveController.ExitReason.USER_INTERACTION
+        )
     }
 
     @Test
@@ -1032,23 +1060,30 @@
         onClickListenerCaptor.value.onClick(view)
 
         verify(mockDesktopTasksController)
-            .toggleDesktopTaskSize(decor.mTaskInfo, ResizeTrigger.MAXIMIZE_BUTTON, null)
+            .toggleDesktopTaskSize(
+                eq(decor.mTaskInfo),
+                eq(ResizeTrigger.MAXIMIZE_BUTTON),
+                    eq(InputMethod.UNKNOWN_INPUT_METHOD),
+                any(),
+                any(),
+            )
     }
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
-    fun testImmersiveClick_togglesImmersiveState() {
+    fun testImmersiveMenuOptionClick_entersImmersiveMode() {
         val onImmersiveClickCaptor = argumentCaptor<() -> Unit>()
         val decor = createOpenTaskDecoration(
             windowingMode = WINDOWING_MODE_FREEFORM,
             onImmersiveOrRestoreListenerCaptor = onImmersiveClickCaptor,
             requestingImmersive = true,
         )
+        whenever(mockDesktopRepository.isTaskInFullImmersiveState(decor.mTaskInfo.taskId))
+            .thenReturn(false)
 
         onImmersiveClickCaptor.firstValue()
 
-        verify(mockDesktopTasksController)
-            .toggleDesktopTaskFullImmersiveState(decor.mTaskInfo)
+        verify(mockDesktopImmersiveController).moveTaskToImmersive(decor.mTaskInfo)
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
index 91eaada..080f496 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
@@ -54,7 +54,9 @@
 import com.android.wm.shell.common.MultiInstanceHelper
 import com.android.wm.shell.common.SyncTransactionQueue
 import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler
+import com.android.wm.shell.desktopmode.DesktopImmersiveController
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger
 import com.android.wm.shell.desktopmode.DesktopRepository
 import com.android.wm.shell.desktopmode.DesktopTasksController
 import com.android.wm.shell.desktopmode.DesktopTasksLimiter
@@ -111,6 +113,7 @@
     protected val displayInsetsController = mock<DisplayInsetsController>()
     protected val mockSyncQueue = mock<SyncTransactionQueue>()
     protected val mockDesktopTasksController = mock<DesktopTasksController>()
+    protected val mockDesktopImmersiveController = mock<DesktopImmersiveController>()
     protected val mockInputMonitor = mock<InputMonitor>()
     protected val mockTransitions = mock<Transitions>()
     internal val mockInputMonitorFactory =
@@ -182,6 +185,7 @@
             mockSyncQueue,
             mockTransitions,
             Optional.of(mockDesktopTasksController),
+            mockDesktopImmersiveController,
             mockGenericLinksParser,
             mockAssistContentRequester,
             mockMultiInstanceHelper,
@@ -199,7 +203,8 @@
             Optional.of(mockActivityOrientationChangeHandler),
             mockTaskPositionerFactory,
             mockFocusTransitionObserver,
-            desktopModeEventLogger
+            desktopModeEventLogger,
+            mock<DesktopModeUiEventLogger>()
         )
         desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController)
         whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index f653622..e390fbb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -265,8 +265,8 @@
         doReturn(defaultDisplay).when(mMockDisplayController).getDisplay(Display.DEFAULT_DISPLAY);
         doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt());
         when(mMockHandleMenuFactory.create(any(), any(), anyInt(), any(), any(), any(),
-                anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), any(),
-                anyInt(), anyInt(), anyInt(), anyInt()))
+                anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(),
+                any(), anyInt(), anyInt(), anyInt(), anyInt()))
                 .thenReturn(mMockHandleMenu);
         when(mMockMultiInstanceHelper.supportsMultiInstanceSplit(any())).thenReturn(false);
         when(mMockAppHeaderViewHolderFactory.create(any(), any(), any(), any(), any(), any(), any(),
@@ -1577,7 +1577,8 @@
     private void verifyHandleMenuCreated(@Nullable Uri uri) {
         verify(mMockHandleMenuFactory).create(any(), any(), anyInt(), any(), any(),
                 any(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(),
-                argThat(intent -> (uri == null && intent == null) || intent.getData().equals(uri)),
+                anyBoolean(), argThat(intent ->
+                        (uri == null && intent == null) || intent.getData().equals(uri)),
                 anyInt(), anyInt(), anyInt(), anyInt());
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
index e7d328e..479f156 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
@@ -63,6 +63,7 @@
     private static final int EDGE_RESIZE_HANDLE_INSET = 4;
     private static final int FINE_CORNER_SIZE = EDGE_RESIZE_THICKNESS * 2 + 10;
     private static final int LARGE_CORNER_SIZE = FINE_CORNER_SIZE + 10;
+    private static final int SMALL_OFFSET = 10;
     private static final DragResizeWindowGeometry GEOMETRY = new DragResizeWindowGeometry(
             TASK_CORNER_RADIUS, TASK_SIZE, EDGE_RESIZE_THICKNESS, EDGE_RESIZE_HANDLE_INSET,
             FINE_CORNER_SIZE, LARGE_CORNER_SIZE, DragResizeWindowGeometry.DisabledEdge.NONE);
@@ -147,15 +148,19 @@
         assertThat(region.contains(point.x + EDGE_RESIZE_THICKNESS, point.y)).isTrue();
         assertThat(region.contains(point.x - EDGE_RESIZE_THICKNESS, point.y)).isTrue();
         // Vertically along the edge is not contained.
-        assertThat(region.contains(point.x, point.y - EDGE_RESIZE_THICKNESS)).isFalse();
-        assertThat(region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS + 10)).isFalse();
+        assertThat(
+                region.contains(point.x, point.y - EDGE_RESIZE_THICKNESS - SMALL_OFFSET)).isFalse();
+        assertThat(
+                region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS + SMALL_OFFSET)).isFalse();
     }
 
     private static void verifyVerticalEdge(@NonNull Region region, @NonNull Point point) {
         assertThat(region.contains(point.x, point.y)).isTrue();
         // Horizontally along the edge is not contained.
-        assertThat(region.contains(point.x + EDGE_RESIZE_THICKNESS, point.y)).isFalse();
-        assertThat(region.contains(point.x - EDGE_RESIZE_THICKNESS, point.y)).isFalse();
+        assertThat(
+                region.contains(point.x + EDGE_RESIZE_THICKNESS + SMALL_OFFSET, point.y)).isFalse();
+        assertThat(
+                region.contains(point.x - EDGE_RESIZE_THICKNESS - SMALL_OFFSET, point.y)).isFalse();
         // Vertically along the edge is contained.
         assertThat(region.contains(point.x, point.y - EDGE_RESIZE_THICKNESS)).isTrue();
         assertThat(region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS)).isTrue();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
index 7ec2cbf..6babf81 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
@@ -266,8 +266,8 @@
             WindowManagerWrapper(mockWindowManager),
             layoutId, appIcon, appName, splitScreenController, shouldShowWindowingPill = true,
             shouldShowNewWindowButton = true, shouldShowManageWindowsButton = false,
-            shouldShowChangeAspectRatioButton = false, isBrowserApp = false,
-            null /* openInAppOrBrowserIntent */, captionWidth = HANDLE_WIDTH,
+            shouldShowChangeAspectRatioButton = false, shouldShowDesktopModeButton = true,
+            isBrowserApp = false, null /* openInAppOrBrowserIntent */, captionWidth = HANDLE_WIDTH,
             captionHeight = 50,
             captionX = captionX,
             captionY = 0,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
index d8c1a11..d290021 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
@@ -27,7 +27,7 @@
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger
 import com.android.wm.shell.desktopmode.DesktopRepository
 import com.android.wm.shell.desktopmode.DesktopTasksController
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
 import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
 import com.android.wm.shell.transition.Transitions
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
index 3143946..121e0e9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
@@ -122,6 +122,6 @@
 
     companion object {
         private val BOUNDS = Rect(1, 2, 3, 4)
-        private val CORNER_RADIUS = 28
+        private const val CORNER_RADIUS = 28
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index d7b971d..3b39f1e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -38,7 +38,7 @@
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
 import com.android.wm.shell.desktopmode.DesktopRepository
 import com.android.wm.shell.desktopmode.DesktopTasksController
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
 import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
 import com.android.wm.shell.transition.Transitions
@@ -124,7 +124,7 @@
 
     @Test
     fun taskTiled_toCorrectBounds_leftTile() {
-        val task1 = createFreeformTask()
+        val task1 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -151,7 +151,7 @@
     @Test
     fun taskTiled_toCorrectBounds_rightTile() {
         // Setup
-        val task1 = createFreeformTask()
+        val task1 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -177,7 +177,7 @@
 
     @Test
     fun taskTiled_notAnimated_whenTilingPositionNotChange() {
-        val task1 = createFreeformTask()
+        val task1 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -213,8 +213,8 @@
 
     @Test
     fun taskNotTiled_notBroughtToFront_tilingNotInitialised() {
-        val task1 = createFreeformTask()
-        val task2 = createFreeformTask()
+        val task1 = createVisibleTask()
+        val task2 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -236,9 +236,9 @@
 
     @Test
     fun taskNotTiled_notBroughtToFront_taskNotTiled() {
-        val task1 = createFreeformTask()
-        val task2 = createFreeformTask()
-        val task3 = createFreeformTask()
+        val task1 = createVisibleTask()
+        val task2 = createVisibleTask()
+        val task3 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -265,9 +265,9 @@
     }
 
     @Test
-    fun taskTiled_broughtToFront_alreadyInFrontNoAction() {
-        val task1 = createFreeformTask()
-        val task2 = createFreeformTask()
+    fun taskTiled_broughtToFront_alreadyInFrontStillReorder() {
+        val task1 = createVisibleTask()
+        val task2 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -275,6 +275,8 @@
         }
         whenever(context.resources).thenReturn(resources)
         whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width)
+        whenever(desktopRepository.isVisibleTask(eq(task1.taskId))).thenReturn(true)
+        whenever(desktopRepository.isVisibleTask(eq(task2.taskId))).thenReturn(true)
 
         tilingDecoration.onAppTiled(
             task1,
@@ -290,15 +292,15 @@
         )
         task1.isFocused = true
 
-        assertThat(tilingDecoration.moveTiledPairToFront(task1)).isFalse()
-        verify(transitions, never()).startTransition(any(), any(), any())
+        assertThat(tilingDecoration.moveTiledPairToFront(task1, isTaskFocused = true)).isTrue()
+        verify(transitions, times(1)).startTransition(eq(TRANSIT_TO_FRONT), any(), eq(null))
     }
 
     @Test
     fun taskTiled_broughtToFront_bringToFront() {
-        val task1 = createFreeformTask()
-        val task2 = createFreeformTask()
-        val task3 = createFreeformTask()
+        val task1 = createVisibleTask()
+        val task2 = createVisibleTask()
+        val task3 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
             (i.arguments.first() as Rect).set(stableBounds)
@@ -329,9 +331,9 @@
 
     @Test
     fun taskTiled_broughtToFront_taskInfoNotUpdated_bringToFront() {
-        val task1 = createFreeformTask()
-        val task2 = createFreeformTask()
-        val task3 = createFreeformTask()
+        val task1 = createVisibleTask()
+        val task2 = createVisibleTask()
+        val task3 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
             (i.arguments.first() as Rect).set(stableBounds)
@@ -361,8 +363,8 @@
     @Test
     fun taskTiledTasks_NotResized_BeforeTouchEndArrival() {
         // Setup
-        val task1 = createFreeformTask()
-        val task2 = createFreeformTask()
+        val task1 = createVisibleTask()
+        val task2 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -428,8 +430,8 @@
     @Test
     fun tiledTasksResizedUsingDividerHandle_shouldLogResizingEvents() {
         // Setup
-        val task1 = createFreeformTask()
-        val task2 = createFreeformTask()
+        val task1 = createVisibleTask()
+        val task2 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -464,8 +466,10 @@
         // this test, so we verify the same log twice.
         verify(desktopModeEventLogger, times(2)).logTaskResizingStarted(
             ResizeTrigger.TILING_DIVIDER,
-            motionEvent,
+            DesktopModeEventLogger.Companion.InputMethod.UNKNOWN_INPUT_METHOD,
             task1,
+            BOUNDS.width() / 2,
+            BOUNDS.height(),
             displayController,
         )
 
@@ -475,17 +479,17 @@
         // this test, so we verify the same log twice.
         verify(desktopModeEventLogger, times(2)).logTaskResizingEnded(
             ResizeTrigger.TILING_DIVIDER,
-            motionEvent,
+            DesktopModeEventLogger.Companion.InputMethod.UNKNOWN_INPUT_METHOD,
             task1,
-            BOUNDS.height(),
             BOUNDS.width(),
+            BOUNDS.height(),
             displayController,
         )
     }
 
     @Test
     fun taskTiled_shouldBeRemoved_whenTileBroken() {
-        val task1 = createFreeformTask()
+        val task1 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -514,8 +518,8 @@
 
     @Test
     fun taskNotTiled_shouldNotBeRemoved_whenNotTiled() {
-        val task1 = createFreeformTask()
-        val task2 = createFreeformTask()
+        val task1 = createVisibleTask()
+        val task2 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -543,8 +547,8 @@
 
     @Test
     fun tasksTiled_shouldBeRemoved_whenSessionDestroyed() {
-        val task1 = createFreeformTask()
-        val task2 = createFreeformTask()
+        val task1 = createVisibleTask()
+        val task2 = createVisibleTask()
         val stableBounds = STABLE_BOUNDS_MOCK
         whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -608,6 +612,11 @@
         return Rect(stableBounds.left, stableBounds.top, rightBound, stableBounds.bottom)
     }
 
+    private fun createVisibleTask() =
+        createFreeformTask().also {
+            whenever(desktopRepository.isVisibleTask(eq(it.taskId))).thenReturn(true)
+        }
+
     companion object {
         private val NON_STABLE_BOUNDS_MOCK = Rect(50, 55, 100, 100)
         private val STABLE_BOUNDS_MOCK = Rect(0, 0, 100, 100)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt
index 734815c..9a9d05a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt
@@ -19,9 +19,12 @@
 import android.graphics.Rect
 import android.os.SystemClock
 import android.testing.AndroidTestingRunner
+import android.util.Size
+import android.view.Display
 import android.view.InputDevice
 import android.view.LayoutInflater
 import android.view.MotionEvent
+import android.view.RoundedCorner
 import android.view.View
 import androidx.test.annotation.UiThreadTest
 import androidx.test.filters.SmallTest
@@ -46,16 +49,19 @@
     private val dividerMoveCallbackMock = mock<DividerMoveCallback>()
 
     private val viewMock = mock<View>()
+    private val display = mock<Display>()
+    private val roundedCorner = mock<RoundedCorner>()
 
     @Before
     @UiThreadTest
     fun setUp() {
+        whenever(display.getRoundedCorner(any())).thenReturn(roundedCorner)
+        whenever(roundedCorner.radius).thenReturn(CORNER_RADIUS)
         tilingDividerView =
             LayoutInflater.from(mContext).inflate(R.layout.tiling_split_divider, /* root= */ null)
                 as TilingDividerView
-        tilingDividerView.setup(dividerMoveCallbackMock, BOUNDS)
-        tilingDividerView.handleStartY = 0
-        tilingDividerView.handleEndY = 1500
+        tilingDividerView.setup(dividerMoveCallbackMock, DIVIDER_BOUNDS, HANDLE_SIZE)
+        tilingDividerView.handleY = 0..1500
     }
 
     @Test
@@ -130,6 +136,8 @@
     }
 
     companion object {
-        private val BOUNDS = Rect(0, 0, 1500, 1500)
+        private val DIVIDER_BOUNDS = Rect(15, 0, 35, 1500)
+        private val HANDLE_SIZE = Size(800, 300)
+        private const val CORNER_RADIUS = 15
     }
 }
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index 2d812d6..4dfe053 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -76,6 +76,7 @@
         result->fBaseWeight = resolvedFace->fBaseWeight;
         result->fAPIStyle = style;
         result->fStyle = computeRelativeStyle(result->fBaseWeight, style);
+        result->fIsVariationInstance = resolvedFace->fIsVariationInstance;
     }
     return result;
 }
@@ -88,6 +89,7 @@
         result->fBaseWeight = resolvedFace->fBaseWeight;
         result->fAPIStyle = computeAPIStyle(weight, italic);
         result->fStyle = computeMinikinStyle(weight, italic);
+        result->fIsVariationInstance = resolvedFace->fIsVariationInstance;
     }
     return result;
 }
@@ -109,6 +111,7 @@
         result->fBaseWeight = resolvedFace->fBaseWeight;
         result->fAPIStyle = resolvedFace->fAPIStyle;
         result->fStyle = resolvedFace->fStyle;
+        result->fIsVariationInstance = true;
     }
     return result;
 }
@@ -121,6 +124,7 @@
         result->fBaseWeight = weight;
         result->fAPIStyle = resolvedFace->fAPIStyle;
         result->fStyle = computeRelativeStyle(weight, result->fAPIStyle);
+        result->fIsVariationInstance = resolvedFace->fIsVariationInstance;
     }
     return result;
 }
@@ -170,6 +174,7 @@
     result->fBaseWeight = weight;
     result->fAPIStyle = computeAPIStyle(weight, italic);
     result->fStyle = computeMinikinStyle(weight, italic);
+    result->fIsVariationInstance = false;
     return result;
 }
 
diff --git a/libs/hwui/hwui/Typeface.h b/libs/hwui/hwui/Typeface.h
index 2c96c1a..97d1bf4 100644
--- a/libs/hwui/hwui/Typeface.h
+++ b/libs/hwui/hwui/Typeface.h
@@ -44,6 +44,9 @@
     // base weight in CSS-style units, 1..1000
     int fBaseWeight;
 
+    // True if the Typeface is already created for variation settings.
+    bool fIsVariationInstance;
+
     static const Typeface* resolveDefault(const Typeface* src);
 
     // The following three functions create new Typeface from an existing Typeface with a different
diff --git a/libs/hwui/jni/ColorFilter.cpp b/libs/hwui/jni/ColorFilter.cpp
index 20301d2..1c6d886 100644
--- a/libs/hwui/jni/ColorFilter.cpp
+++ b/libs/hwui/jni/ColorFilter.cpp
@@ -163,6 +163,20 @@
             filter->updateChild(env, name.c_str(), child);
         }
     }
+
+    static void RuntimeColorFilter_updateInputColorFilter(JNIEnv* env, jobject,
+                                                          jlong colorFilterPtr, jstring childName,
+                                                          jlong childFilterPtr) {
+        auto* filter = reinterpret_cast<RuntimeColorFilter*>(colorFilterPtr);
+        ScopedUtfChars name(env, childName);
+        auto* child = reinterpret_cast<ColorFilter*>(childFilterPtr);
+        if (filter && child) {
+            auto childInput = child->getInstance();
+            if (childInput) {
+                filter->updateChild(env, name.c_str(), childInput.release());
+            }
+        }
+    }
 };
 
 static const JNINativeMethod colorfilter_methods[] = {
@@ -193,7 +207,9 @@
         {"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V",
          (void*)ColorFilterGlue::RuntimeColorFilter_updateUniformsInts},
         {"nativeUpdateChild", "(JLjava/lang/String;J)V",
-         (void*)ColorFilterGlue::RuntimeColorFilter_updateChild}};
+         (void*)ColorFilterGlue::RuntimeColorFilter_updateChild},
+        {"nativeUpdateInputColorFilter", "(JLjava/lang/String;J)V",
+         (void*)ColorFilterGlue::RuntimeColorFilter_updateInputColorFilter}};
 
 int register_android_graphics_ColorFilter(JNIEnv* env) {
     android::RegisterMethodsOrDie(env, "android/graphics/ColorFilter", colorfilter_methods,
diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp
index a7d855d..8d3a5eb 100644
--- a/libs/hwui/jni/Paint.cpp
+++ b/libs/hwui/jni/Paint.cpp
@@ -619,7 +619,16 @@
         // restore the original settings.
         font->setSkewX(saveSkewX);
         font->setEmbolden(savefakeBold);
-        if (paint->getFamilyVariant() == minikin::FamilyVariant::ELEGANT) {
+
+        // Don't use hard coded vertical metrics if target SDK is 35 or later.
+#ifdef __ANDROID__
+        uint32_t isTargetSdk35OrLater = android_get_application_target_sdk_version() >= 35;
+#else
+        uint32_t isTargetSdk35OrLater = true;
+#endif  // __ANDROID
+        bool useHardCodedMetrics = !isTargetSdk35OrLater &&
+                                   (paint->getFamilyVariant() == minikin::FamilyVariant::ELEGANT);
+        if (useHardCodedMetrics) {
             SkScalar size = font->getSize();
             metrics->fTop = -size * kElegantTop / 2048;
             metrics->fBottom = -size * kElegantBottom / 2048;
diff --git a/libs/hwui/jni/RuntimeXfermode.cpp b/libs/hwui/jni/RuntimeXfermode.cpp
index c1c8964..17bee8f 100644
--- a/libs/hwui/jni/RuntimeXfermode.cpp
+++ b/libs/hwui/jni/RuntimeXfermode.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "ColorFilter.h"
 #include "GraphicsJNI.h"
 #include "RuntimeEffectUtils.h"
 #include "SkBlender.h"
@@ -93,6 +94,19 @@
     }
 }
 
+static void RuntimeXfermode_updateColorFilter(JNIEnv* env, jobject, jlong builderPtr,
+                                              jstring childName, jlong colorFilterPtr) {
+    auto* builder = reinterpret_cast<SkRuntimeEffectBuilder*>(builderPtr);
+    ScopedUtfChars name(env, childName);
+    auto* child = reinterpret_cast<ColorFilter*>(colorFilterPtr);
+    if (child) {
+        auto childInput = child->getInstance();
+        if (childInput) {
+            UpdateChild(env, builder, name.c_str(), childInput.release());
+        }
+    }
+}
+
 static const JNINativeMethod gRuntimeXfermodeMethods[] = {
         {"nativeGetFinalizer", "()J", (void*)RuntimeXfermode_getNativeFinalizer},
         {"nativeCreateBlenderBuilder", "(Ljava/lang/String;)J",
@@ -107,6 +121,8 @@
         {"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V",
          (void*)RuntimeXfermode_updateIntUniforms},
         {"nativeUpdateChild", "(JLjava/lang/String;J)V", (void*)RuntimeXfermode_updateChild},
+        {"nativeUpdateColorFilter", "(JLjava/lang/String;J)V",
+         (void*)RuntimeXfermode_updateColorFilter},
 };
 
 int register_android_graphics_RuntimeXfermode(JNIEnv* env) {
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index 018c2b13..eadb9de 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -1,5 +1,6 @@
 #include <vector>
 
+#include "ColorFilter.h"
 #include "Gainmap.h"
 #include "GraphicsJNI.h"
 #include "RuntimeEffectUtils.h"
@@ -331,6 +332,15 @@
     builder->child(name.c_str()) = sk_ref_sp(shader);
 }
 
+static void RuntimeShader_updateColorFilter(JNIEnv* env, jobject, jlong shaderBuilder,
+                                            jstring jUniformName, jlong colorFilterHandle) {
+    SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
+    ScopedUtfChars name(env, jUniformName);
+    auto* childEffect = reinterpret_cast<ColorFilter*>(colorFilterHandle);
+
+    UpdateChild(env, builder, name.c_str(), childEffect->getInstance().release());
+}
+
 static void RuntimeShader_updateChild(JNIEnv* env, jobject, jlong shaderBuilder,
                                       jstring jUniformName, jlong childHandle) {
     SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
@@ -380,6 +390,8 @@
         {"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V",
          (void*)RuntimeShader_updateIntUniforms},
         {"nativeUpdateShader", "(JLjava/lang/String;J)V", (void*)RuntimeShader_updateShader},
+        {"nativeUpdateColorFilter", "(JLjava/lang/String;J)V",
+         (void*)RuntimeShader_updateColorFilter},
         {"nativeUpdateChild", "(JLjava/lang/String;J)V", (void*)RuntimeShader_updateChild},
 };
 
diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp
index d9dc8eb..a0291a9 100644
--- a/libs/hwui/jni/android_graphics_RenderNode.cpp
+++ b/libs/hwui/jni/android_graphics_RenderNode.cpp
@@ -594,14 +594,12 @@
             Matrix4 transform;
             SkIRect clipBounds;
             uirenderer::Rect initialClipBounds;
-            const auto clipFlags = props.getClippingFlags();
             if (enableClip) {
-                if (clipFlags) {
-                    props.getClippingRectForFlags(clipFlags, &initialClipBounds);
-                } else {
-                    // Works for RenderNode::damageSelf()
-                    initialClipBounds.set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
-                }
+                // SurfaceView never draws beyond its bounds regardless of if it can or not,
+                // so if clip-to-bounds is disabled just use the bounds as the starting point
+                // regardless
+                const auto clipFlags = props.getClippingFlags();
+                props.getClippingRectForFlags(clipFlags | CLIP_TO_BOUNDS, &initialClipBounds);
                 clipBounds =
                         info.damageAccumulator
                                 ->computeClipAndTransform(initialClipBounds.toSkRect(), &transform)
diff --git a/libs/hwui/jni/text/TextShaper.cpp b/libs/hwui/jni/text/TextShaper.cpp
index 5f69346..c735989 100644
--- a/libs/hwui/jni/text/TextShaper.cpp
+++ b/libs/hwui/jni/text/TextShaper.cpp
@@ -68,7 +68,7 @@
 static jlong shapeTextRun(const uint16_t* text, int textSize, int start, int count,
     int contextStart, int contextCount, minikin::Bidi bidiFlags,
     const Paint& paint, const Typeface* typeface) {
-
+    const Typeface* resolvedFace = Typeface::resolveDefault(typeface);
     minikin::MinikinPaint minikinPaint = MinikinUtils::prepareMinikinPaint(&paint, typeface);
 
     minikin::Layout layout = MinikinUtils::doLayout(&paint, bidiFlags, typeface,
@@ -103,8 +103,16 @@
                 fontId = it->second;  // We've seen it.
             } else {
                 fontId = fonts.size();  // This is new to us. Create new one.
-                std::shared_ptr<minikin::Font> font = std::make_shared<minikin::Font>(
-                        fakedFont.font, fakedFont.fakery.variationSettings());
+                std::shared_ptr<minikin::Font> font;
+                if (resolvedFace->fIsVariationInstance) {
+                    // The optimization for target SDK 35 or before because the variation instance
+                    // is already created and no runtime variation resolution happens on such
+                    // environment.
+                    font = fakedFont.font;
+                } else {
+                    font = std::make_shared<minikin::Font>(fakedFont.font,
+                                                           fakedFont.fakery.variationSettings());
+                }
                 fonts.push_back(reinterpret_cast<jlong>(new FontWrapper(std::move(font))));
                 fakedToFontIds.insert(std::make_pair(fakedFont, fontId));
             }
diff --git a/libs/input/SpriteIcon.cpp b/libs/input/SpriteIcon.cpp
index 59e36e4..2f8d473 100644
--- a/libs/input/SpriteIcon.cpp
+++ b/libs/input/SpriteIcon.cpp
@@ -25,6 +25,8 @@
 namespace android {
 
 bool SpriteIcon::draw(sp<Surface> surface) const {
+    LOG_ALWAYS_FATAL_IF(!isValid(), "Cannot draw SpriteIcon: not valid");
+
     ANativeWindow_Buffer outBuffer;
     status_t status = surface->lock(&outBuffer, NULL);
     if (status) {
diff --git a/location/java/android/location/altitude/AltitudeConverter.java b/location/java/android/location/altitude/AltitudeConverter.java
index b9fe804..3a4e70d 100644
--- a/location/java/android/location/altitude/AltitudeConverter.java
+++ b/location/java/android/location/altitude/AltitudeConverter.java
@@ -26,8 +26,8 @@
 import android.location.flags.Flags;
 
 import com.android.internal.location.altitude.GeoidMap;
-import com.android.internal.location.altitude.S2CellIdUtils;
 import com.android.internal.location.altitude.nano.MapParamsProto;
+import com.android.internal.location.geometry.S2CellIdUtils;
 import com.android.internal.util.Preconditions;
 
 import java.io.IOException;
diff --git a/location/java/com/android/internal/location/altitude/GeoidMap.java b/location/java/com/android/internal/location/altitude/GeoidMap.java
index df9ca97..d77fb9e 100644
--- a/location/java/com/android/internal/location/altitude/GeoidMap.java
+++ b/location/java/com/android/internal/location/altitude/GeoidMap.java
@@ -26,6 +26,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.location.altitude.nano.MapParamsProto;
 import com.android.internal.location.altitude.nano.S2TileProto;
+import com.android.internal.location.geometry.S2CellIdUtils;
 import com.android.internal.util.Preconditions;
 
 import java.io.IOException;
diff --git a/location/java/com/android/internal/location/altitude/S2CellIdUtils.java b/location/java/com/android/internal/location/geometry/S2CellIdUtils.java
similarity index 80%
rename from location/java/com/android/internal/location/altitude/S2CellIdUtils.java
rename to location/java/com/android/internal/location/geometry/S2CellIdUtils.java
index 08bcda4..fbdaf49 100644
--- a/location/java/com/android/internal/location/altitude/S2CellIdUtils.java
+++ b/location/java/com/android/internal/location/geometry/S2CellIdUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.location.altitude;
+package com.android.internal.location.geometry;
 
 import android.annotation.NonNull;
 
@@ -48,12 +48,22 @@
     private static final double UV_LIMIT = calculateUvLimit();
     private static final UvTransform[] UV_TRANSFORMS = createUvTransforms();
     private static final XyzTransform[] XYZ_TRANSFORMS = createXyzTransforms();
+    private static final long MAX_SI_TI = 1L << (MAX_LEVEL + 1);
 
     // Used to encode (i, j, o) coordinates into primitive longs.
     private static final int I_SHIFT = 33;
     private static final int J_SHIFT = 2;
     private static final long J_MASK = (1L << 31) - 1;
 
+    // Used to insert latitude and longitude values into arrays.
+    public static final int LAT_LNG_MIN_LENGTH = 2;
+    public static final int LAT_INDEX = 0;
+    public static final int LNG_INDEX = 1;
+
+    // Used to encode (si, ti) coordinates into primitive longs.
+    private static final int SI_SHIFT = 32;
+    private static final long TI_MASK = (1L << 32) - 1;
+
     static {
         initLookupCells();
     }
@@ -63,6 +73,130 @@
     }
 
     /**
+     * Inserts into {@code latLngDegrees} the centroid latitude and longitude, in that order and
+     * both measured in degrees, for the specified S2 cell ID. This array must be non-null and of
+     * minimum length two. A reference to this array is returned.
+     *
+     * <p>Behavior is undefined for invalid S2 cell IDs.
+     */
+    public static double[] toLatLngDegrees(long s2CellId, double[] latLngDegrees) {
+        // Used latLngDegrees as scratchpad for toLatLngRadians(long, double[]).
+        final double[] latLngRadians = latLngDegrees;
+        toLatLngRadians(s2CellId, latLngRadians);
+        latLngDegrees[LAT_INDEX] = Math.toDegrees(latLngRadians[LAT_INDEX]);
+        latLngDegrees[LNG_INDEX] = Math.toDegrees(latLngRadians[LNG_INDEX]);
+        return latLngDegrees;
+    }
+
+
+    /**
+     * Inserts into {@code latLngRadians} the centroid latitude and longitude, in that order and
+     * both measured in radians, for the specified S2 cell ID. This array must be non-null and of
+     * minimum length two. A reference to this array is returned.
+     *
+     * <p>Behavior is undefined for invalid S2 cell IDs.
+     */
+    public static double[] toLatLngRadians(long s2CellId, double[] latLngRadians) {
+        checkNotNull(latLngRadians);
+        checkLengthGreaterThanOrEqualTo(LAT_LNG_MIN_LENGTH, latLngRadians.length);
+
+        final long siTi = toSiTi(s2CellId);
+        final double u = siTiToU(siTi);
+        final double v = siTiToV(siTi);
+
+        final int face = getFace(s2CellId);
+        final XyzTransform xyzTransform = faceToXyzTransform(face);
+        final double x = xyzTransform.uvToX(u, v);
+        final double y = xyzTransform.uvToY(u, v);
+        final double z = xyzTransform.uvToZ(u, v);
+
+        latLngRadians[LAT_INDEX] = xyzToLatRadians(x, y, z);
+        latLngRadians[LNG_INDEX] = xyzToLngRadians(x, y);
+        return latLngRadians;
+    }
+
+    private static long toSiTi(long s2CellId) {
+        final long ijo = toIjo(s2CellId);
+        final int i = ijoToI(ijo);
+        final int j = ijoToJ(ijo);
+        int delta = isLeaf(s2CellId) ? 1 : (((i ^ (((int) s2CellId) >>> 2)) & 1) != 0) ? 2 : 0;
+        return (((long) (2 * i + delta)) << SI_SHIFT) | ((2 * j + delta) & TI_MASK);
+    }
+
+    private static int siTiToSi(long siTi) {
+        return (int) (siTi >> SI_SHIFT);
+    }
+
+    private static int siTiToTi(long siTi) {
+        return (int) siTi;
+    }
+
+    private static double siTiToU(long siTi) {
+        final int si = siTiToSi(siTi);
+        return siToU(si);
+    }
+
+    private static double siTiToV(long siTi) {
+        final int ti = siTiToTi(siTi);
+        return tiToV(ti);
+    }
+
+    private static double siToU(long si) {
+        final double s = (1.0 / MAX_SI_TI) * si;
+        if (s >= 0.5) {
+            return (1 / 3.) * (4 * s * s - 1);
+        }
+        return (1 / 3.) * (1 - 4 * (1 - s) * (1 - s));
+    }
+
+    private static double tiToV(long ti) {
+        // Same calculation as siToU.
+        return siToU(ti);
+    }
+
+    private static XyzTransform faceToXyzTransform(int face) {
+        // We map illegal face indices to the largest face index to preserve legacy behavior, i.e.,
+        // we do not want to throw an index out of bounds exception. Note that getFace(s2CellId) is
+        // guaranteed to return a non-negative face index even for invalid S2 cells, so it is
+        // sufficient to just map all face indices greater than the largest face index to the
+        // largest face index.
+        return XYZ_TRANSFORMS[Math.min(NUM_FACES - 1, face)];
+    }
+
+    private static double xyzToLngRadians(double x, double y) {
+        return Math.atan2(y, x);
+    }
+
+    private static double xyzToLatRadians(double x, double y, double z) {
+        return Math.atan2(z, Math.sqrt(x * x + y * y));
+    }
+
+    private static void checkNotNull(Object object) {
+        if (object == null) {
+            throw new NullPointerException("Given array cannot be null.");
+        }
+    }
+
+    private static void checkLengthGreaterThanOrEqualTo(int minLength, int actualLength) {
+        if (actualLength < minLength) {
+            throw new IllegalArgumentException(
+                "Given array of length " + actualLength + " needs to be of minimum length "
+                + minLength);
+        }
+    }
+
+    /**
+     * Returns true if the provided S2 cell contains the provided latitude/longitude, both measured
+     * in degrees.
+     */
+    public static boolean containsLatLngDegrees(long s2CellId, double latDegrees,
+            double lngDegrees) {
+        int level = getLevel(s2CellId);
+        long leafCellId = fromLatLngDegrees(latDegrees, lngDegrees);
+        return (getParent(leafCellId, level) == s2CellId);
+    }
+
+    /**
      * Returns the leaf S2 cell ID for the specified latitude and longitude, both measured in
      * degrees.
      */
@@ -176,7 +310,7 @@
      * Returns the level of the specified S2 cell. The returned level is in [0, 30] for valid
      * S2 cell IDs. Behavior is undefined for invalid S2 cell IDs.
      */
-    static int getLevel(long s2CellId) {
+    public static int getLevel(long s2CellId) {
         if (isLeaf(s2CellId)) {
             return MAX_LEVEL;
         }
@@ -197,12 +331,12 @@
      * Returns the ID of the first S2 cell in a traversal of the children S2 cells at the specified
      * level, in Hilbert curve order.
      */
-    static long getTraversalStart(long s2CellId, int level) {
+    public static long getTraversalStart(long s2CellId, int level) {
         return s2CellId - getLowestOnBit(s2CellId) + getLowestOnBitForLevel(level);
     }
 
     /** Returns the ID of the next S2 cell at the same level along the Hilbert curve. */
-    static long getTraversalNext(long s2CellId) {
+    public static long getTraversalNext(long s2CellId) {
         return s2CellId + (getLowestOnBit(s2CellId) << 1);
     }
 
@@ -211,7 +345,7 @@
      * lower levels (i.e., larger cells) are encoded into fewer characters.
      */
     @NonNull
-    static String getToken(long s2CellId) {
+    public static String getToken(long s2CellId) {
         if (s2CellId == 0) {
             return "X";
         }
diff --git a/media/java/android/media/AudioPlaybackConfiguration.java b/media/java/android/media/AudioPlaybackConfiguration.java
index c085b89..dba9cc9 100644
--- a/media/java/android/media/AudioPlaybackConfiguration.java
+++ b/media/java/android/media/AudioPlaybackConfiguration.java
@@ -283,8 +283,19 @@
      * Flag used when playback is muted by AppOpsManager#OP_PLAY_AUDIO.
      */
     @SystemApi
+    @FlaggedApi(FLAG_MUTED_BY_PORT_VOLUME_API)
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
-    public static final int MUTED_BY_APP_OPS = (1 << 3);
+    public static final int MUTED_BY_OP_PLAY_AUDIO = (1 << 3);
+    /**
+     * @hide
+     * Flag used when playback is muted by AppOpsManager#OP_PLAY_AUDIO.
+     * @deprecated see {@link MUTED_BY_OP_PLAY_AUDIO}
+     */
+    @SystemApi
+    @Deprecated
+    @FlaggedApi(FLAG_MUTED_BY_PORT_VOLUME_API)
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static final int MUTED_BY_APP_OPS = MUTED_BY_OP_PLAY_AUDIO;
     /**
      * @hide
      * Flag used when muted by client volume.
@@ -311,12 +322,21 @@
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public static final int MUTED_BY_PORT_VOLUME = (1 << 6);
 
+    /**
+     * @hide
+     * Flag used when playback is muted by AppOpsManager#OP_CONTROL_AUDIO.
+     */
+    @SystemApi
+    @FlaggedApi(FLAG_MUTED_BY_PORT_VOLUME_API)
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static final int MUTED_BY_OP_CONTROL_AUDIO = (1 << 7);
+
     /** @hide */
     @IntDef(
             flag = true,
             value = {MUTED_BY_MASTER, MUTED_BY_STREAM_VOLUME, MUTED_BY_STREAM_MUTED,
-                    MUTED_BY_APP_OPS, MUTED_BY_CLIENT_VOLUME, MUTED_BY_VOLUME_SHAPER,
-                    MUTED_BY_PORT_VOLUME})
+                    MUTED_BY_OP_PLAY_AUDIO, MUTED_BY_CLIENT_VOLUME, MUTED_BY_VOLUME_SHAPER,
+                    MUTED_BY_PORT_VOLUME, MUTED_BY_OP_CONTROL_AUDIO})
     @Retention(RetentionPolicy.SOURCE)
     public @interface PlayerMuteEvent {
     }
@@ -761,7 +781,7 @@
     private boolean isMuteAffectingActiveState() {
         return (mMutedState & MUTED_BY_CLIENT_VOLUME) != 0
                 || (mMutedState & MUTED_BY_VOLUME_SHAPER) != 0
-                || (mMutedState & MUTED_BY_APP_OPS) != 0;
+                || (mMutedState & MUTED_BY_OP_PLAY_AUDIO) != 0;
     }
 
     /**
@@ -902,8 +922,8 @@
                 if ((mMutedState & MUTED_BY_STREAM_MUTED) != 0) {
                     apcToString.append("streamMute ");
                 }
-                if ((mMutedState & MUTED_BY_APP_OPS) != 0) {
-                    apcToString.append("appOps ");
+                if ((mMutedState & MUTED_BY_OP_PLAY_AUDIO) != 0) {
+                    apcToString.append("opPlayAudio ");
                 }
                 if ((mMutedState & MUTED_BY_CLIENT_VOLUME) != 0) {
                     apcToString.append("clientVolume ");
@@ -914,6 +934,9 @@
                 if ((mMutedState & MUTED_BY_PORT_VOLUME) != 0) {
                     apcToString.append("portVolume ");
                 }
+                if ((mMutedState & MUTED_BY_OP_CONTROL_AUDIO) != 0) {
+                    apcToString.append("opControlAudio ");
+                }
             }
             apcToString.append(" ").append(mFormatInfo);
         }
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 08b0dd3..54a87ad 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -640,6 +640,9 @@
 
     boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af);
 
+    /* Returns a List<Integer> */
+    List getSpatializedChannelMasks();
+
     void registerSpatializerCallback(in ISpatializerCallback cb);
 
     void unregisterSpatializerCallback(in ISpatializerCallback cb);
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 782db35..302969f 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -16,14 +16,15 @@
 
 package android.media;
 
-import static android.media.Utils.intersectSortedDistinctRanges;
-import static android.media.Utils.sortDistinctRanges;
+import static android.media.audio.Flags.FLAG_IAMF_DEFINITIONS_API;
 import static android.media.codec.Flags.FLAG_DYNAMIC_COLOR_ASPECTS;
 import static android.media.codec.Flags.FLAG_HLG_EDITING;
 import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
 import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE;
 import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
 import static android.media.codec.Flags.FLAG_APV_SUPPORT;
+import static android.media.Utils.intersectSortedDistinctRanges;
+import static android.media.Utils.sortDistinctRanges;
 import static android.media.MediaCodec.GetFlag;
 
 import android.annotation.FlaggedApi;
@@ -4758,6 +4759,139 @@
         @FlaggedApi(FLAG_APV_SUPPORT)
         public static final int APVLevel71Band3 = 0x200008;
 
+        // IAMF profiles are defined as the combination of the (listed from LSB to MSB):
+        //  - audio codec (2 bytes)
+        //  - profile (1 byte, offset 16)
+        //  - specification version (1 byte, offset 24)
+        private static final int IAMF_CODEC_OPUS = 0x1;
+        private static final int IAMF_CODEC_AAC  = 0x1 << 1;
+        private static final int IAMF_CODEC_FLAC = 0x1 << 2;
+        private static final int IAMF_CODEC_PCM  = 0x1 << 3;
+        private static final int IAMF_PROFILE_SIMPLE        = 0x1 << 16;
+        private static final int IAMF_PROFILE_BASE          = 0x1 << 17;
+        private static final int IAMF_PROFILE_BASE_ENHANCED = 0x1 << 18;
+        private static final int IAMF_v1 = 0x1 << 24;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-simple">simple profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in OPUS.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileSimpleOpus =
+                IAMF_v1 + IAMF_PROFILE_SIMPLE + IAMF_CODEC_OPUS;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-simple">simple profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in AAC.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileSimpleAac =
+                IAMF_v1 + IAMF_PROFILE_SIMPLE + IAMF_CODEC_AAC;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-simple">simple profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in FLAC.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileSimpleFlac =
+                IAMF_v1 + IAMF_PROFILE_SIMPLE + IAMF_CODEC_FLAC;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-simple">simple profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in PCM.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileSimplePcm =
+                IAMF_v1 + IAMF_PROFILE_SIMPLE + IAMF_CODEC_PCM;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-base">base profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in OPUS.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileBaseOpus =
+                IAMF_v1 + IAMF_PROFILE_BASE + IAMF_CODEC_OPUS;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-base">base profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in AAC.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileBaseAac =
+                IAMF_v1 + IAMF_PROFILE_BASE + IAMF_CODEC_AAC;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-base">base profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in FLAC.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileBaseFlac =
+                IAMF_v1 + IAMF_PROFILE_BASE + IAMF_CODEC_FLAC;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-base">base profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in PCM.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileBasePcm =
+                IAMF_v1 + IAMF_PROFILE_BASE + IAMF_CODEC_PCM;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-base-enhanced">base-enhanced profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in OPUS.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileBaseEnhancedOpus =
+                IAMF_v1 + IAMF_PROFILE_BASE_ENHANCED + IAMF_CODEC_OPUS;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-base-enhanced">base-enhanced profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in AAC.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileBaseEnhancedAac =
+                IAMF_v1 + IAMF_PROFILE_BASE_ENHANCED + IAMF_CODEC_AAC;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-base-enhanced">base-enhanced profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in FLAC.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileBaseEnhancedFlac =
+                IAMF_v1 + IAMF_PROFILE_BASE_ENHANCED + IAMF_CODEC_FLAC;
+        /**
+         * IAMF profile using the
+         * <a href="https://aomediacodec.github.io/iamf/#profiles-base-enhanced">base-enhanced profile</a>
+         * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+         * in PCM.
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+        public static final int IAMFProfileBaseEnhancedPcm =
+                IAMF_v1 + IAMF_PROFILE_BASE_ENHANCED + IAMF_CODEC_PCM;
+
         /**
          * The profile of the media content. Depending on the type of media this can be
          * one of the profile values defined in this class.
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index bc09aee..5038754 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -16,10 +16,12 @@
 
 package android.media;
 
+import static android.media.audio.Flags.FLAG_IAMF_DEFINITIONS_API;
+import static android.media.codec.Flags.FLAG_APV_SUPPORT;
 import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
 import static android.media.codec.Flags.FLAG_NUM_INPUT_SLOTS;
 import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
-import static android.media.codec.Flags.FLAG_APV_SUPPORT;
+import static android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES;
 
 import static com.android.media.codec.flags.Flags.FLAG_CODEC_IMPORTANCE;
 import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME;
@@ -262,6 +264,11 @@
      * MIME type for the IEC61937 audio stream encapsulation. This type isn't defined by IANA.
      */
     public static final String MIMETYPE_AUDIO_IEC61937 = "audio/x-iec61937";
+    /**
+     * MIME type for IAMF audio stream
+     */
+    @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+    public static final String MIMETYPE_AUDIO_IAMF = "audio/iamf";
 
     /**
      * MIME type for HEIF still image data encoded in HEVC.
@@ -1789,6 +1796,27 @@
     public static final String KEY_NUM_SLOTS = "num-slots";
 
     /**
+     * A key describing the picture profile ID to be applied to {@link MediaCodec}.
+     * <p>
+     * The associated value is a string.
+     * <p>
+     * @see {@link android.media.quality.PictureProfile}
+     * @see {@link android.media.quality.PictureProfile#getProfileId}
+     */
+    @FlaggedApi(FLAG_APPLY_PICTURE_PROFILES)
+    public static final String KEY_PICTURE_PROFILE_ID = "picture-profile-id";
+
+    /**
+     * A key describing the picture profile instance to be applied to {@link MediaCodec}.
+     * <p>
+     * The associated value is an instance of {@link android.media.quality.PictureProfile}.
+     * <p>
+     * @see {@link android.media.quality.PictureProfile}
+     */
+    @FlaggedApi(FLAG_APPLY_PICTURE_PROFILES)
+    public static final String KEY_PICTURE_PROFILE_INSTANCE = "picture-profile-instance";
+
+    /**
      * QpOffsetRect constitutes the metadata required for encoding a region of interest in an
      * image or a video frame. The region of interest is represented by a rectangle. The four
      * integer coordinates of the rectangle are stored in fields left, top, right, bottom.
diff --git a/media/java/android/media/Spatializer.java b/media/java/android/media/Spatializer.java
index 99fcaf2..95c4ad3 100644
--- a/media/java/android/media/Spatializer.java
+++ b/media/java/android/media/Spatializer.java
@@ -16,7 +16,10 @@
 
 package android.media;
 
+import static android.media.audio.Flags.FLAG_SPATIALIZER_CAPABILITIES;
+
 import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -35,6 +38,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
@@ -527,6 +531,28 @@
     }
 
     /**
+     * Returns a list of channel masks that represent the widest channel masks the spatializer
+     * is capable of rendering with individual channel positions.
+     * For instance a spatializer may only support virtual speaker positions for 5.1, it would
+     * therefore return {@link AudioFormat#CHANNEL_OUT_5POINT1}. But it would still return
+     * <code>true</code> when querying {@link #canBeSpatialized(AudioAttributes, AudioFormat)} it
+     * with a channel mask of {@link AudioFormat#CHANNEL_OUT_7POINT1POINT2}: the sound present
+     * in each channel would still be heard, but the sounds from the rear, side and top pairs would
+     * be mixed together, and be spatialized at the same location.
+     * @return a list of channel masks following the <code>CHANNEL_OUT_*</code> output channel
+     *     definitions found in {@link AudioFormat}.
+     */
+    @FlaggedApi(FLAG_SPATIALIZER_CAPABILITIES)
+    public @NonNull List<Integer> getSpatializedChannelMasks() {
+        try {
+            return mAm.getService().getSpatializedChannelMasks();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error querying getSpatializedChannelMasks", e);
+            return Collections.emptyList();
+        }
+    }
+
+    /**
      * Adds a listener to be notified of changes to the enabled state of the
      * {@code Spatializer}.
      * @param executor the {@code Executor} handling the callback
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index d8a8c8b..bbe8e4e 100644
--- a/media/java/android/media/flags/media_better_together.aconfig
+++ b/media/java/android/media/flags/media_better_together.aconfig
@@ -141,6 +141,14 @@
 }
 
 flag {
+    name: "enable_route_visibility_control_api"
+    namespace: "media_better_together"
+    description: "API changes to allow more control over route visibility by route providers"
+    bug: "367799834"
+    is_exported: true
+}
+
+flag {
     name: "enable_screen_off_scanning"
     is_exported: true
     namespace: "media_solutions"
diff --git a/media/java/android/media/flags/projection.aconfig b/media/java/android/media/flags/projection.aconfig
index 1bb9a8e..b4dee0c 100644
--- a/media/java/android/media/flags/projection.aconfig
+++ b/media/java/android/media/flags/projection.aconfig
@@ -4,14 +4,6 @@
 # Project link: https://gantry.corp.google.com/projects/android_platform_window_surfaces/changes
 
 flag {
-    name: "limit_manage_media_projection"
-    namespace: "lse_desktop_experience"
-    description: "Limit signature permission manage_media_projection to the SystemUI role"
-    bug: "323008518"
-    is_fixed_read_only: true
-}
-
-flag {
     name: "media_projection_connected_display"
     namespace: "virtual_devices"
     description: "Enable recording connected display"
diff --git a/media/java/android/media/projection/IMediaProjection.aidl b/media/java/android/media/projection/IMediaProjection.aidl
index 8ee966d..dacd1bd 100644
--- a/media/java/android/media/projection/IMediaProjection.aidl
+++ b/media/java/android/media/projection/IMediaProjection.aidl
@@ -17,13 +17,14 @@
 package android.media.projection;
 
 import android.media.projection.IMediaProjectionCallback;
+import android.media.projection.StopReason;
 import android.os.IBinder;
 import android.app.ActivityOptions.LaunchCookie;
 
 /** {@hide} */
 interface IMediaProjection {
     void start(IMediaProjectionCallback callback);
-    void stop();
+    void stop(StopReason stopReason);
 
     boolean canProjectAudio();
     boolean canProjectVideo();
diff --git a/media/java/android/media/projection/IMediaProjectionManager.aidl b/media/java/android/media/projection/IMediaProjectionManager.aidl
index b104972..1d92eab 100644
--- a/media/java/android/media/projection/IMediaProjectionManager.aidl
+++ b/media/java/android/media/projection/IMediaProjectionManager.aidl
@@ -16,11 +16,13 @@
 
 package android.media.projection;
 
+import android.graphics.Rect;
 import android.media.projection.IMediaProjection;
 import android.media.projection.IMediaProjectionCallback;
 import android.media.projection.IMediaProjectionWatcherCallback;
 import android.media.projection.MediaProjectionInfo;
 import android.media.projection.ReviewGrantedConsentResult;
+import android.media.projection.StopReason;
 import android.os.IBinder;
 import android.view.ContentRecordingSession;
 
@@ -107,12 +109,7 @@
     @EnforcePermission("MANAGE_MEDIA_PROJECTION")
     @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
             + ".permission.MANAGE_MEDIA_PROJECTION)")
-    void stopActiveProjection();
-
-    @EnforcePermission("MANAGE_MEDIA_PROJECTION")
-    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
-            + ".permission.MANAGE_MEDIA_PROJECTION)")
-    void notifyActiveProjectionCapturedContentResized(int width, int height);
+    void stopActiveProjection(in StopReason stopReason);
 
     @EnforcePermission("MANAGE_MEDIA_PROJECTION")
     @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
@@ -227,5 +224,11 @@
     @EnforcePermission("MANAGE_MEDIA_PROJECTION")
     @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
             + ".permission.MANAGE_MEDIA_PROJECTION)")
-    void notifyWindowingModeChanged(int contentToRecord, int targetProcessUid, int windowingMode);
+    oneway void notifyWindowingModeChanged(int contentToRecord, int targetProcessUid, int windowingMode);
+
+    @EnforcePermission("MANAGE_MEDIA_PROJECTION")
+    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+            + ".permission.MANAGE_MEDIA_PROJECTION)")
+    oneway void notifyCaptureBoundsChanged(int contentToRecord, int targetProcessUid,
+            in Rect captureBounds);
 }
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 4114f53..f7f10df 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -317,7 +317,7 @@
     public void stop() {
         try {
             Log.d(TAG, "Content Recording: stopping projection");
-            mImpl.stop();
+            mImpl.stop(StopReason.STOP_HOST_APP);
         } catch (RemoteException e) {
             Log.e(TAG, "Unable to stop projection", e);
         }
diff --git a/media/java/android/media/projection/MediaProjectionManager.java b/media/java/android/media/projection/MediaProjectionManager.java
index dc55e41..9cc2cca 100644
--- a/media/java/android/media/projection/MediaProjectionManager.java
+++ b/media/java/android/media/projection/MediaProjectionManager.java
@@ -297,10 +297,10 @@
      * Stop the current projection if there is one.
      * @hide
      */
-    public void stopActiveProjection() {
+    public void stopActiveProjection(@StopReason int stopReason) {
         try {
             Log.d(TAG, "Content Recording: stopping active projection");
-            mService.stopActiveProjection();
+            mService.stopActiveProjection(stopReason);
         } catch (RemoteException e) {
             Log.e(TAG, "Unable to stop the currently active media projection", e);
         }
diff --git a/media/java/android/media/projection/StopReason.aidl b/media/java/android/media/projection/StopReason.aidl
new file mode 100644
index 0000000..8611def
--- /dev/null
+++ b/media/java/android/media/projection/StopReason.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.projection;
+
+/**
+ * Identifies the reason for a MediaProjection being stopped (for metric logging purposes)
+ * @hide
+ */
+@Backing(type="int")
+enum StopReason {
+    STOP_UNKNOWN = 0,
+    STOP_HOST_APP = 1,
+    STOP_TARGET_REMOVED = 2,
+    STOP_DEVICE_LOCKED = 3,
+    STOP_PRIVACY_CHIP = 4,
+    STOP_QS_TILE = 5,
+    STOP_USER_SWITCH = 6,
+    STOP_FOREGROUND_SERVICE_CHANGE = 7,
+    STOP_NEW_PROJECTION = 8,
+    STOP_NEW_MEDIA_ROUTE = 9,
+    STOP_ERROR = 10,
+}
diff --git a/media/java/android/media/quality/AmbientBacklightEvent.java b/media/java/android/media/quality/AmbientBacklightEvent.java
index 273f21e..b1483c6 100644
--- a/media/java/android/media/quality/AmbientBacklightEvent.java
+++ b/media/java/android/media/quality/AmbientBacklightEvent.java
@@ -30,7 +30,6 @@
 
 /**
  * Ambient backlight event
- * @hide
  */
 @FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
 public final class AmbientBacklightEvent implements Parcelable {
diff --git a/media/java/android/media/quality/AmbientBacklightMetadata.java b/media/java/android/media/quality/AmbientBacklightMetadata.java
index 5cea10d..ad19d04 100644
--- a/media/java/android/media/quality/AmbientBacklightMetadata.java
+++ b/media/java/android/media/quality/AmbientBacklightMetadata.java
@@ -32,7 +32,6 @@
  *
  * <p>A metadata instance is sent from ambient backlight hardware in a {@link AmbientBacklightEvent}
  * with {@link AmbientBacklightEvent#AMBIENT_BACKLIGHT_EVENT_METADATA}.
- * @hide
  */
 @FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
 public final class AmbientBacklightMetadata implements Parcelable {
@@ -78,7 +77,6 @@
 
     /**
      * Gets package name of the metadata.
-     * @hide
      */
     @NonNull
     public String getPackageName() {
@@ -130,11 +128,18 @@
     }
 
     /**
-     * Gets color data of vertical color zones.
-     * @hide
+     * Gets color data of all available color zones.
+     *
+     * <p>The format of the color data can be found at {@link #getColorFormat()}.
+     *
+     * @return an array of color data, in row by row (left-to-right then top-to-bottom) order of the
+     * color zones.
+     *
+     * @see #getHorizontalZonesNumber()
+     * @see #getVerticalZonesNumber()
      */
     @NonNull
-    public int[] getVerticalZonesColors() {
+    public int[] getZonesColors() {
         return mZonesColors;
     }
 
diff --git a/media/java/android/media/quality/AmbientBacklightSettings.java b/media/java/android/media/quality/AmbientBacklightSettings.java
index d904cf7..aa06341 100644
--- a/media/java/android/media/quality/AmbientBacklightSettings.java
+++ b/media/java/android/media/quality/AmbientBacklightSettings.java
@@ -31,7 +31,6 @@
 
 /**
  * Settings to configure ambient backlight hardware.
- * @hide
  */
 @FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
 public final class AmbientBacklightSettings implements Parcelable {
@@ -60,16 +59,6 @@
      */
     public static final int SOURCE_AUDIO_VIDEO = 3;
 
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({COLOR_FORMAT_RGB888})
-    public @interface ColorFormat {}
-
-    /**
-     * The color format is RGB888.
-     * @hide
-     */
-    public static final int COLOR_FORMAT_RGB888 = 1;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -201,7 +190,6 @@
      *
      * <p>Letter-box is a technique to keep the original aspect ratio when displayed on a screen
      * with different aspect ratio. Black bars are added to the top and bottom.
-     * @hide
      */
     public boolean isLetterboxOmitted() {
         return mIsLetterboxOmitted;
@@ -210,9 +198,8 @@
     /**
      * Gets the detection threshold of the ambient light.
      *
-     * <p>If the color of a color zone is changed by the difference is smaller than the threshold,
+     * <p>If the color of a color zone is changed but the difference is smaller than the threshold,
      * the change is ignored.
-     * @hide
      */
     public int getThreshold() {
         return mThreshold;
diff --git a/media/java/android/media/quality/IMediaQualityManager.aidl b/media/java/android/media/quality/IMediaQualityManager.aidl
index 1c85c7b..b7e75b7 100644
--- a/media/java/android/media/quality/IMediaQualityManager.aidl
+++ b/media/java/android/media/quality/IMediaQualityManager.aidl
@@ -67,4 +67,5 @@
 
     void setAmbientBacklightSettings(in AmbientBacklightSettings settings);
     void setAmbientBacklightEnabled(in boolean enabled);
+    boolean isAmbientBacklightEnabled();
 }
diff --git a/media/java/android/media/quality/MediaQualityContract.java b/media/java/android/media/quality/MediaQualityContract.java
index 5fec86a..3fac74b 100644
--- a/media/java/android/media/quality/MediaQualityContract.java
+++ b/media/java/android/media/quality/MediaQualityContract.java
@@ -79,12 +79,34 @@
     }
 
     /**
-     * @hide
+     * Parameters for sound quality.
      */
-    public static final class SoundQuality implements BaseParameters {
+    public static final class SoundQuality {
+        /**
+         * The audio volume balance.
+         *
+         * <p>Type: INTEGER
+         */
         public static final String PARAMETER_BALANCE = "balance";
+
+        /**
+         * The bass.
+         *
+         * <p>Bass setting adjust the low sound frequencies.
+         * <p>Type: INTEGER
+         */
         public static final String PARAMETER_BASS = "bass";
+
+        /**
+         * The treble.
+         *
+         * <p>Treble setting adjust the high sound frequencies.
+         * <p>Type: INTEGER
+         */
         public static final String PARAMETER_TREBLE = "treble";
+
+        private SoundQuality() {
+        }
     }
 
     private MediaQualityContract() {
diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java
index 43e884a..5005597 100644
--- a/media/java/android/media/quality/MediaQualityManager.java
+++ b/media/java/android/media/quality/MediaQualityManager.java
@@ -323,7 +323,6 @@
 
     /**
      * Registers a {@link SoundProfileCallback}.
-     * @hide
      */
     public void registerSoundProfileCallback(
             @NonNull @CallbackExecutor Executor executor,
@@ -337,7 +336,6 @@
 
     /**
      * Unregisters the existing {@link SoundProfileCallback}.
-     * @hide
      */
     public void unregisterSoundProfileCallback(@NonNull final SoundProfileCallback callback) {
         Preconditions.checkNotNull(callback);
@@ -359,7 +357,6 @@
      *
      * @return the corresponding sound profile if available; {@code null} if the name doesn't
      *         exist.
-     * @hide
      */
     @Nullable
     public SoundProfile getSoundProfile(
@@ -373,9 +370,11 @@
 
 
     /**
-     * @SystemApi gets profiles that available to the given package
+     * Gets profiles that available to the given package.
+     *
      * @hide
      */
+    @SystemApi
     @NonNull
     @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
     public List<SoundProfile> getSoundProfilesByPackage(@NonNull String packageName) {
@@ -387,8 +386,7 @@
     }
 
     /**
-     * Gets profiles that available to the caller package
-     * @hide
+     * Gets profiles that available to the caller package.
      */
     @NonNull
     public List<SoundProfile> getAvailableSoundProfiles() {
@@ -400,11 +398,13 @@
     }
 
     /**
-     * @SystemApi Gets all package names whose sound profiles are available.
+     * Gets all package names whose sound profiles are available.
      *
      * @see #getSoundProfilesByPackage(String)
+     *
      * @hide
      */
+    @SystemApi
     @NonNull
     @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
     public List<String> getSoundProfilePackageNames() {
@@ -420,8 +420,7 @@
      * Creates a sound profile and store it in the system.
      *
      * <p>If the profile is created successfully,
-     * {@link SoundProfileCallback#onSoundProfileAdded(long, SoundProfile)} is invoked.
-     * @hide
+     * {@link SoundProfileCallback#onSoundProfileAdded(String, SoundProfile)} is invoked.
      */
     public void createSoundProfile(@NonNull SoundProfile sp) {
         try {
@@ -434,7 +433,6 @@
 
     /**
      * Updates an existing sound profile and store it in the system.
-     * @hide
      */
     public void updateSoundProfile(@NonNull String profileId, @NonNull SoundProfile sp) {
         try {
@@ -447,7 +445,6 @@
 
     /**
      * Removes a sound profile from the system.
-     * @hide
      */
     public void removeSoundProfile(@NonNull String profileId) {
         try {
@@ -508,6 +505,7 @@
      * @see #removeSoundProfile(String)
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
     @NonNull
     public List<String> getSoundProfileAllowList() {
@@ -522,6 +520,7 @@
      * Sets the allowlist of packages that can create and removed sound profiles
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
     public void setSoundProfileAllowList(@NonNull List<String> packageNames) {
         try {
@@ -608,6 +607,7 @@
      * @param enabled {@code true} to enable, {@code false} to disable.
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
     public void setAutoSoundQualityEnabled(boolean enabled) {
         try {
@@ -619,7 +619,6 @@
 
     /**
      * Returns {@code true} if auto sound quality is enabled; {@code false} otherwise.
-     * @hide
      */
     public boolean isAutoSoundQualityEnabled() {
         try {
@@ -631,7 +630,6 @@
 
     /**
      * Registers a {@link AmbientBacklightCallback}.
-     * @hide
      */
     public void registerAmbientBacklightCallback(
             @NonNull @CallbackExecutor Executor executor,
@@ -645,7 +643,6 @@
 
     /**
      * Unregisters the existing {@link AmbientBacklightCallback}.
-     * @hide
      */
     public void unregisterAmbientBacklightCallback(
             @NonNull final AmbientBacklightCallback callback) {
@@ -666,7 +663,6 @@
      * Set the ambient backlight settings.
      *
      * @param settings The settings to use for the backlight detector.
-     * @hide
      */
     public void setAmbientBacklightSettings(
             @NonNull AmbientBacklightSettings settings) {
@@ -679,10 +675,20 @@
     }
 
     /**
+     * Returns {@code true} if ambient backlight is enabled; {@code false} otherwise.
+     */
+    public boolean isAmbientBacklightEnabled() {
+        try {
+            return mService.isAmbientBacklightEnabled();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Enables or disables the ambient backlight detection.
      *
      * @param enabled {@code true} to enable, {@code false} to disable.
-     * @hide
      */
     public void setAmbientBacklightEnabled(boolean enabled) {
         try {
@@ -893,7 +899,6 @@
 
     /**
      * Callback used to monitor status of sound profiles.
-     * @hide
      */
     public abstract static class SoundProfileCallback {
         /**
@@ -901,7 +906,6 @@
          *
          * @param profileId the ID of the profile.
          * @param profile the newly added profile.
-         * @hide
          */
         public void onSoundProfileAdded(
                 @NonNull String profileId, @NonNull SoundProfile profile) {
@@ -912,7 +916,6 @@
          *
          * @param profileId the ID of the profile.
          * @param profile the profile with updated info.
-         * @hide
          */
         public void onSoundProfileUpdated(
                 @NonNull String profileId, @NonNull SoundProfile profile) {
@@ -923,7 +926,6 @@
          *
          * @param profileId the ID of the profile.
          * @param profile the removed profile.
-         * @hide
          */
         public void onSoundProfileRemoved(
                 @NonNull String profileId, @NonNull SoundProfile profile) {
@@ -933,7 +935,6 @@
          * This is invoked when an issue has occurred.
          *
          * @param errorCode the error code
-         * @hide
          */
         public void onError(@SoundProfile.ErrorCode int errorCode) {
         }
@@ -945,7 +946,6 @@
          * @param profileId the ID of the profile used by the media content. {@code null} if there
          *                  is no associated profile
          * @param updatedCaps the updated capabilities.
-         * @hide
          */
         public void onParamCapabilitiesChanged(
                 @Nullable String profileId, @NonNull List<ParamCapability> updatedCaps) {
@@ -954,7 +954,6 @@
 
     /**
      * Callback used to monitor status of ambient backlight.
-     * @hide
      */
     public abstract static class AmbientBacklightCallback {
         /**
diff --git a/media/java/android/media/quality/PictureProfileHandle.java b/media/java/android/media/quality/PictureProfileHandle.java
index 2b1cda4..714fd36 100644
--- a/media/java/android/media/quality/PictureProfileHandle.java
+++ b/media/java/android/media/quality/PictureProfileHandle.java
@@ -17,46 +17,58 @@
 package android.media.quality;
 
 import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import androidx.annotation.NonNull;
-
-// TODO(b/337330263): Expose as public API after API review
 /**
-  * A type-safe handle to a picture profile, which represents a collection of parameters used to
-  * configure picture processing hardware to enhance the quality of graphic buffers.
+  * A type-safe handle to a picture profile used to apply picture processing to a SurfaceControl.
+  *
+  * A picture profile represents a collection of parameters used to configure picture processing
+  * to enhance the quality of graphic buffers.
+  *
   * @hide
   */
-@FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+@SystemApi
+@FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
 public final class PictureProfileHandle implements Parcelable {
+    public static final @NonNull PictureProfileHandle NONE = new PictureProfileHandle(0);
+
     private final long mId;
 
-    @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+    /** @hide */
     public PictureProfileHandle(long id) {
         mId = id;
     }
 
-    @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+    /** @hide */
+    @SystemApi
+    @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
     public long getId() {
         return mId;
     }
 
-    @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+    /** @hide */
+    @SystemApi
     @Override
+    @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeLong(mId);
     }
 
-    @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+    /** @hide */
+    @SystemApi
     @Override
+    @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
     public int describeContents() {
         return 0;
     }
 
-    @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
-    @NonNull
-    public static final Creator<PictureProfileHandle> CREATOR =
+    /** @hide */
+    @SystemApi
+    @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
+    public static final @NonNull Creator<PictureProfileHandle> CREATOR =
             new Creator<PictureProfileHandle>() {
                 @Override
                 public PictureProfileHandle createFromParcel(Parcel in) {
diff --git a/media/java/android/media/quality/SoundProfile.java b/media/java/android/media/quality/SoundProfile.java
index de93afe..c7fb4dd 100644
--- a/media/java/android/media/quality/SoundProfile.java
+++ b/media/java/android/media/quality/SoundProfile.java
@@ -18,6 +18,7 @@
 
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
+import android.annotation.SystemApi;
 import android.media.tv.TvInputInfo;
 import android.media.tv.flags.Flags;
 import android.os.Parcel;
@@ -33,10 +34,9 @@
 
 /**
  * Profile for sound quality.
- * @hide
  */
 @FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
-public class SoundProfile implements Parcelable {
+public final class SoundProfile implements Parcelable {
     @Nullable
     private String mId;
     private final int mType;
@@ -113,7 +113,7 @@
      */
     public static final int ERROR_NOT_ALLOWLISTED = 4;
 
-    protected SoundProfile(@NonNull Parcel in) {
+    private SoundProfile(@NonNull Parcel in) {
         mId = in.readString();
         mType = in.readInt();
         mName = in.readString();
@@ -251,9 +251,8 @@
 
     /**
      * A builder for {@link SoundProfile}
-     * @hide
      */
-    public static class Builder {
+    public static final class Builder {
         @Nullable
         private String mId;
         private int mType = TYPE_APPLICATION;
@@ -300,6 +299,7 @@
          *
          * @hide
          */
+        @SystemApi
         @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
         @NonNull
         public Builder setProfileType(@ProfileType int value) {
@@ -314,6 +314,7 @@
          *
          * @hide
          */
+        @SystemApi
         @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
         @NonNull
         public Builder setInputId(@NonNull String value) {
@@ -328,6 +329,7 @@
          *
          * @hide
          */
+        @SystemApi
         @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
         @NonNull
         public Builder setPackageName(@NonNull String value) {
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl
similarity index 73%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl
index 5a04169..550acba 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.analog;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+interface IAnalogAttributeInterface {
+    int getVersion();
+    void setColorSystemCapability(in String[] list);
+    String[] getColorSystemCapability();
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/ICamAppInfoListener.aidl
similarity index 76%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/ICamAppInfoListener.aidl
index 5a04169..73ae209 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/ICamAppInfoListener.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamAppInfoListener {
+    void onCamAppInfoChanged(int slotId, in Bundle appInfo);
 }
diff --git a/media/java/android/media/tv/extension/cam/ICamAppInfoService.aidl b/media/java/android/media/tv/extension/cam/ICamAppInfoService.aidl
new file mode 100644
index 0000000..d3a03bc
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamAppInfoService.aidl
@@ -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 android.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamAppInfoListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamAppInfoService {
+    // Register ICamAppInfoListener to get CICAM Application Information updates.
+    void addCamAppInfoListener(ICamAppInfoListener listener);
+    // Unregister ICamAppInfoListener and stop get Application Information notify.
+    void removeCamAppInfoListener(ICamAppInfoListener listener);
+    // Get the Application Information of the CICAM.
+    int getCamAppInfo(int slotId, out Bundle appInfo);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/ICamDrmInfoListener.aidl
similarity index 76%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/ICamDrmInfoListener.aidl
index 5a04169..c727837 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/ICamDrmInfoListener.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamDrmInfoListener {
+    void onCamDrmInfoChanged(int slotId, in Bundle camDrmInfo);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/ICamHostControlAskReleaseReplyCallback.aidl
similarity index 76%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/ICamHostControlAskReleaseReplyCallback.aidl
index 5a04169..83f2c01 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlAskReleaseReplyCallback.aidl
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+oneway interface ICamHostControlAskReleaseReplyCallback {
+    void onAskReleaseReply(String sessionToken, int replyStatus);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/ICamHostControlInfoListener.aidl
similarity index 76%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/ICamHostControlInfoListener.aidl
index 5a04169..f48ca57 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlInfoListener.aidl
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+oneway interface ICamHostControlInfoListener {
+    void onCamHostControlInfoChanged(String sessionToken, int sessionStatus);
 }
diff --git a/media/java/android/media/tv/extension/cam/ICamHostControlService.aidl b/media/java/android/media/tv/extension/cam/ICamHostControlService.aidl
new file mode 100644
index 0000000..6f6c376
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlService.aidl
@@ -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 android.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamHostControlAskReleaseReplyCallback;
+import android.media.tv.extension.cam.ICamHostControlInfoListener;
+
+/**
+ * @hide
+ */
+interface ICamHostControlService {
+    // Register the listener to monitor host control session updates.
+    void addCamHostcontrolInfoListener(ICamHostControlInfoListener listener);
+    // Unregister ICamHostControlInfoListener and stop monitoring.
+    void removeCamHostcontrolInfoListener(ICamHostControlInfoListener listener);
+    // Request CICAM to release the resource.
+    int sendCamHostControlAskRelease(String sessionToken,
+        ICamHostControlAskReleaseReplyCallback callback);
+    // Enable/disable the host control mode.
+    void setHostControlMode(String sessionToken, boolean enable);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlag.aidl b/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlag.aidl
new file mode 100644
index 0000000..25a78b9
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlag.aidl
@@ -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 android.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamHostControlTuneQuietlyFlagListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamHostControlTuneQuietlyFlag {
+    // Register listener to notify host control tune_quietly_flag.
+    void addHcTuneQuietlyFlagListener(ICamHostControlTuneQuietlyFlagListener listener);
+    // Remove listener and stop monitor host control tune_quietly_flag.
+    void removeHcTuneQuietlyFlagListener(ICamHostControlTuneQuietlyFlagListener listener);
+    // Returns host control tune_quietly_flag value.
+    Bundle getHcTuneQuietlyFlag(String sessionToken);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlagListener.aidl
similarity index 75%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlagListener.aidl
index 5a04169..5967124 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlagListener.aidl
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+oneway interface ICamHostControlTuneQuietlyFlagListener {
+    void onHcTuneQuietlyFlagChanged(String sessionToken, int tuneQuietlyFlag);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/ICamInfoListener.aidl
similarity index 65%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/ICamInfoListener.aidl
index 5a04169..5410bff 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/ICamInfoListener.aidl
@@ -14,8 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamInfoListener {
+    void onCamInfoChanged(int slotId, in Bundle updatedCamInfo);
+    void onSlotInfoChanged(int slotId, in Bundle updatedSlotInfo);
+    void onNewTypeCamInsert(int slotId, in Bundle newCamType);
 }
diff --git a/media/java/android/media/tv/extension/cam/ICamMonitoringService.aidl b/media/java/android/media/tv/extension/cam/ICamMonitoringService.aidl
new file mode 100644
index 0000000..7b8014c
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamMonitoringService.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.extension.cam;
+
+import android.media.tv.extension.cam.ICamInfoListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamMonitoringService {
+    // Register a listener for slot/CAM info updates.
+    void addCamInfoListener(in ICamInfoListener listener);
+    // Unregister a listener for slot/CAM info updates.
+    void removeCamInfoListener(in ICamInfoListener listener);
+    // Get CAM information for the specified slot.
+    Bundle getCamInfo(int slotId);
+    // Get slot information.
+    Bundle getSlotInfo(int slotId);
+    // Returns list of slot Ids.
+    int[] getSlotIds();
+    // Check if the country supports CAM.
+    boolean isCamSupported();
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/ICamPinCapabilityListener.aidl
similarity index 75%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/ICamPinCapabilityListener.aidl
index 5a04169..f92304a 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/ICamPinCapabilityListener.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamPinCapabilityListener {
+    void onCamPinCapabilityChanged(int slotId, in Bundle bundle);
 }
diff --git a/media/java/android/media/tv/extension/cam/ICamPinService.aidl b/media/java/android/media/tv/extension/cam/ICamPinService.aidl
new file mode 100644
index 0000000..3f6cb28
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamPinService.aidl
@@ -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 android.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamPinCapabilityListener;
+import android.media.tv.extension.cam.ICamPinStatusListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamPinService {
+    // Register ICamPinCapabilityListener to get CICAM updates.
+    void addCamPinCapabilityListener(in ICamPinCapabilityListener listener);
+    // Unregister ICamPinCapabilityListener and stop monitor PIN status and PIN capability.
+    void removeCamPinCapabilityListener(in ICamPinCapabilityListener listener);
+    // Send the PinCode that needs to be validated by CICAM.
+    int requestCamPinValidation(int slotId, in int[] pinCode, in ICamPinStatusListener listener);
+    // Get the PIN capabilities of the CICAM.
+    int getCamPinCapability(int slotId, out Bundle camPinCapability);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/ICamPinStatusListener.aidl
similarity index 75%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/ICamPinStatusListener.aidl
index 5a04169..efbc394 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/ICamPinStatusListener.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamPinStatusListener {
+    void onCamPinValidationReply(int slotId, in Bundle bundle);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/ICamProfileInterface.aidl
similarity index 62%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/ICamProfileInterface.aidl
index 5a04169..3f1d40c 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/ICamProfileInterface.aidl
@@ -14,8 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamProfileInterface {
+    // Get CAM service update information for special slot.
+    Bundle getCamServiceUpdateInfo(int slotNumber);
+    // Request CAM TIS resend cam info update broadcast message when APK boot up.
+    void requestResendProfileInfoBroadcastACON();
 }
diff --git a/media/java/android/media/tv/extension/cam/IContentControlService.aidl b/media/java/android/media/tv/extension/cam/IContentControlService.aidl
new file mode 100644
index 0000000..6db79ab
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/IContentControlService.aidl
@@ -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 android.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamDrmInfoListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IContentControlService {
+    // Register the listener to notify the DRM info changed by the CICAM.
+    void addCamDrmInfoListener(in ICamDrmInfoListener listener);
+    // Unregister listener to stop monitor DRM Info.
+    void removeCamDrmInfoListener(in ICamDrmInfoListener listener);
+    // Get the DRM Info of current watching channel.
+    int getCamDrmInfo(int slotId, out Bundle camDrmInfo);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/IEnterMenuErrorCallback.aidl
similarity index 81%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/IEnterMenuErrorCallback.aidl
index 5a04169..ff61ddc 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/IEnterMenuErrorCallback.aidl
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+oneway interface IEnterMenuErrorCallback {
+    void onAppInfoEnterMenuError();
 }
diff --git a/media/java/android/media/tv/extension/cam/IMmiInterface.aidl b/media/java/android/media/tv/extension/cam/IMmiInterface.aidl
new file mode 100644
index 0000000..17a2a9c
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/IMmiInterface.aidl
@@ -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 android.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.IEnterMenuErrorCallback;
+import android.media.tv.extension.cam.IMmiSession;
+import android.media.tv.extension.cam.IMmiStatusCallback;
+
+
+/**
+ * @hide
+ */
+interface IMmiInterface {
+    // Open a session for MMI.
+    IMmiSession openSession(int slotId, IMmiStatusCallback callback);
+    // Request to display CI Module setup screen.
+    void appInfoEnterMenu(int slotId, IEnterMenuErrorCallback callback);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/IMmiSession.aidl
similarity index 60%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/IMmiSession.aidl
index 5a04169..c4f2762 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/IMmiSession.aidl
@@ -14,8 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+interface IMmiSession {
+    // Send user answers to CAM on the MMI Menu screen.
+    void setMenuListAnswer(int response);
+    // Send user answers to CAM on the MMI Enq screen.
+    void setEnquiryAnswer(int answerId, String answer);
+    // Send CloseMmi APDU to Cam.
+    void closeMmi();
+    // Release MMI session.
+    void close();
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/cam/IMmiStatusCallback.aidl
similarity index 72%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/cam/IMmiStatusCallback.aidl
index 5a04169..3e68ced 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/cam/IMmiStatusCallback.aidl
@@ -14,8 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.cam;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IMmiStatusCallback {
+    void onMmiEnq(in Bundle request);
+    void onMmiListMenu(in Bundle request);
+    void onMmiClose();
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/clienttoken/IClientToken.aidl
similarity index 82%
rename from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
rename to media/java/android/media/tv/extension/clienttoken/IClientToken.aidl
index 5a04169..fa701b3 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/clienttoken/IClientToken.aidl
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.clienttoken;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+interface IClientToken {
+    String generateClientToken();
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/event/IEventDownload.aidl
similarity index 61%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/event/IEventDownload.aidl
index 5a04169..29c7553 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/event/IEventDownload.aidl
@@ -14,8 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.event;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.media.tv.extension.event.IEventDownloadListener;
+import android.os.Bundle;
+import android.os.IBinder;
+
+/**
+ * @hide
+ */
+interface IEventDownload {
+    // Create an event download session and return it as a Ibinder for DVB/DTMB
+    IBinder createSession(in Bundle eventDownloadParams, in IEventDownloadListener listener);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/event/IEventDownloadListener.aidl
similarity index 77%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/event/IEventDownloadListener.aidl
index 5a04169..6d7d61f 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/event/IEventDownloadListener.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.event;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IEventDownloadListener {
+    void onCompleted(in Bundle status);
 }
diff --git a/media/java/android/media/tv/extension/event/IEventDownloadSession.aidl b/media/java/android/media/tv/extension/event/IEventDownloadSession.aidl
new file mode 100644
index 0000000..fe7ee37
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventDownloadSession.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.extension.event;
+
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IEventDownloadSession {
+    // Determine to execute barker channel or silent tune flow for related service type
+    int isBarkerOrSequentialDownloadByServiceType(in Bundle eventDownloadParams);
+    // Determine whether to start barker channel or silent tune flow.
+    int isBarkerOrSequentialDownloadByServiceRecord(in Bundle eventDownloadParams);
+    // Start event download.
+    void startTuningMultiplex(in Uri channelUri);
+    // Set active window channels.
+    void setActiveWindowChannelInfo(in Uri[] activeWinChannelInfos);
+    // Cancel barker channel or silent tune flow.
+    void cancel();
+    // Release barker channel or silent tune flow.
+    void release();
+}
diff --git a/media/java/android/media/tv/extension/event/IEventMonitor.aidl b/media/java/android/media/tv/extension/event/IEventMonitor.aidl
new file mode 100644
index 0000000..f6e7bd1
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventMonitor.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.extension.event;
+
+import android.media.tv.extension.event.IEventMonitorListener;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IEventMonitor {
+    // Get present event information.
+    Bundle getPresentEventInfo(long channelDbId);
+    // Add present event information listener.
+    void addPresentEventInfoListener(in IEventMonitorListener listener);
+    // Remove present event information listener.
+    void removePresentEventInfoListener(in IEventMonitorListener listener);
+    // Get following event information.
+    Bundle getFollowingEventInfo(long channelDbId);
+    // Add following event information listener.
+    void addFollowingEventInfoListener(in IEventMonitorListener listener);
+    // Remove following event information listener.
+    void removeFollowingEventInfoListener(in IEventMonitorListener listener);
+    // Get SDT guidance information.
+    Bundle getSdtGuidanceInfo(long channelDbId);
+    // Set Event Background channel list info.
+    void setBgmTuneChannelInfo(in Uri[] tuneChannelInfos);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/event/IEventMonitorListener.aidl
similarity index 75%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/event/IEventMonitorListener.aidl
index 5a04169..a00e542 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/event/IEventMonitorListener.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.event;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IEventMonitorListener {
+    void onInfoChanged(long channelDbId, in Bundle eventinfo);
 }
diff --git a/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl
new file mode 100644
index 0000000..bda60ed
--- /dev/null
+++ b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl
@@ -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 android.media.tv.extension.scanbsu;
+
+import android.media.tv.extension.scanbsu.IScanBackgroundServiceUpdateListener;
+
+/**
+ * @hide
+ */
+interface IScanBackgroundServiceUpdate {
+    // Set the listener for background service update
+    // receives notifications for svl/tsl/nwl update during background service update.
+    void addBackgroundServiceUpdateListener(String clientToken,
+        in IScanBackgroundServiceUpdateListener listener);
+    // Remove the listener for background service update to stop receiving notifications
+    // for svl/tsl/nwl update during background service update.
+    void removeBackgroundServiceUpdateListener(in IScanBackgroundServiceUpdateListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl
new file mode 100644
index 0000000..d9bcbed
--- /dev/null
+++ b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.extension.scanbsu;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IScanBackgroundServiceUpdateListener {
+    // On background service update add/delete/update svl records.
+    void onChannelListUpdate(String sessionToken, out Bundle[] updateInfos);
+    // On background service update add/delete/update nwl records.
+    void onNetworkListUpdate(String sessionToken, out Bundle[] updateInfos);
+    // On background service update add/delete/update tsl records.
+    void onTransportStreamingListUpdate(String sessionToken, out Bundle[] updateInfos);
+}
diff --git a/media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl b/media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl
new file mode 100644
index 0000000..57f3b4a
--- /dev/null
+++ b/media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.extension.screenmode;
+
+/**
+ * @hide
+ */
+interface IScreenModeSettings {
+    // Set screen mode information using a JSON string.
+    void setScreenModeSettings(String sessionToken, String setting);
+    // Get the overscan index which TIS session is applied.
+    int getOverScanIndex(String sessionToken);
+    // Get status that TIS session is support overscan or not.
+    boolean getSupportApplyOverScan(String sessionToken);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl
similarity index 62%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl
index 5a04169..cb6aecc 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl
@@ -14,8 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.servicedb;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IChannelListTransfer {
+    // Parse XML file and import Channels information.
+    void importChannelList(in ParcelFileDescriptor pfd);
+    // Get Channels information for export and create XML file.
+    void exportChannelList(in ParcelFileDescriptor pfd);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/servicedb/IServiceList.aidl
similarity index 60%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/servicedb/IServiceList.aidl
index 5a04169..51daa80 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/servicedb/IServiceList.aidl
@@ -14,8 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.servicedb;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IServiceList {
+    // Get a list of the Service list IDs quivalent to COLUMN_CHANNEL_LIST_ID
+    // in the Channels table of TvProvider.
+    String[] getServiceListIds();
+    // Get the information associated with the Service list.
+    Bundle getServiceListInfo(String serviceListId, in String[] keys);
 }
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl
new file mode 100644
index 0000000..1b1577f
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl
@@ -0,0 +1,81 @@
+/*
+ * 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.extension.servicedb;
+
+import android.media.tv.extension.servicedb.IServiceListEditListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IServiceListEdit {
+    // Open in edit mode. Must call close() after edit is done.
+    int open(IServiceListEditListener listener);
+    // Method to close in edit mode.
+    int close();
+    // Method to commit changes made to service database.
+    int commit();
+    // Method to commit and close the changes.
+    int userEditCommit();
+
+    // Get a service/transportStream/Network/Satellite record information specified by
+    // serviceInfoId and keys from tvdb.
+    Bundle getServiceInfoFromDatabase(String serviceInfoId, in String[] keys);
+    // Get a list of all service records' information specified by serviceListId and keys from tvdb.
+    Bundle getServiceInfoListFromDatabase(String serviceListId, in String[] keys);
+    // Get a list of all service info IDs in the service list of serviceListId from tvdb.
+    String[] getServiceInfoIdsFromDatabase(String inServiceListId);
+    // Update a service information by the contents of serviceInfo;
+    int updateServiceInfoFromDatabase(in Bundle updateServiceInfo);
+    // Update all service information by the contents of serviceInfoList.
+    int updateServiceInfoByListFromDatabase(in Bundle[] updateServiceInfoList);
+    // Remove a service information of the serviceInfoId from the service list.
+    int removeServiceInfoFromDatabase(String serviceInfoId);
+    // Remove all service information of the serviceInfoId from the service list.
+    int removeServiceInfoByListFromDatabase(in String[] serviceInfoIdList);
+    // Get a list of the Service list IDs which is equivalent to COLUMN_CHANNEL_LIST_ID
+    // in Channels table from tv db.
+    String[] getServiceListChannelIds();
+    // Get the information associated with the Service list Channel id.
+    Bundle getServiceListInfoByChannelId(String serviceListChannelId, in String[] keys);
+
+    // Get a list of transportStream records' information specified by serviceListId and keys.
+    Bundle getTransportStreamInfoList(String serviceListId, in String[] keys);
+    // Get a list of transportStream records' information specified by serviceListId and keys
+    // from work db.
+    Bundle getTransportStreamInfoListForce(String serviceListId, in String[] keys);
+
+    // Get a list of network records' information specified by serviceListId and keys.
+    Bundle getNetworkInfoList(String serviceListId, in String[] keys);
+    // Get a list of satellite records' information specified by serviceListId and keys.
+    Bundle getSatelliteInfoList(String serviceListId, in String[] keys);
+
+    // Decompress whole bundle value of single service/transportStream/Network/Satellite record.
+    // RecordInfoBundle:a single record got from database by getServiceInfoFromDatabase()
+    String toRecordInfoByType(in Bundle recordInfoBundle, String recordType);
+    // Set channels(tv.db) modified result to middleware database(SVL/TSL/NWL/SATL).
+    int putRecordIdList(String serviceListId, in Bundle recordIdListBundle, int optType);
+
+    // Add predefined ServiceListInfo of Hotbird 13E in scan two satellite scene EU region
+    // following by commit().
+    String addPredefinedServiceListInfo(int broadcastType, String serviceListType,
+        String serviceListPrefix, String countryCode, int operatorId);
+    // Add predefined channels of Hotbird 13E in scan two satellite scene EU region.
+    int addPredefinedChannelList(String serviceListId, in Bundle[] predefinedListBundle);
+    // Add predefined satellite info of Hotbird 13E in scan two satellite scene EU region.
+    int addPredefinedSatInfo(String serviceListId, in Bundle predefinedSatInfoBundle);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl
similarity index 79%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl
index 5a04169..e227eda 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.servicedb;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+oneway interface IServiceListEditListener {
+    void onCompleted(int requestId, int result);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl
similarity index 80%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl
index 5a04169..c57e8f9 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.servicedb;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+oneway interface IServiceListExportListener {
+    void onExported(int exportResult);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl
similarity index 62%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl
index 5a04169..fcde581 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl
@@ -14,8 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.servicedb;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IServiceListExportSession {
+    // Start export service list with reserved parameters.
+    int exportServiceList(in ParcelFileDescriptor pfd, in Bundle exportParams);
+    // Release export resources.
+    int release();
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl
similarity index 76%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl
index 5a04169..abd8320 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl
@@ -14,8 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.servicedb;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+/**
+ * @hide
+ */
+interface IServiceListImportListener {
+    void onImported(int importResult);
+    void onPreloaded(int preloadResult);
+}
\ No newline at end of file
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl
new file mode 100644
index 0000000..1f1ae01
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl
@@ -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 android.media.tv.extension.servicedb;
+
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IServiceListImportSession {
+    // Start import service list. Should call after preload and before release.
+    int importServiceList(in ParcelFileDescriptor pfd, in Bundle importParams);
+    // Preparing for import.
+    int preload(in ParcelFileDescriptor pfd);
+    // Release import resources.
+    int release();
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl
similarity index 78%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl
index 5a04169..7c9c5c8 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.servicedb;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+oneway interface IServiceListSetChannelListListener {
+    void onCompleted(int setChannelListResult);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl
similarity index 61%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl
index 5a04169..b0527b3 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl
@@ -14,8 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.servicedb;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IServiceListSetChannelListSession {
+    // Set channelList with channelinfo bundles, serviceListInfo, and operation type.
+    int setChannelList(in Bundle[] channelsInfo, in Bundle ServiceListInfoBundle, int optType);
+    // Release set channellist resources.
+    int release();
 }
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl
new file mode 100644
index 0000000..91fb157
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.extension.servicedb;
+
+import android.media.tv.extension.servicedb.IServiceListExportListener;
+import android.media.tv.extension.servicedb.IServiceListImportListener;
+import android.media.tv.extension.servicedb.IServiceListSetChannelListListener;
+import android.os.IBinder;
+
+/**
+ * @hide
+ */
+interface IServiceListTransferInterface {
+    IBinder createExportSession(in IServiceListExportListener listener);
+    IBinder createImportSession(in IServiceListImportListener listener);
+    IBinder createSetChannelListSession(in IServiceListSetChannelListListener listener);
+}
diff --git a/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl
new file mode 100644
index 0000000..a3725e4
--- /dev/null
+++ b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl
@@ -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 android.media.tv.extension.teletext;
+
+import android.media.tv.extension.teletext.IDataServiceSignalInfoListener;
+import android.os.Bundle;
+
+
+/**
+ * @hide
+ */
+interface IDataServiceSignalInfo {
+     // Get Teletext data service signal information.
+     Bundle getDataServiceSignalInfo(String sessionToken);
+     // Add a listener that receives notifications of teletext running information.
+     void addDataServiceSignalInfoListener(String clientToken,
+        IDataServiceSignalInfoListener listener);
+     // Remove a listener that receives notifications of Teletext running information.
+     void removeDataServiceSignalInfoListener(String clientToken,
+        IDataServiceSignalInfoListener listener);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl
similarity index 72%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl
index 5a04169..0e99bf5 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.teletext;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IDataServiceSignalInfoListener {
+    void onDataServiceSignalInfoChanged (String sessionToken, in Bundle changedSignalInfo);
 }
diff --git a/media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl b/media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl
new file mode 100644
index 0000000..c96ffc0
--- /dev/null
+++ b/media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.extension.teletext;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ITeletextPageSubCode {
+    // Get Teletext page number
+    Bundle getTeletextPageNumber(String sessionToken);
+    // Set Teletext page number.
+    void setTeleltextPageNumber(String sessionToken, int pageNumber);
+    // Get Teletext sub page number.
+    Bundle getTeletextPageSubCode(String sessionToken);
+    // Set Teletext sub page number.
+    void setTeletextPageSubCode(String sessionToken, int pageSubCode);
+    // Get Teletext TopInfo.
+    Bundle getTeletextHasTopInfo(String sessionToken);
+    // Get Teletext TopBlockList.
+    Bundle getTeletextTopBlockList(String sessionToken);
+    // Get Teletext TopGroupList.
+    Bundle getTeletextTopGroupList(String sessionToken, int indexGroup);
+    // Get Teletext TopPageList.
+    Bundle getTeletextTopPageList(String sessionToken, int indexPage);
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl
similarity index 67%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl
index 5a04169..88e5084 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl
@@ -14,8 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.tune;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.media.tv.extension.tune.IChannelTunedListener;
+
+/*
+* @hide
+*/
+interface IChannelTunedInterface {
+    void addChannelTunedListener(in IChannelTunedListener listener);
+    void removeChannelTunedListener(in IChannelTunedListener listener);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl
similarity index 75%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl
index 5a04169..4687546 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.tune;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.os.Bundle;
+
+/*
+* @hide
+*/
+oneway interface IChannelTunedListener {
+    void onChannelTuned(String sessionToken, in Bundle channelTunedInfo);
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/media/java/android/media/tv/extension/tune/IMuxTune.aidl
similarity index 74%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to media/java/android/media/tv/extension/tune/IMuxTune.aidl
index 5a04169..4e9dbda 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/media/java/android/media/tv/extension/tune/IMuxTune.aidl
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.media.tv.extension.tune;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import android.media.tv.extension.tune.IMuxTuneSession;
+
+/**
+* @hide
+*/
+interface IMuxTune {
+    IMuxTuneSession createSession(int broadcastType, String clientToken);
 }
diff --git a/media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl b/media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl
new file mode 100644
index 0000000..5ad72b4
--- /dev/null
+++ b/media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl
@@ -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 android.media.tv.extension.tune;
+
+import android.os.Bundle;
+
+/**
+* @hide
+*/
+interface IMuxTuneSession {
+    // Start mux tune with tune params.
+    void start(int broadcastType, int frequency, int brandwith, in Bundle muxTuneParams);
+    // Stop mux tune.
+    void stop();
+    // Release muxtune resources.
+    void release();
+    // Get the session token created by TIS to identify different sessions.
+    String getSessionToken();
+}
diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig
index 4b832ae..572db97 100644
--- a/media/java/android/media/tv/flags/media_tv.aconfig
+++ b/media/java/android/media/tv/flags/media_tv.aconfig
@@ -112,3 +112,11 @@
     description : "Feature flag to enable APIs for applying picture profiles"
     bug: "337330263"
 }
+
+flag {
+    name: "hdmi_control_collect_physical_address"
+    is_exported: true
+    namespace: "media_tv"
+    description: "Collect physical address from HDMI-CEC messages in metrics"
+    bug: "376001043"
+}
diff --git a/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java b/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java
index c9807e6..58aa56b 100644
--- a/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java
+++ b/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java
@@ -46,7 +46,7 @@
     }
 
     @Override
-    public void stop() throws RemoteException {
+    public void stop(@StopReason int stopReason) throws RemoteException {
         // Pass along to the client's callback wrapper.
         mIMediaProjectionCallback.onStop();
     }
diff --git a/native/android/Android.bp b/native/android/Android.bp
index da29c49..cd6de5a 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -55,6 +55,7 @@
         "surface_control_input_receiver.cpp",
         "choreographer.cpp",
         "configuration.cpp",
+        "display_luts.cpp",
         "dynamic_instrumentation_manager.cpp",
         "hardware_buffer_jni.cpp",
         "input.cpp",
diff --git a/native/android/display_luts.cpp b/native/android/display_luts.cpp
new file mode 100644
index 0000000..179a32b
--- /dev/null
+++ b/native/android/display_luts.cpp
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+#define LOG_TAG "DisplayLuts"
+
+#include <android/display_luts.h>
+#include <display_luts_private.h>
+#include <utils/Log.h>
+
+#include <cmath>
+
+#define ADISPLAYLUTS_BUFFER_LENGTH_LIMIT (100000)
+
+#define CHECK_NOT_NULL(name) \
+    LOG_ALWAYS_FATAL_IF(name == nullptr, "nullptr passed as " #name " argument");
+
+ADisplayLutsEntry* ADisplayLutsEntry_createEntry(float* buffer, int32_t length, int32_t dimension,
+                                                 int32_t key) {
+    CHECK_NOT_NULL(buffer);
+    LOG_ALWAYS_FATAL_IF(length >= ADISPLAYLUTS_BUFFER_LENGTH_LIMIT,
+                        "the lut raw buffer length is too big to handle");
+    if (dimension != ADISPLAYLUTS_ONE_DIMENSION && dimension != ADISPLAYLUTS_THREE_DIMENSION) {
+        LOG_ALWAYS_FATAL("the lut dimension is be either 1 or 3");
+    }
+    int32_t size = 0;
+    if (dimension == ADISPLAYLUTS_THREE_DIMENSION) {
+        LOG_ALWAYS_FATAL_IF(length % 3 != 0, "the 3d lut raw buffer is not divisible by 3");
+        int32_t lengthPerChannel = length / 3;
+        float sizeForDim = std::cbrt(static_cast<float>(lengthPerChannel));
+        LOG_ALWAYS_FATAL_IF(sizeForDim != (int)(sizeForDim),
+                            "the 3d lut buffer length is incorrect");
+        size = (int)sizeForDim;
+    } else {
+        size = length;
+    }
+    LOG_ALWAYS_FATAL_IF(size < 2, "the lut size for each dimension is too small");
+
+    ADisplayLutsEntry* entry = new ADisplayLutsEntry();
+    entry->buffer.data.resize(length);
+    std::copy(buffer, buffer + length, entry->buffer.data.begin());
+    entry->properties = {dimension, size, key};
+
+    entry->incStrong((void*)ADisplayLutsEntry_createEntry);
+    return static_cast<ADisplayLutsEntry*>(entry);
+}
+
+void ADisplayLutsEntry_destroy(ADisplayLutsEntry* entry) {
+    if (entry != NULL) {
+        entry->decStrong((void*)ADisplayLutsEntry_createEntry);
+    }
+}
+
+ADisplayLuts_Dimension ADisplayLutsEntry_getDimension(const ADisplayLutsEntry* entry) {
+    CHECK_NOT_NULL(entry);
+    return static_cast<ADisplayLuts_Dimension>(entry->properties.dimension);
+}
+
+int32_t ADisplayLutsEntry_getSize(const ADisplayLutsEntry* entry) {
+    CHECK_NOT_NULL(entry);
+    return entry->properties.size;
+}
+
+ADisplayLuts_SamplingKey ADisplayLutsEntry_getSamplingKey(const ADisplayLutsEntry* entry) {
+    CHECK_NOT_NULL(entry);
+    return static_cast<ADisplayLuts_SamplingKey>(entry->properties.samplingKey);
+}
+
+const float* ADisplayLutsEntry_getBuffer(const ADisplayLutsEntry* _Nonnull entry) {
+    CHECK_NOT_NULL(entry);
+    return entry->buffer.data.data();
+}
+
+ADisplayLuts* ADisplayLuts_create() {
+    ADisplayLuts* luts = new ADisplayLuts();
+    if (luts == NULL) {
+        delete luts;
+        return NULL;
+    }
+    luts->incStrong((void*)ADisplayLuts_create);
+    return static_cast<ADisplayLuts*>(luts);
+}
+
+void ADisplayLuts_clearLuts(ADisplayLuts* luts) {
+    for (auto& entry : luts->entries) {
+        entry->decStrong((void*)ADisplayLuts_setEntries); // Decrement ref count
+    }
+    luts->entries.clear();
+    luts->offsets.clear();
+    luts->totalBufferSize = 0;
+}
+
+void ADisplayLuts_destroy(ADisplayLuts* luts) {
+    if (luts != NULL) {
+        ADisplayLuts_clearLuts(luts);
+        luts->decStrong((void*)ADisplayLuts_create);
+    }
+}
+
+void ADisplayLuts_setEntries(ADisplayLuts* luts, ADisplayLutsEntry** entries, int32_t numEntries) {
+    CHECK_NOT_NULL(luts);
+    // always clear the previously set lut(s)
+    ADisplayLuts_clearLuts(luts);
+
+    // do nothing
+    if (!entries || numEntries == 0) {
+        return;
+    }
+
+    LOG_ALWAYS_FATAL_IF(numEntries > 2, "The number of entries should be not over 2!");
+    if (numEntries == 2 && entries[0]->properties.dimension != ADISPLAYLUTS_ONE_DIMENSION &&
+        entries[1]->properties.dimension != ADISPLAYLUTS_THREE_DIMENSION) {
+        LOG_ALWAYS_FATAL("The entries should be 1D and 3D in order!");
+    }
+
+    luts->offsets.reserve(numEntries);
+    luts->entries.reserve(numEntries);
+    for (int32_t i = 0; i < numEntries; i++) {
+        luts->offsets.emplace_back(luts->totalBufferSize);
+        luts->totalBufferSize += entries[i]->buffer.data.size();
+        luts->entries.emplace_back(entries[i]);
+        luts->entries.back()->incStrong((void*)ADisplayLuts_setEntries);
+    }
+}
\ No newline at end of file
diff --git a/native/android/dynamic_instrumentation_manager.cpp b/native/android/dynamic_instrumentation_manager.cpp
index d9bacb1..5322136 100644
--- a/native/android/dynamic_instrumentation_manager.cpp
+++ b/native/android/dynamic_instrumentation_manager.cpp
@@ -65,7 +65,7 @@
 }
 
 void ADynamicInstrumentationManager_TargetProcess_destroy(
-        ADynamicInstrumentationManager_TargetProcess* instance) {
+        const ADynamicInstrumentationManager_TargetProcess* instance) {
     delete instance;
 }
 
@@ -96,7 +96,7 @@
 }
 
 void ADynamicInstrumentationManager_MethodDescriptor_destroy(
-        ADynamicInstrumentationManager_MethodDescriptor* instance) {
+        const ADynamicInstrumentationManager_MethodDescriptor* instance) {
     delete instance;
 }
 
@@ -112,29 +112,29 @@
 }
 
 const char* ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getContainerPath(
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
     return instance->containerPath.c_str();
 }
 
 uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getContainerOffset(
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
     return instance->containerOffset;
 }
 
 uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getMethodOffset(
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
     return instance->methodOffset;
 }
 
 void ADynamicInstrumentationManager_ExecutableMethodFileOffsets_destroy(
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
     delete instance;
 }
 
 int32_t ADynamicInstrumentationManager_getExecutableMethodFileOffsets(
         const ADynamicInstrumentationManager_TargetProcess* targetProcess,
         const ADynamicInstrumentationManager_MethodDescriptor* methodDescriptor,
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets** out) {
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets** out) {
     android::os::instrumentation::TargetProcess targetProcessParcel;
     targetProcessParcel.uid = targetProcess->uid;
     targetProcessParcel.pid = targetProcess->pid;
diff --git a/native/android/include_platform/android/dynamic_instrumentation_manager.h b/native/android/include_platform/android/dynamic_instrumentation_manager.h
index 6c46288..ab9f370 100644
--- a/native/android/include_platform/android/dynamic_instrumentation_manager.h
+++ b/native/android/include_platform/android/dynamic_instrumentation_manager.h
@@ -51,7 +51,7 @@
  * @param instance returned from ADynamicInstrumentationManager_TargetProcess_create.
  */
 void ADynamicInstrumentationManager_TargetProcess_destroy(
-        ADynamicInstrumentationManager_TargetProcess* _Nonnull instance) __INTRODUCED_IN(36);
+        const ADynamicInstrumentationManager_TargetProcess* _Nonnull instance) __INTRODUCED_IN(36);
 
 /**
  * Initializes an ADynamicInstrumentationManager_MethodDescriptor. Caller must clean up when they
@@ -74,7 +74,8 @@
  * @param instance returned from ADynamicInstrumentationManager_MethodDescriptor_create.
  */
 void ADynamicInstrumentationManager_MethodDescriptor_destroy(
-        ADynamicInstrumentationManager_MethodDescriptor* _Nonnull instance) __INTRODUCED_IN(36);
+        const ADynamicInstrumentationManager_MethodDescriptor* _Nonnull instance)
+        __INTRODUCED_IN(36);
 
 /**
  * Get the containerPath calculated by
@@ -83,7 +84,7 @@
  * @return The OS path of the containing file.
  */
 const char* _Nullable ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getContainerPath(
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
         __INTRODUCED_IN(36);
 /**
  * Get the containerOffset calculated by
@@ -92,7 +93,7 @@
  * @return The offset of the containing file within the process' memory.
  */
 uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getContainerOffset(
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
         __INTRODUCED_IN(36);
 /**
  * Get the methodOffset calculated by ADynamicInstrumentationManager_getExecutableMethodFileOffsets.
@@ -100,7 +101,7 @@
  * @return The offset of the method within the containing file.
  */
 uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getMethodOffset(
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
         __INTRODUCED_IN(36);
 /**
  * Clean up an ADynamicInstrumentationManager_ExecutableMethodFileOffsets.
@@ -108,7 +109,7 @@
  * @param instance returned from ADynamicInstrumentationManager_getExecutableMethodFileOffsets.
  */
 void ADynamicInstrumentationManager_ExecutableMethodFileOffsets_destroy(
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
         __INTRODUCED_IN(36);
 /**
  * Provides ART metadata about the described java method within the target process.
@@ -124,7 +125,7 @@
 int32_t ADynamicInstrumentationManager_getExecutableMethodFileOffsets(
         const ADynamicInstrumentationManager_TargetProcess* _Nonnull targetProcess,
         const ADynamicInstrumentationManager_MethodDescriptor* _Nonnull methodDescriptor,
-        ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull* _Nullable out)
+        const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nullable* _Nonnull out)
         __INTRODUCED_IN(36);
 
 __END_DECLS
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 6b41ddd..7f555a8 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -95,6 +95,15 @@
     AConfiguration_setTouchscreen;
     AConfiguration_setUiModeNight;
     AConfiguration_setUiModeType;
+    ADisplayLuts_create; # introduced=36
+    ADisplayLuts_setEntries; # introduced=36
+    ADisplayLuts_destroy; # introduced=36
+    ADisplayLutsEntry_createEntry; # introduced=36
+    ADisplayLutsEntry_getDimension; # introduced=36
+    ADisplayLutsEntry_getSize; # introduced=36
+    ADisplayLutsEntry_getSamplingKey; # introduced=36
+    ADisplayLutsEntry_getBuffer; # introduced=36
+    ADisplayLutsEntry_destroy; # introduced=36
     AInputEvent_getDeviceId;
     AInputEvent_getSource;
     AInputEvent_getType;
@@ -300,6 +309,7 @@
     ASurfaceTransaction_setHdrMetadata_smpte2086; # introduced=29
     ASurfaceTransaction_setExtendedRangeBrightness; # introduced=UpsideDownCake
     ASurfaceTransaction_setDesiredHdrHeadroom; # introduced=VanillaIceCream
+    ASurfaceTransaction_setLuts; # introduced=36
     ASurfaceTransaction_setOnComplete; # introduced=29
     ASurfaceTransaction_setOnCommit; # introduced=31
     ASurfaceTransaction_setPosition; # introduced=31
@@ -355,12 +365,14 @@
     APerformanceHint_getManager; # introduced=Tiramisu
     APerformanceHint_createSession; # introduced=Tiramisu
     APerformanceHint_getPreferredUpdateRateNanos; # introduced=Tiramisu
+    APerformanceHint_getMaxGraphicsPipelineThreadsCount; # introduced=36
     APerformanceHint_updateTargetWorkDuration; # introduced=Tiramisu
     APerformanceHint_reportActualWorkDuration; # introduced=Tiramisu
     APerformanceHint_closeSession; # introduced=Tiramisu
     APerformanceHint_setThreads; # introduced=UpsideDownCake
     APerformanceHint_setPreferPowerEfficiency; # introduced=VanillaIceCream
     APerformanceHint_reportActualWorkDuration2; # introduced=VanillaIceCream
+    APerformanceHint_createSessionUsingConfig; # introduced=36
     APerformanceHint_notifyWorkloadIncrease; # introduced=36
     APerformanceHint_notifyWorkloadReset; # introduced=36
     APerformanceHint_borrowSessionFromJava; # introduced=36
@@ -370,6 +382,12 @@
     AWorkDuration_setActualTotalDurationNanos; # introduced=VanillaIceCream
     AWorkDuration_setActualCpuDurationNanos; # introduced=VanillaIceCream
     AWorkDuration_setActualGpuDurationNanos; # introduced=VanillaIceCream
+    ASessionCreationConfig_create; # introduced=36
+    ASessionCreationConfig_release; # introduced=36
+    ASessionCreationConfig_setTids; # introduced=36
+    ASessionCreationConfig_setTargetWorkDurationNanos; # introduced=36
+    ASessionCreationConfig_setPreferPowerEfficiency; # introduced=36
+    ASessionCreationConfig_setGraphicsPipeline; # introduced=36
   local:
     *;
 };
@@ -379,8 +397,10 @@
     AThermal_setIThermalServiceForTesting;
     APerformanceHint_setIHintManagerForTesting;
     APerformanceHint_sendHint;
+    APerformanceHint_setUseGraphicsPipelineForTesting;
     APerformanceHint_getThreadIds;
     APerformanceHint_createSessionInternal;
+    APerformanceHint_createSessionUsingConfigInternal;
     APerformanceHint_setUseFMQForTesting;
     APerformanceHint_getRateLimiterPropertiesForTesting;
     APerformanceHint_setUseNewLoadHintBehaviorForTesting;
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index bc1945e..883e139 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -26,6 +26,7 @@
 #include <aidl/android/hardware/power/WorkDurationFixedV1.h>
 #include <aidl/android/os/IHintManager.h>
 #include <aidl/android/os/IHintSession.h>
+#include <aidl/android/os/SessionCreationConfig.h>
 #include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
 #include <android/binder_manager.h>
@@ -65,6 +66,13 @@
 
 constexpr int64_t SEND_HINT_TIMEOUT = std::chrono::nanoseconds(100ms).count();
 struct AWorkDuration : public hal::WorkDuration {};
+struct ASessionCreationConfig : public SessionCreationConfig {};
+
+bool kForceGraphicsPipeline = false;
+
+bool useGraphicsPipeline() {
+    return android::os::adpf_graphics_pipeline() || kForceGraphicsPipeline;
+}
 
 // A pair of values that determine the behavior of the
 // load hint rate limiter, to only allow "X hints every Y seconds"
@@ -142,7 +150,11 @@
                                            bool isJava = false);
     APerformanceHintSession* getSessionFromJava(JNIEnv* _Nonnull env, jobject _Nonnull sessionObj);
 
+    APerformanceHintSession* createSessionUsingConfig(ASessionCreationConfig* sessionCreationConfig,
+                                                      hal::SessionTag tag = hal::SessionTag::APP,
+                                                      bool isJava = false);
     int64_t getPreferredRateNanos() const;
+    int32_t getMaxGraphicsPipelineThreadsCount();
     FMQWrapper& getFMQWrapper();
     bool canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) REQUIRES(sHintMutex);
     void initJava(JNIEnv* _Nonnull env);
@@ -163,6 +175,7 @@
     std::shared_ptr<IHintManager> mHintManager;
     ndk::SpAIBinder mToken;
     const int64_t mPreferredRateNanos;
+    std::optional<int32_t> mMaxGraphicsPipelineThreadsCount;
     FMQWrapper mFMQWrapper;
     double mHintBudget = kMaxLoadHintsPerInterval;
     int64_t mLastBudgetReplenish = 0;
@@ -220,8 +233,10 @@
     std::vector<int32_t> mLastThreadIDs GUARDED_BY(sHintMutex);
     std::optional<hal::SessionConfig> mSessionConfig GUARDED_BY(sHintMutex);
     // Tracing helpers
-    void traceThreads(std::vector<int32_t>& tids) REQUIRES(sHintMutex);
+    void traceThreads(const std::vector<int32_t>& tids) REQUIRES(sHintMutex);
     void tracePowerEfficient(bool powerEfficient);
+    void traceGraphicsPipeline(bool graphicsPipeline);
+    void traceModes(const std::vector<hal::SessionMode>& modesToEnable);
     void traceActualDuration(int64_t actualDuration);
     void traceBatchSize(size_t batchSize);
     void traceTargetDuration(int64_t targetDuration);
@@ -311,27 +326,45 @@
 APerformanceHintSession* APerformanceHintManager::createSession(
         const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos,
         hal::SessionTag tag, bool isJava) {
-    std::vector<int32_t> tids(threadIds, threadIds + size);
-    std::shared_ptr<IHintSession> session;
     ndk::ScopedAStatus ret;
     hal::SessionConfig sessionConfig{.id = -1};
-    ret = mHintManager->createHintSessionWithConfig(mToken, tids, initialTargetWorkDurationNanos,
-                                                    tag, &sessionConfig, &session);
+
+    SessionCreationConfig creationConfig{
+            .tids = std::vector<int32_t>(threadIds, threadIds + size),
+            .targetWorkDurationNanos = initialTargetWorkDurationNanos,
+    };
+
+    return APerformanceHintManager::createSessionUsingConfig(static_cast<ASessionCreationConfig*>(
+                                                                     &creationConfig),
+                                                             tag, isJava);
+}
+
+APerformanceHintSession* APerformanceHintManager::createSessionUsingConfig(
+        ASessionCreationConfig* sessionCreationConfig, hal::SessionTag tag, bool isJava) {
+    std::shared_ptr<IHintSession> session;
+    hal::SessionConfig sessionConfig{.id = -1};
+    ndk::ScopedAStatus ret;
+
+    ret = mHintManager->createHintSessionWithConfig(mToken, tag,
+                                                    *static_cast<SessionCreationConfig*>(
+                                                            sessionCreationConfig),
+                                                    &sessionConfig, &session);
 
     if (!ret.isOk() || !session) {
         ALOGE("%s: PerformanceHint cannot create session. %s", __FUNCTION__, ret.getMessage());
         return nullptr;
     }
     auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
-                                           initialTargetWorkDurationNanos, isJava,
+                                           sessionCreationConfig->targetWorkDurationNanos, isJava,
                                            sessionConfig.id == -1
                                                    ? std::nullopt
                                                    : std::make_optional<hal::SessionConfig>(
                                                              std::move(sessionConfig)));
     std::scoped_lock lock(sHintMutex);
-    out->traceThreads(tids);
-    out->traceTargetDuration(initialTargetWorkDurationNanos);
-    out->tracePowerEfficient(false);
+    out->traceThreads(sessionCreationConfig->tids);
+    out->traceTargetDuration(sessionCreationConfig->targetWorkDurationNanos);
+    out->traceModes(sessionCreationConfig->modesToEnable);
+
     return out;
 }
 
@@ -351,6 +384,23 @@
     return mPreferredRateNanos;
 }
 
+int32_t APerformanceHintManager::getMaxGraphicsPipelineThreadsCount() {
+    if (!mMaxGraphicsPipelineThreadsCount.has_value()) {
+        int32_t threadsCount = -1;
+        ndk::ScopedAStatus ret = mHintManager->getMaxGraphicsPipelineThreadsCount(&threadsCount);
+        if (!ret.isOk()) {
+            ALOGE("%s: PerformanceHint cannot get max graphics pipeline threads count. %s",
+                  __FUNCTION__, ret.getMessage());
+            return -1;
+        }
+        if (threadsCount <= 0) {
+            threadsCount = -1;
+        }
+        mMaxGraphicsPipelineThreadsCount.emplace(threadsCount);
+    }
+    return mMaxGraphicsPipelineThreadsCount.value();
+}
+
 FMQWrapper& APerformanceHintManager::getFMQWrapper() {
     return mFMQWrapper;
 }
@@ -787,7 +837,7 @@
 
 // ===================================== Tracing helpers
 
-void APerformanceHintSession::traceThreads(std::vector<int32_t>& tids) {
+void APerformanceHintSession::traceThreads(const std::vector<int32_t>& tids) {
     std::set<int32_t> tidSet{tids.begin(), tids.end()};
 
     // Disable old TID tracing
@@ -813,6 +863,30 @@
     ATrace_setCounter((mSessionName + " power efficiency mode").c_str(), powerEfficient);
 }
 
+void APerformanceHintSession::traceGraphicsPipeline(bool graphicsPipeline) {
+    ATrace_setCounter((mSessionName + " graphics pipeline mode").c_str(), graphicsPipeline);
+}
+
+void APerformanceHintSession::traceModes(const std::vector<hal::SessionMode>& modesToEnable) {
+    // Iterate through all modes to trace, set to enable for all modes in modesToEnable,
+    // and set to disable for those are not.
+    for (hal::SessionMode mode :
+         {hal::SessionMode::POWER_EFFICIENCY, hal::SessionMode::GRAPHICS_PIPELINE}) {
+        bool isEnabled =
+                find(modesToEnable.begin(), modesToEnable.end(), mode) != modesToEnable.end();
+        switch (mode) {
+            case hal::SessionMode::POWER_EFFICIENCY:
+                tracePowerEfficient(isEnabled);
+                break;
+            case hal::SessionMode::GRAPHICS_PIPELINE:
+                traceGraphicsPipeline(isEnabled);
+                break;
+            default:
+                break;
+        }
+    }
+}
+
 void APerformanceHintSession::traceActualDuration(int64_t actualDuration) {
     ATrace_setCounter((mSessionName + " actual duration").c_str(), actualDuration);
 }
@@ -855,6 +929,22 @@
     return manager->createSession(threadIds, size, initialTargetWorkDurationNanos);
 }
 
+APerformanceHintSession* APerformanceHint_createSessionUsingConfig(
+        APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig) {
+    VALIDATE_PTR(manager);
+    VALIDATE_PTR(sessionCreationConfig);
+    return manager->createSessionUsingConfig(sessionCreationConfig);
+}
+
+APerformanceHintSession* APerformanceHint_createSessionUsingConfigInternal(
+        APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig,
+        SessionTag tag) {
+    VALIDATE_PTR(manager);
+    VALIDATE_PTR(sessionCreationConfig);
+    return manager->createSessionUsingConfig(sessionCreationConfig,
+                                             static_cast<hal::SessionTag>(tag));
+}
+
 APerformanceHintSession* APerformanceHint_createSessionInternal(
         APerformanceHintManager* manager, const int32_t* threadIds, size_t size,
         int64_t initialTargetWorkDurationNanos, SessionTag tag) {
@@ -885,6 +975,11 @@
     return manager->getPreferredRateNanos();
 }
 
+int APerformanceHint_getMaxGraphicsPipelineThreadsCount(APerformanceHintManager* manager) {
+    VALIDATE_PTR(manager);
+    return manager->getMaxGraphicsPipelineThreadsCount();
+}
+
 int APerformanceHint_updateTargetWorkDuration(APerformanceHintSession* session,
                                               int64_t targetDurationNanos) {
     VALIDATE_PTR(session)
@@ -1018,6 +1113,81 @@
     gForceFMQEnabled = enabled;
 }
 
+ASessionCreationConfig* ASessionCreationConfig_create() {
+    return new ASessionCreationConfig();
+}
+
+void ASessionCreationConfig_release(ASessionCreationConfig* config) {
+    VALIDATE_PTR(config)
+
+    delete config;
+}
+
+int ASessionCreationConfig_setTids(ASessionCreationConfig* config, const pid_t* tids, size_t size) {
+    VALIDATE_PTR(config)
+    VALIDATE_PTR(tids)
+
+    if (!useGraphicsPipeline()) {
+        return ENOTSUP;
+    }
+
+    if (size <= 0) {
+        LOG_ALWAYS_FATAL_IF(size <= 0,
+                            "%s: Invalid value. Thread id list size should be greater than zero.",
+                            __FUNCTION__);
+        return EINVAL;
+    }
+    config->tids = std::vector<int32_t>(tids, tids + size);
+    return 0;
+}
+
+int ASessionCreationConfig_setTargetWorkDurationNanos(ASessionCreationConfig* config,
+                                                      int64_t targetWorkDurationNanos) {
+    VALIDATE_PTR(config)
+    VALIDATE_INT(targetWorkDurationNanos, >= 0)
+
+    if (!useGraphicsPipeline()) {
+        return ENOTSUP;
+    }
+
+    config->targetWorkDurationNanos = targetWorkDurationNanos;
+    return 0;
+}
+
+int ASessionCreationConfig_setPreferPowerEfficiency(ASessionCreationConfig* config, bool enabled) {
+    VALIDATE_PTR(config)
+
+    if (!useGraphicsPipeline()) {
+        return ENOTSUP;
+    }
+
+    if (enabled) {
+        config->modesToEnable.push_back(hal::SessionMode::POWER_EFFICIENCY);
+    } else {
+        std::erase(config->modesToEnable, hal::SessionMode::POWER_EFFICIENCY);
+    }
+    return 0;
+}
+
+int ASessionCreationConfig_setGraphicsPipeline(ASessionCreationConfig* config, bool enabled) {
+    VALIDATE_PTR(config)
+
+    if (!useGraphicsPipeline()) {
+        return ENOTSUP;
+    }
+
+    if (enabled) {
+        config->modesToEnable.push_back(hal::SessionMode::GRAPHICS_PIPELINE);
+    } else {
+        std::erase(config->modesToEnable, hal::SessionMode::GRAPHICS_PIPELINE);
+    }
+    return 0;
+}
+
+void APerformanceHint_setUseGraphicsPipelineForTesting(bool enabled) {
+    kForceGraphicsPipeline = enabled;
+}
+
 void APerformanceHint_getRateLimiterPropertiesForTesting(int32_t* maxLoadHintsPerInterval,
                                                          int64_t* loadHintInterval) {
     *maxLoadHintsPerInterval = kMaxLoadHintsPerInterval;
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 698bc84..fc64e9b 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -14,12 +14,15 @@
  * limitations under the License.
  */
 
+#include <android/gui/LutProperties.h>
 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <android/native_window.h>
 #include <android/surface_control.h>
 #include <android/surface_control_jni.h>
 #include <android_runtime/android_view_SurfaceControl.h>
 #include <configstore/Utils.h>
+#include <cutils/ashmem.h>
+#include <display_luts_private.h>
 #include <gui/HdrMetadata.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/Surface.h>
@@ -53,6 +56,14 @@
 static_assert(static_cast<int>(ADATASPACE_DISPLAY_P3) ==
               static_cast<int>(HAL_DATASPACE_DISPLAY_P3));
 static_assert(static_cast<int>(ADATASPACE_BT2020_PQ) == static_cast<int>(HAL_DATASPACE_BT2020_PQ));
+static_assert(static_cast<int>(ADISPLAYLUTS_ONE_DIMENSION) ==
+              static_cast<int>(android::gui::LutProperties::Dimension::ONE_D));
+static_assert(static_cast<int>(ADISPLAYLUTS_THREE_DIMENSION) ==
+              static_cast<int>(android::gui::LutProperties::Dimension::THREE_D));
+static_assert(static_cast<int>(ADISPLAYLUTS_SAMPLINGKEY_RGB) ==
+              static_cast<int>(android::gui::LutProperties::SamplingKey::RGB));
+static_assert(static_cast<int>(ADISPLAYLUTS_SAMPLINGKEY_MAX_RGB) ==
+              static_cast<int>(android::gui::LutProperties::SamplingKey::MAX_RGB));
 
 Transaction* ASurfaceTransaction_to_Transaction(ASurfaceTransaction* aSurfaceTransaction) {
     return reinterpret_cast<Transaction*>(aSurfaceTransaction);
@@ -693,6 +704,58 @@
     transaction->setDesiredHdrHeadroom(surfaceControl, desiredRatio);
 }
 
+void ASurfaceTransaction_setLuts(ASurfaceTransaction* aSurfaceTransaction,
+                                 ASurfaceControl* aSurfaceControl,
+                                 const struct ADisplayLuts* luts) {
+    CHECK_NOT_NULL(aSurfaceTransaction);
+    CHECK_NOT_NULL(aSurfaceControl);
+
+    sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
+    Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+    int fd = -1;
+    std::vector<int32_t> offsets;
+    std::vector<int32_t> dimensions;
+    std::vector<int32_t> sizes;
+    std::vector<int32_t> samplingKeys;
+
+    if (luts) {
+        std::vector<float> buffer(luts->totalBufferSize);
+        int32_t count = luts->offsets.size();
+        offsets = luts->offsets;
+
+        dimensions.reserve(count);
+        sizes.reserve(count);
+        samplingKeys.reserve(count);
+        for (int32_t i = 0; i < count; i++) {
+            dimensions.emplace_back(luts->entries[i]->properties.dimension);
+            sizes.emplace_back(luts->entries[i]->properties.size);
+            samplingKeys.emplace_back(luts->entries[i]->properties.samplingKey);
+            std::copy(luts->entries[i]->buffer.data.begin(), luts->entries[i]->buffer.data.end(),
+                      buffer.begin() + offsets[i]);
+        }
+
+        // mmap
+        fd = ashmem_create_region("lut_shared_mem", luts->totalBufferSize * sizeof(float));
+        if (fd < 0) {
+            LOG_ALWAYS_FATAL("setLuts, ashmem_create_region() failed");
+            return;
+        }
+        void* ptr = mmap(nullptr, luts->totalBufferSize * sizeof(float), PROT_READ | PROT_WRITE,
+                         MAP_SHARED, fd, 0);
+        if (ptr == MAP_FAILED) {
+            LOG_ALWAYS_FATAL("setLuts, Failed to map the shared memory");
+            return;
+        }
+
+        memcpy(ptr, buffer.data(), luts->totalBufferSize * sizeof(float));
+        munmap(ptr, luts->totalBufferSize * sizeof(float));
+    }
+
+    transaction->setLuts(surfaceControl, base::unique_fd(fd), offsets, dimensions, sizes,
+                         samplingKeys);
+}
+
 void ASurfaceTransaction_setColor(ASurfaceTransaction* aSurfaceTransaction,
                                   ASurfaceControl* aSurfaceControl,
                                   float r, float g, float b, float alpha,
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index f707a0e..b006580 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -18,9 +18,11 @@
 
 #include <aidl/android/hardware/power/ChannelConfig.h>
 #include <aidl/android/hardware/power/SessionConfig.h>
+#include <aidl/android/hardware/power/SessionMode.h>
 #include <aidl/android/hardware/power/SessionTag.h>
 #include <aidl/android/hardware/power/WorkDuration.h>
 #include <aidl/android/os/IHintManager.h>
+#include <aidl/android/os/SessionCreationConfig.h>
 #include <android/binder_manager.h>
 #include <android/binder_status.h>
 #include <android/performance_hint.h>
@@ -36,6 +38,7 @@
 namespace hal = aidl::android::hardware::power;
 using aidl::android::os::IHintManager;
 using aidl::android::os::IHintSession;
+using aidl::android::os::SessionCreationConfig;
 using ndk::ScopedAStatus;
 using ndk::SpAIBinder;
 using HalChannelMessageContents = hal::ChannelMessage::ChannelMessageContents;
@@ -49,11 +52,13 @@
 class MockIHintManager : public IHintManager {
 public:
     MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig,
-                (const SpAIBinder& token, const ::std::vector<int32_t>& tids, int64_t durationNanos,
-                 hal::SessionTag tag, hal::SessionConfig* config,
+                (const SpAIBinder& token, hal::SessionTag tag,
+                 const SessionCreationConfig& creationConfig, hal::SessionConfig* config,
                  std::shared_ptr<IHintSession>* _aidl_return),
                 (override));
     MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
+    MOCK_METHOD(ScopedAStatus, getMaxGraphicsPipelineThreadsCount, (int32_t* _aidl_return),
+                (override));
     MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
                 (const std::shared_ptr<IHintSession>& hintSession,
                  const ::std::vector<int32_t>& tids),
@@ -68,13 +73,13 @@
     MOCK_METHOD(ScopedAStatus, closeSessionChannel, (), (override));
     MOCK_METHOD(ScopedAStatus, getCpuHeadroom,
                 (const ::aidl::android::os::CpuHeadroomParamsInternal& in_params,
-                 std::vector<float>* _aidl_return),
+                 std::optional<hal::CpuHeadroomResult>* _aidl_return),
                 (override));
     MOCK_METHOD(ScopedAStatus, getCpuHeadroomMinIntervalMillis, (int64_t* _aidl_return),
                 (override));
     MOCK_METHOD(ScopedAStatus, getGpuHeadroom,
                 (const ::aidl::android::os::GpuHeadroomParamsInternal& in_params,
-                 float* _aidl_return),
+                 std::optional<hal::GpuHeadroomResult>* _aidl_return),
                 (override));
     MOCK_METHOD(ScopedAStatus, getGpuHeadroomMinIntervalMillis, (int64_t* _aidl_return),
                 (override));
@@ -105,6 +110,7 @@
         APerformanceHint_getRateLimiterPropertiesForTesting(&mMaxLoadHintsPerInterval,
                                                             &mLoadHintInterval);
         APerformanceHint_setIHintManagerForTesting(&mMockIHintManager);
+        APerformanceHint_setUseGraphicsPipelineForTesting(true);
         APerformanceHint_setUseNewLoadHintBehaviorForTesting(true);
     }
 
@@ -118,21 +124,22 @@
         APerformanceHint_setUseFMQForTesting(mUsingFMQ);
         ON_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
                 .WillByDefault(DoAll(SetArgPointee<0>(123L), [] { return ScopedAStatus::ok(); }));
+        ON_CALL(*mMockIHintManager, getMaxGraphicsPipelineThreadsCount(_))
+                .WillByDefault(DoAll(SetArgPointee<0>(5), [] { return ScopedAStatus::ok(); }));
         return APerformanceHint_getManager();
     }
 
     APerformanceHintSession* createSession(APerformanceHintManager* manager,
                                            int64_t targetDuration = 56789L, bool isHwui = false) {
         mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
-        int64_t sessionId = 123;
+        const int64_t sessionId = 123;
         std::vector<int32_t> tids;
         tids.push_back(1);
         tids.push_back(2);
 
-        ON_CALL(*mMockIHintManager,
-                createHintSessionWithConfig(_, Eq(tids), Eq(targetDuration), _, _, _))
-                .WillByDefault(DoAll(SetArgPointee<4>(hal::SessionConfig({.id = sessionId})),
-                                     SetArgPointee<5>(std::shared_ptr<IHintSession>(mMockSession)),
+        ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
+                .WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
+                                     SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
                                      [] { return ScopedAStatus::ok(); }));
 
         ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
@@ -157,6 +164,43 @@
         return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
     }
 
+    APerformanceHintSession* createSessionUsingConfig(APerformanceHintManager* manager,
+                                                      SessionCreationConfig config,
+                                                      bool isHwui = false) {
+        mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
+        const int64_t sessionId = 123;
+
+        ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
+                .WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
+                                     SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
+                                     [] { return ScopedAStatus::ok(); }));
+
+        ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
+            return ScopedAStatus::ok();
+        });
+        ON_CALL(*mMockSession, sendHint(_)).WillByDefault([] { return ScopedAStatus::ok(); });
+        ON_CALL(*mMockSession, setMode(_, true)).WillByDefault([] { return ScopedAStatus::ok(); });
+        ON_CALL(*mMockSession, close()).WillByDefault([] { return ScopedAStatus::ok(); });
+        ON_CALL(*mMockSession, updateTargetWorkDuration(_)).WillByDefault([] {
+            return ScopedAStatus::ok();
+        });
+        ON_CALL(*mMockSession, reportActualWorkDuration(_, _)).WillByDefault([] {
+            return ScopedAStatus::ok();
+        });
+        ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
+            return ScopedAStatus::ok();
+        });
+
+        if (isHwui) {
+            return APerformanceHint_createSessionUsingConfigInternal(
+                    manager, reinterpret_cast<ASessionCreationConfig*>(&config), SessionTag::HWUI);
+        }
+
+        return APerformanceHint_createSessionUsingConfig(manager,
+                                                         reinterpret_cast<ASessionCreationConfig*>(
+                                                                 &config));
+    }
+
     void setFMQEnabled(bool enabled) {
         mUsingFMQ = enabled;
         if (enabled) {
@@ -272,16 +316,26 @@
 }
 
 TEST_F(PerformanceHintTest, TestUpdatedSessionCreation) {
-    EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _, _)).Times(1);
+    EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
     APerformanceHintManager* manager = createManager();
     APerformanceHintSession* session = createSession(manager);
     ASSERT_TRUE(session);
     APerformanceHint_closeSession(session);
 }
 
+TEST_F(PerformanceHintTest, TestSessionCreationUsingConfig) {
+    EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
+    SessionCreationConfig config{.tids = std::vector<int32_t>(1, 2),
+                                 .targetWorkDurationNanos = 5678,
+                                 .modesToEnable = std::vector<hal::SessionMode>(0)};
+    APerformanceHintManager* manager = createManager();
+    APerformanceHintSession* session = createSessionUsingConfig(manager, config);
+    ASSERT_TRUE(session);
+    APerformanceHint_closeSession(session);
+}
+
 TEST_F(PerformanceHintTest, TestHwuiSessionCreation) {
-    EXPECT_CALL(*mMockIHintManager,
-                createHintSessionWithConfig(_, _, _, hal::SessionTag::HWUI, _, _))
+    EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, hal::SessionTag::HWUI, _, _, _))
             .Times(1);
     APerformanceHintManager* manager = createManager();
     APerformanceHintSession* session = createSession(manager, 56789L, true);
@@ -447,3 +501,16 @@
                                                reinterpret_cast<AWorkDuration*>(&duration));
     expectToReadFromFmq<HalChannelMessageContents::Tag::workDuration>(durationExpected);
 }
+
+TEST_F(PerformanceHintTest, TestASessionCreationConfig) {
+    ASessionCreationConfig* config = ASessionCreationConfig_create();
+    ASSERT_NE(config, nullptr);
+
+    const int32_t testTids[2] = {1, 2};
+    const size_t size = 2;
+    EXPECT_EQ(ASessionCreationConfig_setTids(config, testTids, size), 0);
+    EXPECT_EQ(ASessionCreationConfig_setTargetWorkDurationNanos(config, 20), 0);
+    EXPECT_EQ(ASessionCreationConfig_setPreferPowerEfficiency(config, true), 0);
+    EXPECT_EQ(ASessionCreationConfig_setGraphicsPipeline(config, true), 0);
+    ASessionCreationConfig_release(config);
+}
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 7ae2eafa..0ee81cb 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -202,6 +202,7 @@
     method public boolean categoryAllowsForegroundPreference(String);
     method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
     method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
+    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public int getDefaultNfcSubscriptionId();
     method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService();
     method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
     method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService();
@@ -232,6 +233,7 @@
     field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1; // 0x1
     field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2; // 0x2
     field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0; // 0x0
+    field @FlaggedApi("android.nfc.nfc_associated_role_services") public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY = "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
     field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3; // 0x3
     field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0; // 0x0
     field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1; // 0x1
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 15814ed..3ed9b76 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -57,17 +57,19 @@
   @FlaggedApi("android.nfc.nfc_oem_extension") public final class NfcOemExtension {
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int forceRoutingTableCommit();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.List<java.lang.String> getActiveNfceeList();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getActiveNfceeList();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public long getMaxPausePollingTimeoutMills();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.nfc.RoutingStatus getRoutingStatus();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.List<android.nfc.NfcRoutingTableEntry> getRoutingTable();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.T4tNdefNfcee getT4tNdefNfcee();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean hasUserEnabledNfc();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAutoChangeEnabled();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagPresent();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overwriteRoutingTable(int, int, int, int);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void pausePolling(int);
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int pausePolling(long);
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void resumePolling();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int resumePolling();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAutoChangeEnabled(boolean);
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void setControllerAlwaysOnMode(int);
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState();
@@ -83,6 +85,8 @@
     field public static final int HCE_ACTIVATE = 1; // 0x1
     field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
     field public static final int HCE_DEACTIVATE = 3; // 0x3
+    field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
+    field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
     field public static final int STATUS_OK = 0; // 0x0
     field public static final int STATUS_UNKNOWN_ERROR = 1; // 0x1
   }
@@ -120,6 +124,11 @@
 
   @FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry {
     method public int getNfceeId();
+    method public int getType();
+    field public static final int TYPE_AID = 0; // 0x0
+    field public static final int TYPE_PROTOCOL = 1; // 0x1
+    field public static final int TYPE_SYSTEM_CODE = 3; // 0x3
+    field public static final int TYPE_TECHNOLOGY = 2; // 0x2
   }
 
   @FlaggedApi("android.nfc.nfc_oem_extension") public final class OemLogItems implements android.os.Parcelable {
@@ -179,6 +188,47 @@
     field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_V = 3; // 0x3
   }
 
+  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfcee {
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int clearData();
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isOperationOngoing();
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isSupported();
+    method @Nullable @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public android.nfc.T4tNdefNfceeCcFileInfo readCcfile();
+    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public byte[] readData(@IntRange(from=0, to=65535) int);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int writeData(@IntRange(from=0, to=65535) int, @NonNull byte[]);
+    field public static final int CLEAR_DATA_FAILED_INTERNAL = 0; // 0x0
+    field public static final int CLEAR_DATA_SUCCESS = 1; // 0x1
+    field public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6; // 0xfffffffa
+    field public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7; // 0xfffffff9
+    field public static final int WRITE_DATA_ERROR_INTERNAL = -1; // 0xffffffff
+    field public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4; // 0xfffffffc
+    field public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5; // 0xfffffffb
+    field public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8; // 0xfffffff8
+    field public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3; // 0xfffffffd
+    field public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2; // 0xfffffffe
+    field public static final int WRITE_DATA_SUCCESS = 0; // 0x0
+  }
+
+  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfceeCcFileInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=15, to=32767) public int getCcFileLength();
+    method @IntRange(from=0xffffffff, to=65535) public int getFileId();
+    method @IntRange(from=15, to=65535) public int getMaxReadLength();
+    method @IntRange(from=5, to=32767) public int getMaxSize();
+    method @IntRange(from=13, to=65535) public int getMaxWriteLength();
+    method public int getReadAccess();
+    method public int getVersion();
+    method public int getWriteAccess();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.T4tNdefNfceeCcFileInfo> CREATOR;
+    field public static final int READ_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
+    field public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
+    field public static final int VERSION_2_0 = 32; // 0x20
+    field public static final int VERSION_3_0 = 48; // 0x30
+    field public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
+    field public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
+    field public static final int WRITE_ACCESS_NOT_GRANTED = 255; // 0xff
+  }
+
 }
 
 package android.nfc.cardemulation {
@@ -186,14 +236,19 @@
   public final class CardEmulation {
     method @FlaggedApi("android.permission.flags.wallet_role_enabled") @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static android.content.ComponentName getPreferredPaymentService(@NonNull android.content.Context);
     method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int);
-    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void overrideRoutingTable(@NonNull android.app.Activity, int, int);
-    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void recoverRoutingTable(@NonNull android.app.Activity);
+    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overrideRoutingTable(@NonNull android.app.Activity, int, int);
+    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void recoverRoutingTable(@NonNull android.app.Activity);
+    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setDefaultNfcSubscriptionId(int);
     method @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setServiceEnabledForCategoryOther(@NonNull android.content.ComponentName, boolean);
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3; // 0x3
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1; // 0x1
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2; // 0x2
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4; // 0x4
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_OK = 0; // 0x0
+    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2; // 0x2
+    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1; // 0x1
+    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3; // 0x3
+    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0; // 0x0
   }
 
 }
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index a08b55f..ac0a5aa 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -31,6 +31,7 @@
 import android.nfc.INfcFCardEmulation;
 import android.nfc.INfcOemExtensionCallback;
 import android.nfc.INfcUnlockHandler;
+import android.nfc.IT4tNdefNfcee;
 import android.nfc.ITagRemovedCallback;
 import android.nfc.INfcDta;
 import android.nfc.INfcWlcStateListener;
@@ -52,8 +53,8 @@
     int getState();
     boolean disable(boolean saveState, in String pkg);
     boolean enable(in String pkg);
-    void pausePolling(int timeoutInMs);
-    void resumePolling();
+    int pausePolling(long timeoutInMs);
+    int resumePolling();
 
     void setForegroundDispatch(in PendingIntent intent,
             in IntentFilter[] filters, in TechListParcel techLists);
@@ -114,7 +115,7 @@
     void clearPreference();
     void setScreenState();
     void checkFirmware();
-    List<String> fetchActiveNfceeList();
+    Map fetchActiveNfceeList();
     void triggerInitialization();
     boolean getSettingStatus();
     boolean isTagPresent();
@@ -122,4 +123,6 @@
     void indicateDataMigration(boolean inProgress, String pkg);
     int commitRouting();
     boolean isTagIntentAllowed(in String pkg, in int Userid);
+    IT4tNdefNfcee getT4tNdefNfceeInterface();
+    long getMaxPausePollingTimeoutMs();
 }
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
index 633d8bf..bb9fe95 100644
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ b/nfc/java/android/nfc/INfcCardEmulation.aidl
@@ -53,6 +53,8 @@
     void overrideRoutingTable(int userHandle, String protocol, String technology, in String pkg);
     void recoverRoutingTable(int userHandle);
     boolean isEuiccSupported();
+    int getDefaultNfcSubscriptionId(in String pkg);
+    int setDefaultNfcSubscriptionId(int subscriptionId, in String pkg);
     void setAutoChangeStatus(boolean state);
     boolean isAutoChangeEnabled();
     List<String> getRoutingStatus();
diff --git a/nfc/java/android/nfc/IT4tNdefNfcee.aidl b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
new file mode 100644
index 0000000..b4cda5b
--- /dev/null
+++ b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
@@ -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 android.nfc;
+
+import android.nfc.T4tNdefNfceeCcFileInfo;
+
+/**
+ * @hide
+ */
+interface IT4tNdefNfcee {
+    int writeData(in int fileId, in byte[] data);
+    byte[] readData(in int fileId);
+    int clearNdefData();
+    boolean isNdefOperationOngoing();
+    boolean isNdefNfceeEmulationSupported();
+    T4tNdefNfceeCcFileInfo readCcfile();
+}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 056844f..89ce423 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -589,6 +589,7 @@
     static INfcTag sTagService;
     static INfcCardEmulation sCardEmulationService;
     static INfcFCardEmulation sNfcFCardEmulationService;
+    static IT4tNdefNfcee sNdefNfceeService;
 
     /**
      * The NfcAdapter object for each application context.
@@ -827,7 +828,13 @@
                     throw new UnsupportedOperationException();
                 }
             }
-
+            try {
+                sNdefNfceeService = sService.getT4tNdefNfceeInterface();
+            } catch (RemoteException e) {
+                sNdefNfceeService = null;
+                Log.e(TAG, "could not retrieve NDEF NFCEE service");
+                throw new UnsupportedOperationException();
+            }
             sIsInitialized = true;
         }
         NfcAdapter adapter = sNfcAdapters.get(context);
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 9ed678f..f78161e 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -39,6 +39,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
+import android.se.omapi.Reader;
 import android.util.Log;
 
 import java.lang.annotation.Retention;
@@ -148,6 +149,48 @@
     public @interface ControllerMode{}
 
     /**
+     * Technology Type for {@link #getActiveNfceeList()}.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    public static final int NFCEE_TECH_NONE = 0;
+
+    /**
+     * Technology Type for {@link #getActiveNfceeList()}.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    public static final int NFCEE_TECH_A = 1;
+
+    /**
+     * Technology Type for {@link #getActiveNfceeList()}.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    public static final int NFCEE_TECH_B = 1 << 1;
+
+    /**
+     * Technology Type for {@link #getActiveNfceeList()}.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    public static final int NFCEE_TECH_F = 1 << 2;
+
+    /**
+     * Nfc technology flags for {@link #getActiveNfceeList()}.
+     *
+     * @hide
+     */
+    @IntDef(flag = true, value = {
+        NFCEE_TECH_NONE,
+        NFCEE_TECH_A,
+        NFCEE_TECH_B,
+        NFCEE_TECH_F,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NfceeTechnology {}
+
+    /**
      * Event that Host Card Emulation is activated.
      */
     public static final int HCE_ACTIVATE = 1;
@@ -173,6 +216,31 @@
     public @interface HostCardEmulationAction {}
 
     /**
+     * Status code returned when the polling state change request succeeded.
+     * @see #pausePolling()
+     * @see #resumePolling()
+     */
+    public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1;
+    /**
+     * Status code returned when the polling state change request is already in
+     * required state.
+     * @see #pausePolling()
+     * @see #resumePolling()
+     */
+    public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2;
+    /**
+     * Possible status codes for {@link #pausePolling()} and
+     * {@link #resumePolling()}.
+     * @hide
+     */
+    @IntDef(value = {
+            POLLING_STATE_CHANGE_SUCCEEDED,
+            POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PollingStateChangeStatusCode {}
+
+    /**
      * Status OK
      */
     public static final int STATUS_OK = 0;
@@ -467,6 +535,28 @@
     }
 
     /**
+     * Get an instance of {@link T4tNdefNfcee} object for performing T4T (Type-4 Tag)
+     * NDEF (NFC Data Exchange Format) NFCEE (NFC Execution Environment) operations.
+     * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
+     * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
+     * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     *
+     * This is a singleton object which shall be used by OEM extension module to do NDEF-NFCEE
+     * read/write operations.
+     *
+     * <p>Returns {@link T4tNdefNfcee}
+     * <p>Does not cause any RF activity and does not block.
+     * @return NFC Data Exchange Format (NDEF) NFC Execution Environment (NFCEE) object
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    public T4tNdefNfcee getT4tNdefNfcee() {
+        return T4tNdefNfcee.getInstance();
+    }
+
+    /**
      * Register an {@link Callback} to listen for NFC oem extension callbacks
      * Multiple clients can register and callbacks will be invoked asynchronously.
      *
@@ -580,14 +670,18 @@
     /**
      * Get the Active NFCEE (NFC Execution Environment) List
      *
-     * @return List of activated secure elements on success
-     *         which can contain "eSE" and "UICC", otherwise empty list.
+     * @see Reader#getName() for the list of possible NFCEE names.
+     *
+     * @return Map< String, @NfceeTechnology Integer >
+     *         A HashMap where keys are activated secure elements and
+     *         the values are bitmap of technologies supported by each secure element
+     *         on success keys can contain "eSE" and "UICC", otherwise empty map.
      */
     @NonNull
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public List<String> getActiveNfceeList() {
+    public Map<String, Integer> getActiveNfceeList() {
         return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sService.fetchActiveNfceeList(), new ArrayList<String>());
+            NfcAdapter.sService.fetchActiveNfceeList(), new HashMap<String, Integer>());
     }
 
     /**
@@ -653,24 +747,45 @@
 
     /**
      * Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
-     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely
-     * use {@link #resumePolling()} to resume the polling.
-     * @param timeoutInMs the pause polling duration in millisecond, ranging from 0 to 40000.
+     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely.
+     * Use {@link #resumePolling()} to resume the polling.
+     * Use {@link #getMaxPausePollingTimeoutMs()} to check the max timeout value.
+     * @param timeoutInMs the pause polling duration in millisecond.
+     * @return status of the operation
+     * @throws IllegalArgumentException if timeoutInMs value is invalid
+     *         (0 < timeoutInMs < max).
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void pausePolling(@DurationMillisLong int timeoutInMs) {
-        NfcAdapter.callService(() -> NfcAdapter.sService.pausePolling(timeoutInMs));
+    public @PollingStateChangeStatusCode int pausePolling(@DurationMillisLong long timeoutInMs) {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sService.pausePolling(timeoutInMs),
+                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
     }
 
     /**
      * Resumes default NFC tag reader mode polling for the current device state if polling is
      * paused. Calling this while already in polling is a no-op.
+     * @return status of the operation
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void resumePolling() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.resumePolling());
+    public @PollingStateChangeStatusCode int resumePolling() {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sService.resumePolling(),
+                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
+    }
+
+    /**
+     * Gets the max pause polling timeout value in millisecond.
+     * @return long integer representing the max timeout
+     */
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @DurationMillisLong
+    public long getMaxPausePollingTimeoutMills() {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sService.getMaxPausePollingTimeoutMs(), 0L);
     }
 
     /**
diff --git a/nfc/java/android/nfc/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java
index 4e91377..c2cbbed 100644
--- a/nfc/java/android/nfc/NfcRoutingTableEntry.java
+++ b/nfc/java/android/nfc/NfcRoutingTableEntry.java
@@ -17,8 +17,12 @@
 
 
 import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Class to represent an entry of routing table. This class is abstract and extended by
  * {@link RoutingTableTechnologyEntry}, {@link RoutingTableProtocolEntry},
@@ -30,10 +34,42 @@
 @SystemApi
 public abstract class NfcRoutingTableEntry {
     private final int mNfceeId;
+    private final int mType;
+
+    /**
+     * AID routing table type.
+     */
+    public static final int TYPE_AID = 0;
+    /**
+     * Protocol routing table type.
+     */
+    public static final int TYPE_PROTOCOL = 1;
+    /**
+     * Technology routing table type.
+     */
+    public static final int TYPE_TECHNOLOGY = 2;
+    /**
+     * System Code routing table type.
+     */
+    public static final int TYPE_SYSTEM_CODE = 3;
+
+    /**
+     * Possible type of this routing table entry.
+     * @hide
+     */
+    @IntDef(prefix = "TYPE_", value = {
+            TYPE_AID,
+            TYPE_PROTOCOL,
+            TYPE_TECHNOLOGY,
+            TYPE_SYSTEM_CODE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RoutingTableType {}
 
     /** @hide */
-    protected NfcRoutingTableEntry(int nfceeId) {
+    protected NfcRoutingTableEntry(int nfceeId, @RoutingTableType int type) {
         mNfceeId = nfceeId;
+        mType = type;
     }
 
     /**
@@ -43,4 +79,13 @@
     public int getNfceeId() {
         return mNfceeId;
     }
+
+    /**
+     * Get the type of this entry.
+     * @return an integer defined in {@link RoutingTableType}
+     */
+    @RoutingTableType
+    public int getType() {
+        return mType;
+    }
 }
diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java
index 7634fe3..bf697d6 100644
--- a/nfc/java/android/nfc/RoutingTableAidEntry.java
+++ b/nfc/java/android/nfc/RoutingTableAidEntry.java
@@ -20,7 +20,7 @@
 import android.annotation.SystemApi;
 
 /**
- * Represents an AID entry in current routing table.
+ * Represents an Application ID (AID) entry in current routing table.
  * @hide
  */
 @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@@ -30,7 +30,7 @@
 
     /** @hide */
     public RoutingTableAidEntry(int nfceeId, String value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_AID);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
index 0c5be7d..536de4d 100644
--- a/nfc/java/android/nfc/RoutingTableProtocolEntry.java
+++ b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
@@ -97,7 +97,7 @@
 
     /** @hide */
     public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_PROTOCOL);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
index f87ad5f..f61892d 100644
--- a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
+++ b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
@@ -20,7 +20,9 @@
 import android.annotation.SystemApi;
 
 /**
- * Represents a system code entry in current routing table.
+ * Represents a system code entry in current routing table, where system codes are two-byte values
+ * used in NFC-F technology (a type of NFC communication) to identify specific
+ * device configurations.
  * @hide
  */
 @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@@ -30,7 +32,7 @@
 
     /** @hide */
     public RoutingTableSystemCodeEntry(int nfceeId, byte[] value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_SYSTEM_CODE);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
index f51a529..2dbc942 100644
--- a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
+++ b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
@@ -30,22 +30,27 @@
 @SystemApi
 public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry {
     /**
-     * Technology-A
+     * Technology-A.
+     * <p>Tech-A is mostly used for payment and ticketing applications. It supports various
+     * Tag platforms including Type 1, Type 2 and Type 4A tags. </p>
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_A = 0;
     /**
-     * Technology-B
+     * Technology-B which is based on ISO/IEC 14443-3 standard.
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_B = 1;
     /**
-     * Technology-F
+     * Technology-F.
+     * <p>Tech-F is a standard which supports Type 3 Tags and NFC-DEP protocol etc.</p>
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_F = 2;
     /**
-     * Technology-V
+     * Technology-V.
+     * <p>Tech-V is an NFC technology used for communication with passive tags that operate
+     * at a longer range than other NFC technologies. </p>
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_V = 3;
@@ -73,7 +78,7 @@
 
     /** @hide */
     public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_TECHNOLOGY);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/T4tNdefNfcee.java b/nfc/java/android/nfc/T4tNdefNfcee.java
new file mode 100644
index 0000000..06d02c5
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfcee.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.WorkerThread;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used for performing T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
+ * NFCEE (NFC Execution Environment) operations.
+ * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
+ * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
+ * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class T4tNdefNfcee {
+    private static final String TAG = "NdefNfcee";
+    static T4tNdefNfcee sNdefNfcee;
+
+    private T4tNdefNfcee() {
+    }
+
+    /**
+     * Helper to get an instance of this class.
+     *
+     * @return
+     * @hide
+     */
+    @NonNull
+    public static T4tNdefNfcee getInstance() {
+        if (sNdefNfcee == null) {
+            sNdefNfcee = new T4tNdefNfcee();
+        }
+        return sNdefNfcee;
+    }
+
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data is successful.
+     */
+    public static final int WRITE_DATA_SUCCESS = 0;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to unknown reasons.
+     */
+    public static final int WRITE_DATA_ERROR_INTERNAL = -1;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to ongoing rf activity.
+     */
+    public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to Nfc off.
+     */
+    public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to invalid file id.
+     */
+    public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to invalid length.
+     */
+    public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to core connection create failure.
+     */
+    public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to empty payload.
+     */
+    public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7;
+    /**
+     * Returns flag for {@link #writeData(int, byte[])}.
+     * It idicates write data fail due to invalid ndef format.
+     */
+    public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8;
+
+    /**
+     * Possible return values for {@link #writeData(int, byte[])}.
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "WRITE_DATA_" }, value = {
+        WRITE_DATA_SUCCESS,
+        WRITE_DATA_ERROR_INTERNAL,
+        WRITE_DATA_ERROR_RF_ACTIVATED,
+        WRITE_DATA_ERROR_NFC_NOT_ON,
+        WRITE_DATA_ERROR_INVALID_FILE_ID,
+        WRITE_DATA_ERROR_INVALID_LENGTH,
+        WRITE_DATA_ERROR_CONNECTION_FAILED,
+        WRITE_DATA_ERROR_EMPTY_PAYLOAD,
+        WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteDataStatus{}
+
+    /**
+     * This API performs writes of T4T data to NFCEE.
+     *
+     * <p>This is an I/O operation and will block until complete. It must
+     * not be called from the main application thread.</p>
+     *
+     * @param fileId File id (Refer NFC Forum Type 4 Tag Specification
+     *               Section 4.2 File Identifiers and Access Conditions
+     *               for more information) to which to write.
+     * @param data   This should be valid Ndef Message format.
+     *               Refer to Nfc forum NDEF specification NDEF Message section
+     * @return status of the operation.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public @WriteDataStatus int writeData(@IntRange(from = 0, to = 65535) int fileId,
+            @NonNull byte[] data) {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sNdefNfceeService.writeData(fileId, data), WRITE_DATA_ERROR_INTERNAL);
+    }
+
+    /**
+     * This API performs reading of T4T content of Nfcee.
+     *
+     * <p>This is an I/O operation and will block until complete. It must
+     * not be called from the main application thread.</p>
+     *
+     * @param fileId File Id (Refer
+     *               Section 4.2 File Identifiers and Access Conditions
+     *               for more information) from which to read.
+     * @return - Returns Ndef message if success
+     *           Refer to Nfc forum NDEF specification NDEF Message section
+     * @throws IllegalStateException if read fails because the fileId is invalid.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public byte[] readData(@IntRange(from = 0, to = 65535) int fileId) {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.readData(fileId), null);
+    }
+
+    /**
+     * Return flag for {@link #clearNdefData()}.
+     * It indicates clear data is successful.
+     */
+    public static final int CLEAR_DATA_SUCCESS = 1;
+     /**
+     * Return flag for {@link #clearNdefData()}.
+     * It indicates clear data failed due to internal error while processing the clear.
+     */
+    public static final int CLEAR_DATA_FAILED_INTERNAL = 0;
+
+    /**
+     * Possible return values for {@link #clearNdefData()}.
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "CLEAR_DATA_" }, value = {
+        CLEAR_DATA_SUCCESS,
+        CLEAR_DATA_FAILED_INTERNAL,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ClearDataStatus{}
+
+    /**
+     * This API will set all the T4T NDEF NFCEE data to zero.
+     *
+     * <p>This is an I/O operation and will block until complete. It must
+     * not be called from the main application thread.
+     *
+     * <p>This API can be called regardless of NDEF file lock state.
+     * </p>
+     * @return status of the operation
+     *
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public @ClearDataStatus int clearData() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.clearNdefData(), CLEAR_DATA_FAILED_INTERNAL);
+    }
+
+    /**
+     * Returns whether NDEF NFCEE operation is ongoing or not.
+     *
+     * @return true if NDEF NFCEE operation is ongoing, else false.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public boolean isOperationOngoing() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.isNdefOperationOngoing(), false);
+    }
+
+    /**
+     * This Api is to check the status of NDEF NFCEE emulation feature is
+     * supported or not.
+     *
+     * @return true if NDEF NFCEE emulation feature is supported, else false.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public boolean isSupported() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.isNdefNfceeEmulationSupported(), false);
+    }
+
+    /**
+     * This API performs reading of T4T NDEF NFCEE CC file content.
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+     *
+     * @return Returns CC file content if success or null if failed to read.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @Nullable
+    public T4tNdefNfceeCcFileInfo readCcfile() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.readCcfile(), null);
+    }
+}
diff --git a/core/java/android/content/pm/verify/pkg/VerificationSession.aidl b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
similarity index 87%
rename from core/java/android/content/pm/verify/pkg/VerificationSession.aidl
rename to nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
index ac85585..f72f74e 100644
--- a/core/java/android/content/pm/verify/pkg/VerificationSession.aidl
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.content.pm.verify.pkg;
+package android.nfc;
 
-/** @hide */
-parcelable VerificationSession;
+parcelable T4tNdefNfceeCcFileInfo;
+
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
new file mode 100644
index 0000000..5fca052
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used to represence T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
+ * NFCEE (NFC Execution Environment) CC (Capability Container) File data.
+ * The CC file stores metadata about the T4T tag being emulated.
+ *
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class T4tNdefNfceeCcFileInfo implements Parcelable {
+    /**
+     * Indicates the size of this capability container (called “CC File”)<p>
+     */
+    private int mCcLength;
+    /**
+     * Indicates the mapping specification version<p>
+     */
+    private int mVersion;
+    /**
+     * Indicates the max data size by a single ReadBinary<p>
+     */
+    private int mMaxReadLength;
+    /**
+     * Indicates the max data size by a single UpdateBinary<p>
+     */
+    private int mMaxWriteLength;
+    /**
+     * Indicates the NDEF File Identifier<p>
+     */
+    private int mFileId;
+    /**
+     * Indicates the maximum Max NDEF file size<p>
+     */
+    private int mMaxSize;
+    /**
+     * Indicates the read access condition<p>
+     */
+    private int mReadAccess;
+    /**
+     * Indicates the write access condition<p>
+     */
+    private int mWriteAccess;
+
+    /**
+     * Constructor to be used by NFC service and internal classes.
+     * @hide
+     */
+    public T4tNdefNfceeCcFileInfo(int cclen, int version, int maxLe, int maxLc,
+                      int ndefFileId, int ndefMaxSize,
+                      int ndefReadAccess, int ndefWriteAccess) {
+        mCcLength = cclen;
+        mVersion = version;
+        mMaxWriteLength = maxLc;
+        mMaxReadLength = maxLe;
+        mFileId = ndefFileId;
+        mMaxSize = ndefMaxSize;
+        mReadAccess = ndefReadAccess;
+        mWriteAccess = ndefWriteAccess;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+
+        dest.writeInt(mCcLength);
+        dest.writeInt(mVersion);
+        dest.writeInt(mMaxWriteLength);
+        dest.writeInt(mMaxReadLength);
+        dest.writeInt(mFileId);
+        dest.writeInt(mMaxSize);
+        dest.writeInt(mReadAccess);
+        dest.writeInt(mWriteAccess);
+    }
+
+    /**
+     * Indicates the size of this capability container (called “CC File”).
+     *
+     * @return length of the CC file.
+     */
+    @IntRange(from = 0xf, to = 0x7fff)
+    public int getCcFileLength() {
+        return mCcLength;
+    }
+
+    /**
+     * T4T tag mapping version 2.0.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+     */
+    public static final int VERSION_2_0 = 0x20;
+    /**
+     * T4T tag mapping version 2.0.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+     */
+    public static final int VERSION_3_0 = 0x30;
+
+    /**
+     * Possible return values for {@link #getVersion()}.
+     * @hide
+     */
+    @IntDef(prefix = { "VERSION_" }, value = {
+            VERSION_2_0,
+            VERSION_3_0,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Version{}
+
+    /**
+     * Indicates the mapping version of the T4T tag supported.
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.5" for more details.
+     *
+     * @return version of the specification
+     */
+    @Version
+    public int getVersion() {
+        return mVersion;
+    }
+
+    /**
+     * Indicates the max data size that can be read by a single invocation of
+     * {@link T4tNdefNfcee#readData(int)}.
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLe.
+     * @return max size of read (in bytes).
+     */
+    @IntRange(from = 0xf, to = 0xffff)
+    public int getMaxReadLength() {
+        return mMaxReadLength;
+    }
+
+    /**
+     * Indicates the max data size that can be written by a single invocation of
+     * {@link T4tNdefNfcee#writeData(int, byte[])}
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLc.
+     * @return max size of write (in bytes).
+     */
+    @IntRange(from = 0xd, to = 0xffff)
+    public int getMaxWriteLength() {
+        return mMaxWriteLength;
+    }
+
+    /**
+     * Indicates the NDEF File Identifier. This is the identifier used in the last invocation of
+     * {@link T4tNdefNfcee#writeData(int, byte[])}
+     *
+     * @return FileId of the data stored or -1 if no data is present.
+     */
+    @IntRange(from = -1, to = 65535)
+    public int getFileId() {
+        return mFileId;
+    }
+
+    /**
+     * Indicates the maximum size of T4T NDEF data that can be written to the NFCEE.
+     *
+     * @return max size of the contents.
+     */
+    @IntRange(from = 0x5, to = 0x7fff)
+    public int getMaxSize() {
+        return mMaxSize;
+    }
+
+    /**
+     * T4T tag read access granted without any security.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0x0;
+    /**
+     * T4T tag read access granted with limited proprietary access only.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int READ_ACCESS_GRANTED_RESTRICTED = 0x80;
+
+    /**
+     * Possible return values for {@link #getVersion()}.
+     * @hide
+     */
+    @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
+            READ_ACCESS_GRANTED_RESTRICTED,
+            READ_ACCESS_GRANTED_UNRESTRICTED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ReadAccess {}
+
+    /**
+     * Indicates the read access condition.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     * @return read access restriction
+     */
+    @ReadAccess
+    public int getReadAccess() {
+        return mReadAccess;
+    }
+
+    /**
+     * T4T tag write access granted without any security.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0x0;
+    /**
+     * T4T tag write access granted with limited proprietary access only.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 0x80;
+    /**
+     * T4T tag write access not granted.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int WRITE_ACCESS_NOT_GRANTED = 0xFF;
+
+    /**
+     * Possible return values for {@link #getVersion()}.
+     * @hide
+     */
+    @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
+            WRITE_ACCESS_GRANTED_RESTRICTED,
+            WRITE_ACCESS_GRANTED_UNRESTRICTED,
+            WRITE_ACCESS_NOT_GRANTED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteAccess {}
+
+    /**
+     * Indicates the write access condition.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     * @return write access restriction
+     */
+    @WriteAccess
+    public int getWriteAccess() {
+        return mWriteAccess;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Parcelable.Creator<T4tNdefNfceeCcFileInfo> CREATOR =
+            new Parcelable.Creator<>() {
+                @Override
+                public T4tNdefNfceeCcFileInfo createFromParcel(Parcel in) {
+
+                    // NdefNfceeCcFileInfo fields
+                    int cclen = in.readInt();
+                    int version = in.readInt();
+                    int maxLe = in.readInt();
+                    int maxLc = in.readInt();
+                    int ndefFileId = in.readInt();
+                    int ndefMaxSize = in.readInt();
+                    int ndefReadAccess = in.readInt();
+                    int ndefWriteAccess = in.readInt();
+
+                    return new T4tNdefNfceeCcFileInfo(cclen, version, maxLe, maxLc,
+                            ndefFileId, ndefMaxSize,
+                            ndefReadAccess, ndefWriteAccess);
+                }
+
+                @Override
+                public T4tNdefNfceeCcFileInfo[] newArray(int size) {
+                    return new T4tNdefNfceeCcFileInfo[size];
+                }
+            };
+}
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
index 9ff83fe..308b5d1 100644
--- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -171,6 +171,12 @@
     private boolean mShouldDefaultToObserveMode;
 
     /**
+     * Whether or not this service wants to share the same routing priority as the
+     * Wallet role owner.
+     */
+    private boolean mShareRolePriority;
+
+    /**
      * @hide
      */
     @UnsupportedAppUsage
@@ -307,6 +313,12 @@
                 mShouldDefaultToObserveMode = sa.getBoolean(
                         R.styleable.HostApduService_shouldDefaultToObserveMode,
                         false);
+                if (Flags.nfcAssociatedRoleServices()) {
+                    mShareRolePriority = sa.getBoolean(
+                            R.styleable.HostApduService_shareRolePriority,
+                            false
+                    );
+                }
                 sa.recycle();
             } else {
                 TypedArray sa = res.obtainAttributes(attrs,
@@ -337,6 +349,12 @@
                     }
                 }
                 mStaticOffHostName = mOffHostName;
+                if (Flags.nfcAssociatedRoleServices()) {
+                    mShareRolePriority = sa.getBoolean(
+                            R.styleable.OffHostApduService_shareRolePriority,
+                            false
+                    );
+                }
                 sa.recycle();
             }
 
@@ -728,6 +746,17 @@
     }
 
     /**
+     * Returns whether or not this service wants to share the Wallet role holder priority
+     * with other packages/services with the same signature.
+     *
+     * @return whether or not this service wants to share priority
+     */
+    @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
+    public boolean shareRolePriority() {
+        return mShareRolePriority;
+    }
+
+    /**
      * Returns description of service.
      * @return user readable description of service
      */
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index e9ec721..8037702 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -22,6 +22,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -45,6 +46,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.telephony.SubscriptionManager;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -244,6 +246,25 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface SetServiceEnabledStatusCode {}
 
+    /**
+     * Property name used to indicate that an application wants to allow associated services
+     * to share the same AID routing priority when this application is the role holder.
+     * <p>
+     * Example:
+     * <pre>
+     *     {@code
+     *     <application>
+     *       ...
+     *       <property android:name="android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY"
+     *         android:value="true"/>
+     *     </application>
+     *     }
+     * </pre>
+     */
+    @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
+    public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY =
+            "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
+
     static boolean sIsInitialized = false;
     static HashMap<Context, CardEmulation> sCardEmus = new HashMap<Context, CardEmulation>();
     static INfcCardEmulation sService;
@@ -947,7 +968,7 @@
      *
      * @param service The ComponentName of the service
      * @param status  true to enable, false to disable
-     * @return true if preferred service is successfully set or unset, otherwise return false.
+     * @return status code defined in {@link SetServiceEnabledStatusCode}
      *
      * @hide
      */
@@ -1010,6 +1031,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
     @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
     public void overrideRoutingTable(
             @NonNull Activity activity, @ProtocolAndTechnologyRoute int protocol,
@@ -1037,6 +1059,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
     @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
     public void recoverRoutingTable(@NonNull Activity activity) {
         if (!activity.isResumed()) {
@@ -1058,6 +1081,97 @@
     }
 
     /**
+     * Setting the default subscription ID succeeded.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0;
+
+    /**
+     * Setting the default subscription ID failed because the subscription ID is invalid.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1;
+
+    /**
+     * Setting the default subscription ID failed because there was an internal error processing
+     * the request. For ex: NFC service died in the middle of handling the API.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2;
+
+    /**
+     * Setting the default subscription ID failed because this feature is not supported on the
+     * device.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3;
+
+    /** @hide */
+    @IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_",
+            value = {
+                    SET_SUBSCRIPTION_ID_STATUS_SUCCESS,
+                    SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID,
+                    SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR,
+                    SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SetSubscriptionIdStatus {}
+
+    /**
+     * Sets the system's default NFC subscription id.
+     *
+     * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this sets the
+     * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+     *
+     * @param subscriptionId the default NFC subscription Id to set.
+     * @return status of the operation.
+     *
+     * @throws UnsupportedOperationException If the device does not have
+     * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public @SetSubscriptionIdStatus int setDefaultNfcSubscriptionId(int subscriptionId) {
+        return callServiceReturn(() ->
+                        sService.setDefaultNfcSubscriptionId(
+                                subscriptionId, mContext.getPackageName()),
+                SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR);
+    }
+
+    /**
+     * Returns the system's default NFC subscription id.
+     *
+     * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this returns the
+     * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+     * <p> If the device has no UICC that can serve as NFCEE, this will return
+     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.</p>
+     *
+     * @return the default NFC subscription Id if set,
+     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} otherwise.
+     *
+     * @throws UnsupportedOperationException If the device does not have
+     * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
+     */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public int getDefaultNfcSubscriptionId() {
+        return callServiceReturn(() ->
+                sService.getDefaultNfcSubscriptionId(mContext.getPackageName()),
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+    }
+
+    /**
      * Returns the value of {@link Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT}.
      *
      * @param context A context
diff --git a/nfc/tests/src/android/nfc/NdefMessageTest.java b/nfc/tests/src/android/nfc/NdefMessageTest.java
new file mode 100644
index 0000000..9ca295d
--- /dev/null
+++ b/nfc/tests/src/android/nfc/NdefMessageTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class NdefMessageTest {
+    private NdefMessage mNdefMessage;
+    private NdefRecord mNdefRecord;
+
+    @Before
+    public void setUp() {
+        mNdefRecord = NdefRecord.createUri("http://www.example.com");
+        mNdefMessage = new NdefMessage(mNdefRecord);
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void testGetRecords() {
+        NdefRecord[] records = mNdefMessage.getRecords();
+        assertThat(records).isNotNull();
+        assertThat(records).hasLength(1);
+        assertThat(records[0]).isEqualTo(mNdefRecord);
+    }
+
+    @Test
+    public void testToByteArray() throws FormatException {
+        byte[] bytes = mNdefMessage.toByteArray();
+        assertThat(bytes).isNotNull();
+        assertThat(bytes.length).isGreaterThan(0);
+        NdefMessage ndefMessage = new NdefMessage(bytes);
+        assertThat(ndefMessage).isNotNull();
+    }
+}
diff --git a/packages/BackupRestoreConfirmation/Android.bp b/packages/BackupRestoreConfirmation/Android.bp
index ad3f4c1..a7d16a1 100644
--- a/packages/BackupRestoreConfirmation/Android.bp
+++ b/packages/BackupRestoreConfirmation/Android.bp
@@ -27,6 +27,7 @@
     name: "BackupRestoreConfirmation",
     defaults: ["platform_app_defaults"],
     srcs: ["src/**/*.java"],
+    static_libs: ["androidx.core_core"],
     platform_apis: true,
     certificate: "platform",
     privileged: true,
diff --git a/packages/BackupRestoreConfirmation/AndroidManifest.xml b/packages/BackupRestoreConfirmation/AndroidManifest.xml
index 44aa1b1..fee4657 100644
--- a/packages/BackupRestoreConfirmation/AndroidManifest.xml
+++ b/packages/BackupRestoreConfirmation/AndroidManifest.xml
@@ -27,7 +27,6 @@
                  android:permission="android.permission.CONFIRM_FULL_BACKUP" >
 
         <activity android:name=".BackupRestoreConfirmation"
-                  android:theme="@style/OptOutEdgeToEdgeEnforcement"
                   android:title=""
                   android:windowSoftInputMode="stateAlwaysHidden"
                   android:excludeFromRecents="true"
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
index 6504435..16e4706 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
@@ -24,6 +24,7 @@
               android:orientation="vertical" >
 
     <ScrollView
+            android:id="@+id/scroll_view"
             android:layout_height="0dp"
             android:layout_weight="1"
             android:layout_width="match_parent"
@@ -84,11 +85,11 @@
           android:layout_width="match_parent" />
 
     <!-- button bar -->
-    <LinearLayout android:orientation="horizontal"
-                  style="?android:attr/buttonBarStyle"                 
+    <LinearLayout android:id="@+id/button_bar"
+                  android:orientation="horizontal"
+                  style="?android:attr/buttonBarStyle"
                   android:layout_height="wrap_content"
-                  android:layout_width="match_parent"
-                  android:layout_gravity="bottom">
+                  android:layout_width="match_parent">
 
     <Button android:id="@+id/button_deny"
             style="?android:attr/buttonBarButtonStyle"
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
index 2ee74fe..55efe4a 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
@@ -23,11 +23,13 @@
               android:layout_height="match_parent"
               android:orientation="vertical">
 
-    <ScrollView 
+    <ScrollView
+            android:id="@+id/scroll_view"
             android:padding="16dp"
             android:layout_height="0dp"
             android:layout_weight="1"
-            android:layout_width="match_parent">
+            android:layout_width="match_parent"
+            android:clipToPadding="false" >
         <LinearLayout
                 android:orientation="vertical"
                 android:layout_height="wrap_content"
@@ -82,8 +84,9 @@
           android:layout_width="match_parent" />
 
     <!-- button bar -->
-    <LinearLayout android:orientation="horizontal"
-                  style="?android:attr/buttonBarStyle"                 
+    <LinearLayout android:id="@+id/button_bar"
+                  android:orientation="horizontal"
+                  style="?android:attr/buttonBarStyle"
                   android:layout_height="wrap_content"
                   android:layout_width="match_parent"
                   android:layout_gravity="bottom">
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index 3c790f0..bc06bdb 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -31,10 +31,17 @@
 import android.text.TextWatcher;
 import android.util.Slog;
 import android.view.View;
+import android.view.ViewGroup.MarginLayoutParams;
 import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
 /**
  * Confirm with the user that a requested full backup/restore operation is legitimate.
  * Any attempt to perform a full backup/restore will launch this UI and wait for a
@@ -208,6 +215,8 @@
         setTitle(titleId);
         setContentView(layoutId);
 
+        handleInsets();
+
         // Same resource IDs for each layout variant (backup / restore)
         mStatusView = findViewById(R.id.package_name);
         mAllowButton = findViewById(R.id.button_allow);
@@ -254,6 +263,31 @@
         }
     }
 
+    // Handle insets so that UI components are not covered by navigation and status bars
+    private void handleInsets() {
+        LinearLayout buttonBar = findViewById(R.id.button_bar);
+        ViewCompat.setOnApplyWindowInsetsListener(buttonBar, (v, windowInsets) -> {
+            Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
+            MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
+            mlp.leftMargin = insets.left;
+            mlp.bottomMargin = insets.bottom;
+            mlp.rightMargin = insets.right;
+            v.setLayoutParams(mlp);
+            return WindowInsetsCompat.CONSUMED;
+        });
+
+        ScrollView scrollView = findViewById(R.id.scroll_view);
+        ViewCompat.setOnApplyWindowInsetsListener(scrollView, (v, windowInsets) -> {
+            Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
+            MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
+            mlp.leftMargin = insets.left;
+            mlp.topMargin = insets.top;
+            mlp.rightMargin = insets.right;
+            v.setLayoutParams(mlp);
+            return WindowInsetsCompat.CONSUMED;
+        });
+    }
+
     private void monitorEncryptionPassword() {
         mAllowButton.setEnabled(false);
         mEncPassword.addTextChangedListener(new TextWatcher() {
diff --git a/packages/CarrierDefaultApp/res/values-ar/strings.xml b/packages/CarrierDefaultApp/res/values-ar/strings.xml
index 53a2733..fe746f2 100644
--- a/packages/CarrierDefaultApp/res/values-ar/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ar/strings.xml
@@ -8,7 +8,7 @@
     <string name="portal_notification_detail" msgid="2295729385924660881">"‏النقر للانتقال إلى موقع %s الإلكتروني"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"‏يُرجى الاتصال بمقدم الخدمة %s"</string>
     <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"لا يوجد اتصال بيانات الجوال"</string>
-    <string name="no_mobile_data_connection" msgid="544980465184147010">"‏إضافة بيانات أو خطة تجوال خلال %%s"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"‏إضافة بيانات أو خطة تجوال خلال %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"حالة بيانات الجوّال"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"تسجيل الدخول إلى شبكة الجوّال"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"الشبكة التي تحاول الانضمام إليها بها مشاكل أمنية."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ur/strings.xml b/packages/CarrierDefaultApp/res/values-ur/strings.xml
index 20d1300..d6225c2 100644
--- a/packages/CarrierDefaultApp/res/values-ur/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ur/strings.xml
@@ -16,7 +16,7 @@
     <string name="ssl_error_continue" msgid="1138548463994095584">"براؤزر کے ذریعے بہرحال جاری رکھیں"</string>
     <string name="performance_boost_notification_channel" msgid="3475440855635538592">"پرفارمینس بوسٹ"</string>
     <string name="performance_boost_notification_title" msgid="3126203390685781861">"‏آپ کے کیریئر سے 5G کے اختیارات"</string>
-    <string name="performance_boost_notification_detail" msgid="216569851036236346">"‏اپنی ایپ کے تجربے کے اختیارات دیکھنے کے لیے %%s کی ویب سائٹ ملاحظہ کریں"</string>
+    <string name="performance_boost_notification_detail" msgid="216569851036236346">"‏اپنی ایپ کے تجربے کے اختیارات دیکھنے کے لیے %s کی ویب سائٹ ملاحظہ کریں"</string>
     <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ابھی نہیں"</string>
     <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"نظم کریں"</string>
     <string name="slice_purchase_app_label" msgid="7170191659233241166">"پرفارمینس بوسٹ خریدیں۔"</string>
diff --git a/packages/CrashRecovery/framework/Android.bp b/packages/CrashRecovery/framework/Android.bp
index 2beffda..43d8a62 100644
--- a/packages/CrashRecovery/framework/Android.bp
+++ b/packages/CrashRecovery/framework/Android.bp
@@ -14,6 +14,7 @@
     name: "framework-platformcrashrecovery",
     srcs: [":framework-crashrecovery-sources"],
     defaults: ["framework-non-updatable-unbundled-defaults"],
+    permitted_packages: ["android.service.watchdog"],
     aidl: {
         include_dirs: [
             "frameworks/base/core/java",
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 8c15b09..2ba93f1 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
@@ -456,7 +456,7 @@
      *
      * <p>This method could be called frequently if there is a severe problem on the device.
      */
-    public void onPackageFailure(@NonNull List<VersionedPackage> packages,
+    public void notifyPackageFailure(@NonNull List<VersionedPackage> packages,
             @FailureReasons int failureReason) {
         if (packages == null) {
             Slog.w(TAG, "Could not resolve a list of failing packages");
@@ -467,7 +467,7 @@
             if (Flags.recoverabilityDetection()) {
                 if (now >= mLastMitigation
                         && (now - mLastMitigation) < getMitigationWindowMs()) {
-                    Slog.i(TAG, "Skipping onPackageFailure mitigation");
+                    Slog.i(TAG, "Skipping notifyPackageFailure mitigation");
                     return;
                 }
             }
@@ -494,7 +494,7 @@
                             ObserverInternal observer = mAllObservers.valueAt(oIndex);
                             PackageHealthObserver registeredObserver = observer.registeredObserver;
                             if (registeredObserver != null
-                                    && observer.onPackageFailureLocked(
+                                    && observer.notifyPackageFailureLocked(
                                     versionedPackage.getPackageName())) {
                                 MonitoredPackage p = observer.getMonitoredPackage(
                                         versionedPackage.getPackageName());
@@ -693,7 +693,7 @@
         // Check if native watchdog reported a crash
         if ("1".equals(SystemProperties.get("sys.init.updatable_crashing"))) {
             // We rollback all available low impact rollbacks when crash is unattributable
-            onPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
+            notifyPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
             // we stop polling after an attempt to execute rollback, regardless of whether the
             // attempt succeeds or not
         } else {
@@ -731,6 +731,25 @@
     }
 
     /**
+     * The minimum value that can be returned by any observer.
+     * It represents that no mitigations were available.
+     */
+    public static final int LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT =
+            PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
+
+    /**
+     * The mitigation impact beyond which the user will start noticing the mitigations.
+     */
+    public static final int MEDIUM_USER_IMPACT_THRESHOLD =
+            PackageHealthObserverImpact.USER_IMPACT_LEVEL_20;
+
+    /**
+     * The mitigation impact beyond which the user impact is severely high.
+     */
+    public static final int HIGH_USER_IMPACT_THRESHOLD =
+            PackageHealthObserverImpact.USER_IMPACT_LEVEL_71;
+
+    /**
      * Possible severity values of the user impact of a
      * {@link PackageHealthObserver#onExecuteHealthCheckMitigation}.
      * @hide
@@ -773,6 +792,11 @@
         /**
          * Called when health check fails for the {@code versionedPackage}.
          *
+         * Note: if the returned user impact is higher than
+         * {@link #DEFAULT_HIGH_USER_IMPACT_THRESHOLD}, then
+         * {@link #onExecuteHealthCheckMitigation} would be called only in severe device conditions
+         * like boot-loop or network failure.
+         *
          * @param versionedPackage the package that is failing. This may be null if a native
          *                          service is crashing.
          * @param failureReason   the type of failure that is occurring.
@@ -780,8 +804,8 @@
          *                        (including this time).
          *
          *
-         * @return any one of {@link PackageHealthObserverImpact} to express the impact
-         * to the user on {@link #onExecuteHealthCheckMitigation}
+         * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
+         * the impact of mitigation on the user in {@link #onExecuteHealthCheckMitigation}
          */
         @PackageHealthObserverImpact int onHealthCheckFailed(
                 @Nullable VersionedPackage versionedPackage,
@@ -790,9 +814,8 @@
 
         /**
          * This would be called after {@link #onHealthCheckFailed}.
-         * This is called only if current observer returned least
-         * {@link PackageHealthObserverImpact} mitigation for failed health
-         * check.
+         * This is called only if current observer returned least impact mitigation for failed
+         * health check.
          *
          * @param versionedPackage the package that is failing. This may be null if a native
          *                          service is crashing.
@@ -811,6 +834,9 @@
          *
          * @param mitigationCount the number of times mitigation has been attempted for this
          *                        boot loop (including this time).
+         *
+         * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
+         * the impact of mitigation on the user in {@link #onExecuteBootLoopMitigation}
          */
         default @PackageHealthObserverImpact int onBootLoop(int mitigationCount) {
             return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
@@ -818,11 +844,13 @@
 
         /**
          * This would be called after {@link #onBootLoop}.
-         * This is called only if current observer returned least
-         * {@link PackageHealthObserverImpact} mitigation for fixing boot loop
+         * This is called only if current observer returned least impact mitigation for fixing
+         * boot loop.
          *
          * @param mitigationCount the number of times mitigation has been attempted for this
          *                        boot loop (including this time).
+         *
+         * @return {@code true} if action was executed successfully, {@code false} otherwise
          */
         default boolean onExecuteBootLoopMitigation(int mitigationCount) {
             return false;
@@ -916,7 +944,7 @@
      * effectively behave as if the explicit health check hasn't passed for {@code packageName}.
      *
      * <p> {@code packageName} can still be considered failed if reported by
-     * {@link #onPackageFailureLocked} before the package expires.
+     * {@link #notifyPackageFailureLocked} before the package expires.
      *
      * <p> Triggered by components outside the system server when they are fully functional after an
      * update.
@@ -1317,7 +1345,6 @@
      * Check if we're currently attempting to reboot during mitigation. This method must return
      * true if triggered reboot early during a boot loop, since the device will not be fully booted
      * at this time.
-     * @hide
      */
     public static boolean isRecoveryTriggeredReboot() {
         return isFactoryResetPropertySet() || isRebootPropertySet();
@@ -1461,7 +1488,7 @@
          * @hide
          */
         @GuardedBy("sLock")
-        public boolean onPackageFailureLocked(String packageName) {
+        public boolean notifyPackageFailureLocked(String packageName) {
             if (getMonitoredPackage(packageName) == null && registeredObserver.isPersistent()
                     && registeredObserver.mayObservePackage(packageName)) {
                 putMonitoredPackage(sPackageWatchdog.newMonitoredPackage(
diff --git a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
index 129e47f..88fe36c 100644
--- a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
@@ -477,7 +477,7 @@
      *
      * <p>This method could be called frequently if there is a severe problem on the device.
      */
-    public void onPackageFailure(@NonNull List<VersionedPackage> packages,
+    public void notifyPackageFailure(@NonNull List<VersionedPackage> packages,
             @FailureReasons int failureReason) {
         if (packages == null) {
             Slog.w(TAG, "Could not resolve a list of failing packages");
@@ -488,7 +488,7 @@
             if (Flags.recoverabilityDetection()) {
                 if (now >= mLastMitigation
                         && (now - mLastMitigation) < getMitigationWindowMs()) {
-                    Slog.i(TAG, "Skipping onPackageFailure mitigation");
+                    Slog.i(TAG, "Skipping notifyPackageFailure mitigation");
                     return;
                 }
             }
@@ -515,7 +515,7 @@
                             ObserverInternal observer = mAllObservers.valueAt(oIndex);
                             PackageHealthObserver registeredObserver = observer.registeredObserver;
                             if (registeredObserver != null
-                                    && observer.onPackageFailureLocked(
+                                    && observer.notifyPackageFailureLocked(
                                     versionedPackage.getPackageName())) {
                                 MonitoredPackage p = observer.getMonitoredPackage(
                                         versionedPackage.getPackageName());
@@ -714,7 +714,7 @@
         // Check if native watchdog reported a crash
         if ("1".equals(SystemProperties.get("sys.init.updatable_crashing"))) {
             // We rollback all available low impact rollbacks when crash is unattributable
-            onPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
+            notifyPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
             // we stop polling after an attempt to execute rollback, regardless of whether the
             // attempt succeeds or not
         } else {
@@ -926,7 +926,7 @@
      * effectively behave as if the explicit health check hasn't passed for {@code packageName}.
      *
      * <p> {@code packageName} can still be considered failed if reported by
-     * {@link #onPackageFailureLocked} before the package expires.
+     * {@link #notifyPackageFailureLocked} before the package expires.
      *
      * <p> Triggered by components outside the system server when they are fully functional after an
      * update.
@@ -1253,7 +1253,7 @@
                         return;
                     }
                     final List<VersionedPackage> pkgList = Collections.singletonList(pkg);
-                    onPackageFailure(pkgList, FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
+                    notifyPackageFailure(pkgList, FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
                 });
     }
 
@@ -1467,7 +1467,7 @@
          * @hide
          */
         @GuardedBy("mLock")
-        public boolean onPackageFailureLocked(String packageName) {
+        public boolean notifyPackageFailureLocked(String packageName) {
             if (getMonitoredPackage(packageName) == null && registeredObserver.isPersistent()
                     && registeredObserver.mayObservePackage(packageName)) {
                 putMonitoredPackage(sPackageWatchdog.newMonitoredPackage(
diff --git a/packages/NeuralNetworks/OWNERS b/packages/NeuralNetworks/OWNERS
new file mode 100644
index 0000000..6b39150
--- /dev/null
+++ b/packages/NeuralNetworks/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 195575
+
+sandeepbandaru@google.com
+shivanker@google.com
+shiqing@google.com
\ No newline at end of file
diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml
index 5147c52..ca0ca9c 100644
--- a/packages/PackageInstaller/res/values-cs/strings.xml
+++ b/packages/PackageInstaller/res/values-cs/strings.xml
@@ -21,7 +21,7 @@
     <string name="update" msgid="3932142540719227615">"Aktualizovat"</string>
     <string name="done" msgid="6632441120016885253">"Hotovo"</string>
     <string name="cancel" msgid="1018267193425558088">"Zrušit"</string>
-    <string name="installing" msgid="4921993079741206516">"Instalace…"</string>
+    <string name="installing" msgid="4921993079741206516">"Probíhá instalace…"</string>
     <string name="installing_app" msgid="1165095864863849422">"Instalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="install_done" msgid="5987363587661783896">"Aplikace je nainstalována."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Chcete tuto aplikaci nainstalovat?"</string>
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 00342082..f97b758 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -65,6 +65,7 @@
             android:configChanges="mnc|mnc|touchscreen|navigation|screenLayout|screenSize|smallestScreenSize|orientation|locale|keyboard|keyboardHidden|fontScale|uiMode|layoutDirection|density"
             android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE"
             android:theme="@style/Theme.PrintActivity"
+            android:enableOnBackInvokedCallback="true"
             android:exported="true">
             <intent-filter>
                 <action android:name="android.print.PRINT_DIALOG" />
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index bd2b5ec..4a3a6d2 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -84,6 +84,7 @@
 import android.widget.Spinner;
 import android.widget.TextView;
 import android.widget.Toast;
+import android.window.OnBackInvokedDispatcher;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -323,6 +324,8 @@
                 });
 
         getLoaderManager().initLoader(LOADER_ID_ENABLED_PRINT_SERVICES, null, this);
+        getWindow().getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+                OnBackInvokedDispatcher.PRIORITY_DEFAULT, this::onBackInvoked);
     }
 
     private void onConnectedToPrintSpooler(final IBinder documentAdapter) {
@@ -481,17 +484,21 @@
 
         if ((keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE)
                 && event.isTracking() && !event.isCanceled()) {
-            if (mPrintPreviewController != null && mPrintPreviewController.isOptionsOpened()
-                    && !hasErrors()) {
-                mPrintPreviewController.closeOptions();
-            } else {
-                cancelPrint();
-            }
+            onBackInvoked();
             return true;
         }
         return super.onKeyUp(keyCode, event);
     }
 
+    private void onBackInvoked() {
+        if (mPrintPreviewController != null && mPrintPreviewController.isOptionsOpened()
+                && !hasErrors()) {
+            mPrintPreviewController.closeOptions();
+        } else {
+            cancelPrint();
+        }
+    }
+
     @Override
     public void onRequestContentUpdate() {
         if (canUpdateDocument()) {
diff --git a/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml
new file mode 100644
index 0000000..38cae30
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Kies \'n prent"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Neem \'n foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Verstekgebruikerikoon"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml
new file mode 100644
index 0000000..917a2fd
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"ምስል ይምረጡ"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ፎቶ ያንሱ"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ነባሪ የተጠቃሚ አዶ"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml
new file mode 100644
index 0000000..8e5231b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"اختيار صورة"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"التقاط صورة"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"رمز المستخدم التلقائي"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml
new file mode 100644
index 0000000..c77b573
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"এখন ফট’ তোলক"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ডিফ’ল্ট ব্যৱহাৰকাৰীৰ চিহ্ন"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml
new file mode 100644
index 0000000..6871473
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Şəkil seçin"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Foto çəkin"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Defolt istifadəçi ikonası"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..42fb478
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Odaberite sliku"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Slikajte"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Podrazumevana ikona korisnika"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml
new file mode 100644
index 0000000..c2ef4db
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Выбраць відарыс"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Зрабіць фота"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Стандартны карыстальніцкі значок"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml
new file mode 100644
index 0000000..eeca7d8
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Избиране на изображение"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Правене на снимка"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Икона за основния потребител"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml
new file mode 100644
index 0000000..6d4d29f
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"একটি ছবি বেছে নিন"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ফটো তুলুন"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ডিফল্ট ব্যবহারকারীর আইকন"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml
new file mode 100644
index 0000000..def1b45
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Odaberite sliku"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Snimite fotografiju"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Zadana ikona korisnika"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml
new file mode 100644
index 0000000..1b613ca
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Tria una imatge"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Fes una foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Icona d\'usuari predeterminat"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml
new file mode 100644
index 0000000..ffe2f47
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Zvolit obrázek"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Vyfotit"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Výchozí uživatelská ikona"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml
new file mode 100644
index 0000000..ab01eef
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Vælg et billede"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Tag et billede"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ikon for standardbruger"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml
new file mode 100644
index 0000000..4d6c651a
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Bild auswählen"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Foto aufnehmen"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Standardmäßiges Nutzersymbol"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml
new file mode 100644
index 0000000..9e6813f
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Επιλέξτε μια εικόνα"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Λήψη φωτογραφίας"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Προεπιλεγμένο εικονίδιο χρήστη"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..d0aae79
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rCA/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..f9905d0
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rCA/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"Choose a profile picture"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
+    <string name="done" msgid="3587741621903511576">"Done"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..d0aae79
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..d0aae79
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..296dcc8
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Elegir una imagen"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Tomar una foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ícono de usuario predeterminado"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml
new file mode 100644
index 0000000..5d4a8d2
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Seleccionar una imagen"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Hacer una foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Icono de usuario predeterminado"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml
new file mode 100644
index 0000000..ecd3a83
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Vali pilt"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Pildista"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Vaikekasutajaikoon"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml
new file mode 100644
index 0000000..e29bc11
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Aukeratu irudi bat"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Atera argazki bat"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Erabiltzaile lehenetsiaren ikonoa"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml
new file mode 100644
index 0000000..25efac4
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"انتخاب تصویر"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"عکس گرفتن"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"نماد کاربر پیش‌فرض"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml
new file mode 100644
index 0000000..4d805ed
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Valitse kuva"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Ota kuva"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Oletuskäyttäjäkuvake"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..fb32c5b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Sélectionner une image"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Prendre une photo"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Icône d\'utilisateur par défaut"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml
new file mode 100644
index 0000000..79620e9
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Choisir une image"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Prendre une photo"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Icône de l\'utilisateur par défaut"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml
new file mode 100644
index 0000000..bbfa18b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Escoller unha imaxe"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Tirar unha foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Icona do usuario predeterminado"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml
new file mode 100644
index 0000000..247afe1
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"છબી પસંદ કરો"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ફોટો લો"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ડિફૉલ્ટ વપરાશકર્તાનું આઇકન"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml
new file mode 100644
index 0000000..3c51576
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"इमेज चुनें"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"फ़ोटो खींचें"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"उपयोगकर्ता के लिए डिफ़ॉल्ट आइकॉन"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml
new file mode 100644
index 0000000..e9a56bd
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Odaberite sliku"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Snimi fotografiju"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ikona zadanog korisnika"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml
new file mode 100644
index 0000000..f3d53cd
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Kép kiválasztása"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Fotó készítése"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Alapértelmezett felhasználó ikonja"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hy/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hy/strings.xml
new file mode 100644
index 0000000..d897cd2
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-hy/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Ընտրել պատկեր"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Լուսանկարել"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"Ընտրեք պրոֆիլի նկար"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Օգտատիրոջ կանխադրված պատկերակ"</string>
+    <string name="done" msgid="3587741621903511576">"Պատրաստ է"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml
new file mode 100644
index 0000000..bfa0d93
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Pilih gambar"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Ambil foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ikon pengguna default"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml
new file mode 100644
index 0000000..d496524
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Velja mynd"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Taka mynd"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Tákn sjálfgefins notanda"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml
new file mode 100644
index 0000000..3ba0a01
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Scegli un\'immagine"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Scatta una foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Icona dell\'utente predefinito"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml
new file mode 100644
index 0000000..903989d
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"לבחירת תמונה"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"צילום תמונה"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"סמל המשתמש שמוגדר כברירת מחדל"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ja/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ja/strings.xml
new file mode 100644
index 0000000..15a4cdc
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ja/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"画像を選択"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"写真を撮る"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"プロフィール写真の選択"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"デフォルト ユーザー アイコン"</string>
+    <string name="done" msgid="3587741621903511576">"完了"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml
new file mode 100644
index 0000000..817180b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"სურათის არჩევა"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ფოტოს გადაღება"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"მომხმარებლის ნაგულისხმევი ხატულა"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml
new file mode 100644
index 0000000..ec01801
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Кескін таңдау"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Суретке түсіру"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Әдепкі пайдаланушы белгішесі"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml
new file mode 100644
index 0000000..7a31122
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"ជ្រើសរើស​រូបភាព"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ថតរូប"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"រូបអ្នកប្រើប្រាស់លំនាំដើម"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-kn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-kn/strings.xml
new file mode 100644
index 0000000..67f8899
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-kn/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"ಚಿತ್ರವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ಫೋಟೋವನ್ನು ಸೆರೆಹಿಡಿಯಿರಿ"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"ಪ್ರೊಫೈಲ್‌ ಚಿತ್ರವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ಡೀಫಾಲ್ಟ್ ಬಳಕೆದಾರರ ಐಕಾನ್"</string>
+    <string name="done" msgid="3587741621903511576">"ಮುಗಿದಿದೆ"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml
new file mode 100644
index 0000000..45bfb53
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"이미지 선택"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"사진 찍기"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"기본 사용자 아이콘"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml
new file mode 100644
index 0000000..b3d39de
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Сүрөт тандоо"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Сүрөткө тартуу"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Демейки колдонуучунун сүрөтчөсү"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml
new file mode 100644
index 0000000..3ba6709
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"ເລືອກຮູບ"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ຖ່າຍຮູບ"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ໄອຄອນຜູ້ໃຊ້ເລີ່ມຕົ້ນ"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml
new file mode 100644
index 0000000..b0c0c39
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Pasirinkti vaizdą"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Fotografuoti"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Numatytojo naudotojo piktograma"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml
new file mode 100644
index 0000000..e664c80
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Izvēlēties attēlu"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Uzņemt fotoattēlu"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Noklusējuma lietotāja ikona"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml
new file mode 100644
index 0000000..bb0e247
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Изберете слика"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Фотографирај"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Икона за стандарден корисник"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml
new file mode 100644
index 0000000..674b4f5
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ഡിഫോൾട്ട് ഉപയോക്തൃ ഐക്കൺ"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml
new file mode 100644
index 0000000..61553b5
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Зураг сонгох"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Зураг авах"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Өгөгдмөл хэрэглэгчийн дүрс тэмдэг"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-mr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-mr/strings.xml
new file mode 100644
index 0000000..acc2c46
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-mr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"इमेज निवडा"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"फोटो काढा"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"प्रोफाइल फोटो निवडा"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"डीफॉल्ट वापरकर्ता आयकन"</string>
+    <string name="done" msgid="3587741621903511576">"पूर्ण झाले"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml
new file mode 100644
index 0000000..2599696
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Pilih imej"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Ambil foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ikon pengguna lalai"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml
new file mode 100644
index 0000000..f9f697b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"ပုံရွေးရန်"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ဓာတ်ပုံရိုက်ရန်"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"မူရင်းအသုံးပြုသူ သင်္ကေတ"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml
new file mode 100644
index 0000000..c1b7631
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Velg et bilde"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Ta et bilde"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Standard brukerikon"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml
new file mode 100644
index 0000000..a8c02b9
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"कुनै फोटो छनौट गर्नुहोस्"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"फोटो खिच्नुहोस्"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"प्रयोगकर्ताको डिफल्ट आइकन"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml
new file mode 100644
index 0000000..47352bc
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Een afbeelding kiezen"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Een foto maken"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Standaard gebruikersicoon"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml
new file mode 100644
index 0000000..132b97a
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"ଗୋଟିଏ ଛବି ବାଛନ୍ତୁ"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ଗୋଟିଏ ଫଟୋ ଉଠାନ୍ତୁ"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ଡିଫଲ୍ଟ ୟୁଜର ଆଇକନ"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pa/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pa/strings.xml
new file mode 100644
index 0000000..a336226
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pa/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"ਚਿੱਤਰ ਚੁਣੋ"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ਫ਼ੋਟੋ ਖਿੱਚੋ"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"ਕੋਈ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਚੁਣੋ"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਵਰਤੋਂਕਾਰ ਪ੍ਰਤੀਕ"</string>
+    <string name="done" msgid="3587741621903511576">"ਹੋ ਗਿਆ"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml
new file mode 100644
index 0000000..7db7904
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Wybierz obraz"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Zrób zdjęcie"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ikona domyślnego użytkownika"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..ae3e6e5
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Escolher uma imagem"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Tirar uma foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ícone de usuário padrão"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pt-rPT/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..18f36c3
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pt-rPT/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Escolher uma imagem"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Tirar uma foto"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"Escolha uma imagem do perfil"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ícone do utilizador predefinido"</string>
+    <string name="done" msgid="3587741621903511576">"Concluído"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml
new file mode 100644
index 0000000..ae3e6e5
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Escolher uma imagem"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Tirar uma foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ícone de usuário padrão"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml
new file mode 100644
index 0000000..ce662d4
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Alege o imagine"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Fă o fotografie"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Pictograma prestabilită a utilizatorului"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml
new file mode 100644
index 0000000..47f8a83
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Выбрать фото"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Сделать снимок"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Значок пользователя по умолчанию"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml
new file mode 100644
index 0000000..aaba442
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"රූපයක් තෝරන්න"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ඡායාරූපයක් ගන්න"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"පෙරනිමි පරිශීලක නිරූපකය"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml
new file mode 100644
index 0000000..3f801a3
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Vybrať obrázok"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Odfotiť"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Predvolená ikona používateľa"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sl/strings.xml
new file mode 100644
index 0000000..7d0bf10
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Izbira slike"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Fotografiranje"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"Izbira profilne slike"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Privzeta ikona uporabnika"</string>
+    <string name="done" msgid="3587741621903511576">"Končano"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml
new file mode 100644
index 0000000..0b8a58d
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Zgjidh një imazh"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Bëj një fotografi"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ikona e parazgjedhur e përdoruesit"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml
new file mode 100644
index 0000000..1014df4
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Одаберите слику"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Сликајте"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Подразумевана икона корисника"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml
new file mode 100644
index 0000000..8203409
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Välj en bild"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Ta ett foto"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Ikon för standardanvändare"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml
new file mode 100644
index 0000000..b0e8c44
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Chagua picha"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Piga picha"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Aikoni chaguomsingi ya mtumiaji"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ta/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ta/strings.xml
new file mode 100644
index 0000000..13c7b5b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ta/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"படத்தைத் தேர்வுசெய்க"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"படமெடு"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"சுயவிவரப் படத்தைத் தேர்வுசெய்யுங்கள்"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"இயல்புநிலைப் பயனர் ஐகான்"</string>
+    <string name="done" msgid="3587741621903511576">"முடிந்தது"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-te/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-te/strings.xml
new file mode 100644
index 0000000..b731848
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-te/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"చిత్రాన్ని ఎంచుకోండి"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ఫోటోను తీయి"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"ప్రొఫైల్ ఫోటోను ఎంచుకోండి"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ఆటోమేటిక్ సెట్టింగ్ యూజర్ చిహ్నం"</string>
+    <string name="done" msgid="3587741621903511576">"పూర్తయింది"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml
new file mode 100644
index 0000000..31e753e
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"เลือกรูปภาพ"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ถ่ายรูป"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ไอคอนผู้ใช้เริ่มต้น"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-tl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-tl/strings.xml
new file mode 100644
index 0000000..77b28cd
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-tl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Pumili ng larawan"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Kumuha ng larawan"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"Pumili ng larawan sa profile"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Icon ng default na user"</string>
+    <string name="done" msgid="3587741621903511576">"Tapos na"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml
new file mode 100644
index 0000000..26d96c2
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Resim seç"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Fotoğraf çek"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Varsayılan kullanıcı simgesi"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml
new file mode 100644
index 0000000..1fbe5fb
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Вибрати зображення"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Зробити фото"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Значок користувача за умовчанням"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ur/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ur/strings.xml
new file mode 100644
index 0000000..7972ee1
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ur/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"ایک تصویر منتخب کریں"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"ایک تصویر لیں"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"پروفائل کی تصویر منتخب کریں"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"ڈیفالٹ صارف کا آئیکن"</string>
+    <string name="done" msgid="3587741621903511576">"ہو گیا"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-uz/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-uz/strings.xml
new file mode 100644
index 0000000..208be10
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-uz/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Rasm tanlash"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Suratga olish"</string>
+    <string name="avatar_picker_title" msgid="7478146965334560463">"Profil rasmini tanlash"</string>
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Foydalanuvchining standart belgisi"</string>
+    <string name="done" msgid="3587741621903511576">"Tayyor"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml
new file mode 100644
index 0000000..036c006
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Chọn hình ảnh"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Chụp ảnh"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Biểu tượng người dùng mặc định"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..58488b3
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"选择图片"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"拍照"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"默认用户图标"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..e5f3752
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"選擇圖片"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"拍攝相片"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"預設使用者圖示"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..4a58180b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"選擇圖片"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"拍照"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"預設使用者圖示"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml
new file mode 100644
index 0000000..ad15f89
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="user_image_choose_photo" msgid="5630717762469961028">"Khetha isithombe"</string>
+    <string name="user_image_take_photo" msgid="3147097821937166738">"Thatha isithombe"</string>
+    <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+    <skip />
+    <string name="default_user_icon_description" msgid="6018582161341388812">"Isithonjana somsebenzisi sokuzenzakalelayo"</string>
+    <!-- no translation found for done (3587741621903511576) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/IntroPreference/src/com/android/settingslib/widget/IntroPreference.kt b/packages/SettingsLib/IntroPreference/src/com/android/settingslib/widget/IntroPreference.kt
index 0cdfc66..f9931cf 100644
--- a/packages/SettingsLib/IntroPreference/src/com/android/settingslib/widget/IntroPreference.kt
+++ b/packages/SettingsLib/IntroPreference/src/com/android/settingslib/widget/IntroPreference.kt
@@ -31,7 +31,7 @@
     attrs: AttributeSet? = null,
     defStyleAttr: Int = 0,
     defStyleRes: Int = 0
-) : Preference(context, attrs, defStyleAttr, defStyleRes) {
+) : Preference(context, attrs, defStyleAttr, defStyleRes), GroupSectionDividerMixin {
 
     private var isCollapsable: Boolean = false
     private var minLines: Int = 2
@@ -68,6 +68,7 @@
         (holder.findViewById(R.id.collapsable_summary) as? CollapsableTextView)?.apply {
             setCollapsable(isCollapsable)
             setMinLines(minLines)
+            visibility = if (summary.isNullOrEmpty()) View.GONE else View.VISIBLE
             setText(summary.toString())
             if (hyperlinkListener != null) {
                 setHyperlinkListener(hyperlinkListener)
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt
index c2728b4..7601b9a 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt
@@ -20,7 +20,7 @@
 import com.android.settingslib.datastore.KeyValueStore
 
 /** Adapter to translate [KeyValueStore] into [PreferenceDataStore]. */
-class PreferenceDataStoreAdapter(private val keyValueStore: KeyValueStore) : PreferenceDataStore() {
+class PreferenceDataStoreAdapter(val keyValueStore: KeyValueStore) : PreferenceDataStore() {
 
     override fun getBoolean(key: String, defValue: Boolean): Boolean =
         keyValueStore.getValue(key, Boolean::class.javaObjectType) ?: defValue
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
index 62ac3ad..7cec59c 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
@@ -74,16 +74,12 @@
     private val preferences: ImmutableMap<String, PreferenceHierarchyNode>
     private val dependencies: ImmutableMultimap<String, String>
     private val lifecycleAwarePreferences: Array<PreferenceLifecycleProvider>
-    private val storages = mutableSetOf<KeyedObservable<String>>()
+    private val storages = mutableMapOf<String, KeyedObservable<String>>()
 
     private val preferenceObserver: KeyedObserver<String?>
 
     private val storageObserver =
-        KeyedObserver<String?> { key, _ ->
-            if (key != null) {
-                notifyChange(key, CHANGE_REASON_VALUE)
-            }
-        }
+        KeyedObserver<String> { key, _ -> notifyChange(key, CHANGE_REASON_VALUE) }
 
     init {
         val preferencesBuilder = ImmutableMap.builder<String, PreferenceHierarchyNode>()
@@ -98,7 +94,6 @@
                 preferencesBuilder.put(it.key, this)
                 it.dependencyOfEnabledState(context)?.addDependency(it)
                 if (it is PreferenceLifecycleProvider) lifecycleAwarePreferences.add(it)
-                if (it is PersistentPreference<*>) storages.add(it.storage(context))
             }
         }
 
@@ -120,7 +115,16 @@
 
         preferenceObserver = KeyedObserver { key, reason -> onPreferenceChange(key, reason) }
         addObserver(preferenceObserver, mainExecutor)
-        for (storage in storages) storage.addObserver(storageObserver, mainExecutor)
+
+        preferenceScreen.forEachRecursively {
+            val preferenceDataStore = it.preferenceDataStore
+            if (preferenceDataStore is PreferenceDataStoreAdapter) {
+                val key = it.key
+                val keyValueStore = preferenceDataStore.keyValueStore
+                storages[key] = keyValueStore
+                keyValueStore.addObserver(key, storageObserver, mainExecutor)
+            }
+        }
     }
 
     private fun onPreferenceChange(key: String?, reason: Int) {
@@ -181,7 +185,7 @@
 
     fun onDestroy() {
         removeObserver(preferenceObserver)
-        for (storage in storages) storage.removeObserver(storageObserver)
+        for ((key, storage) in storages) storage.removeObserver(key, storageObserver)
         for (preference in lifecycleAwarePreferences) {
             preference.onDestroy(preferenceLifecycleContext)
         }
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/Utils.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/Utils.kt
new file mode 100644
index 0000000..2e7221b
--- /dev/null
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/Utils.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.settingslib.preference
+
+import androidx.preference.Preference
+import androidx.preference.PreferenceGroup
+
+/** Traversals preference hierarchy recursively and applies an action. */
+fun PreferenceGroup.forEachRecursively(action: (Preference) -> Unit) {
+    action.invoke(this)
+    for (index in 0 until preferenceCount) {
+        val preference = getPreference(index)
+        if (preference is PreferenceGroup) {
+            preference.forEachRecursively(action)
+        } else {
+            action.invoke(preference)
+        }
+    }
+}
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml
index ca17836f..db7f687 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml
@@ -19,5 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"व्यक्तिगत"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"कामसम्बन्धी"</string>
-    <string name="settingslib_category_private" msgid="5039276873477591386">"निजी"</string>
+    <string name="settingslib_category_private" msgid="5039276873477591386">"निजी स्पेस"</string>
 </resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-en-rCA/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..2539aa0
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-en-rCA/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Expand"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Collapse"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-hy/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-hy/strings.xml
new file mode 100644
index 0000000..2fc65f0
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-hy/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Ծավալել"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Ծալել"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ja/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ja/strings.xml
new file mode 100644
index 0000000..4e7287c
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ja/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"開く"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"閉じる"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-kn/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-kn/strings.xml
new file mode 100644
index 0000000..3fc1fcc
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-kn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ವಿಸ್ತೃತಗೊಳಿಸಿ"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ಕುಗ್ಗಿಸಿ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-mr/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-mr/strings.xml
new file mode 100644
index 0000000..db9d422
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-mr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"विस्तार करा"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"कोलॅप्स करा"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-pa/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-pa/strings.xml
new file mode 100644
index 0000000..48a756b
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-pa/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ਵਿਸਤਾਰ ਕਰੋ"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ਸਮੇਟੋ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-pt-rPT/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..58bd936
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-pt-rPT/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Expandir"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Reduzir"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-sl/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-sl/strings.xml
new file mode 100644
index 0000000..6fd67c5
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-sl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Razširi"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Strni"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ta/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ta/strings.xml
new file mode 100644
index 0000000..4a0fb4d
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ta/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"விரிவாக்கும்"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"சுருக்கும்"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-te/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-te/strings.xml
new file mode 100644
index 0000000..706e225
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-te/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"విస్తరించండి"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"కుదించండి"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-tl/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-tl/strings.xml
new file mode 100644
index 0000000..ef5825f
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-tl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"I-expand"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"I-collapse"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ur/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ur/strings.xml
new file mode 100644
index 0000000..2e020b4
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ur/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"پھیلائیں"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"سکیڑیں"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-uz/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-uz/strings.xml
new file mode 100644
index 0000000..16e389b
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-uz/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Yoyish"</string>
+    <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Yopish"</string>
+</resources>
diff --git a/packages/SettingsLib/Spa/build.gradle.kts b/packages/SettingsLib/Spa/build.gradle.kts
index 73d0bec..02e1904 100644
--- a/packages/SettingsLib/Spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/build.gradle.kts
@@ -29,7 +29,7 @@
 
 allprojects {
     extra["androidTop"] = androidTop
-    extra["jetpackComposeVersion"] = "1.7.3"
+    extra["jetpackComposeVersion"] = "1.8.0-alpha06"
 }
 
 subprojects {
diff --git a/packages/SettingsLib/Spa/gradle/libs.versions.toml b/packages/SettingsLib/Spa/gradle/libs.versions.toml
index 272dc2d..74811d3 100644
--- a/packages/SettingsLib/Spa/gradle/libs.versions.toml
+++ b/packages/SettingsLib/Spa/gradle/libs.versions.toml
@@ -15,7 +15,7 @@
 #
 
 [versions]
-agp = "8.6.1"
+agp = "8.7.2"
 compose-compiler = "1.5.11"
 dexmaker-mockito = "2.28.3"
 jvm = "17"
diff --git a/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.10.2-bin.zip b/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.10.2-bin.zip
deleted file mode 100644
index 45f0424..0000000
--- a/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.10.2-bin.zip
+++ /dev/null
Binary files differ
diff --git a/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.11.1-bin.zip b/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.11.1-bin.zip
new file mode 100644
index 0000000..f8c4ecb
--- /dev/null
+++ b/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.11.1-bin.zip
Binary files differ
diff --git a/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties b/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
index 1c25e974..ca510eb 100644
--- a/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
@@ -16,6 +16,6 @@
 
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=gradle-8.10.2-bin.zip
+distributionUrl=gradle-8.11.1-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts
index 914f06c..1f32ad6 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/spa/build.gradle.kts
@@ -54,14 +54,14 @@
 dependencies {
     api(project(":SettingsLibColor"))
     api("androidx.appcompat:appcompat:1.7.0")
-    api("androidx.compose.material3:material3:1.4.0-alpha01")
-    api("androidx.compose.material:material-icons-extended:$jetpackComposeVersion")
+    api("androidx.compose.material3:material3:1.4.0-alpha04")
+    api("androidx.compose.material:material-icons-extended")
     api("androidx.compose.runtime:runtime-livedata:$jetpackComposeVersion")
     api("androidx.compose.ui:ui-tooling-preview:$jetpackComposeVersion")
     api("androidx.graphics:graphics-shapes-android:1.0.1")
     api("androidx.lifecycle:lifecycle-livedata-ktx")
     api("androidx.lifecycle:lifecycle-runtime-compose")
-    api("androidx.navigation:navigation-compose:2.8.1")
+    api("androidx.navigation:navigation-compose:2.9.0-alpha03")
     api("com.github.PhilJay:MPAndroidChart:v3.1.0-alpha")
     api("com.google.android.material:material:1.12.0")
     debugApi("androidx.compose.ui:ui-tooling:$jetpackComposeVersion")
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
index ea6a272..7466f95 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
@@ -41,8 +41,6 @@
 import com.android.settingslib.spaprivileged.model.app.IPackageManagers
 import com.android.settingslib.spaprivileged.model.app.PackageManagers
 import com.android.settingslib.spaprivileged.model.app.toRoute
-import com.android.settingslib.spaprivileged.model.enterprise.EnhancedConfirmation
-import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
 import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderFactory
 import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl
 import com.android.settingslib.spaprivileged.template.preference.RestrictedSwitchPreference
@@ -155,12 +153,12 @@
             override val changeable = { isChangeable }
             override val onCheckedChange: (Boolean) -> Unit = { setAllowed(record, it) }
         }
-        val restrictions = Restrictions(userId = userId,
-            keys = switchRestrictionKeys,
-            enhancedConfirmation = enhancedConfirmationKey?.let { EnhancedConfirmation(
-                key = it,
-                packageName = packageName) })
-        RestrictedSwitchPreference(switchModel, restrictions, restrictionsProviderFactory)
+        RestrictedSwitchPreference(
+            model = switchModel,
+            restrictions = getRestrictions(userId, packageName),
+            ifBlockedByAdminOverrideCheckedValueTo = switchifBlockedByAdminOverrideCheckedValueTo,
+            restrictionsProviderFactory = restrictionsProviderFactory,
+        )
         InfoPageAdditionalContent(record, isAllowed)
     }
 }
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
index 627b248..d2867af1 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
@@ -26,6 +26,8 @@
 import com.android.settingslib.spa.framework.compose.rememberContext
 import com.android.settingslib.spa.framework.util.asyncMapItem
 import com.android.settingslib.spaprivileged.model.app.AppRecord
+import com.android.settingslib.spaprivileged.model.enterprise.EnhancedConfirmation
+import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
 import kotlinx.coroutines.flow.Flow
 
 /**
@@ -38,6 +40,16 @@
     val switchRestrictionKeys: List<String>
         get() = emptyList()
 
+    /**
+     * If this is not null, and on a switch UI restricted by admin, the switch's checked status will
+     * be overridden.
+     *
+     * And if there is an admin summary, such as "Enabled by admin" or "Disabled by admin", will
+     * also be overridden.
+     */
+    val switchifBlockedByAdminOverrideCheckedValueTo: Boolean?
+        get() = null
+
     val enhancedConfirmationKey: String?
         get() = null
 
@@ -101,6 +113,16 @@
     record: T,
 ): Boolean = !record.isSystemOrRootUid() && isChangeable(record)
 
+fun <T : AppRecord> TogglePermissionAppListModel<T>.getRestrictions(
+    userId: Int,
+    packageName: String,
+) =
+    Restrictions(
+        userId = userId,
+        keys = switchRestrictionKeys,
+        enhancedConfirmation =
+            enhancedConfirmationKey?.let { key -> EnhancedConfirmation(key, packageName) },
+    )
 
 interface TogglePermissionAppListProvider {
     val permissionType: String
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
index 57102ba..ec44d2a 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
@@ -42,8 +42,6 @@
 import com.android.settingslib.spaprivileged.model.app.AppListModel
 import com.android.settingslib.spaprivileged.model.app.AppRecord
 import com.android.settingslib.spaprivileged.model.app.userId
-import com.android.settingslib.spaprivileged.model.enterprise.EnhancedConfirmation
-import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
 import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderFactory
 import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl
 import com.android.settingslib.spaprivileged.model.enterprise.rememberRestrictedMode
@@ -151,23 +149,19 @@
 
     @Composable
     fun getSummary(record: T): () -> String {
-        val restrictions = remember(record.app.userId, record.app.packageName) {
-            Restrictions(
+        val restrictions =
+            listModel.getRestrictions(
                 userId = record.app.userId,
-                keys = listModel.switchRestrictionKeys,
-                enhancedConfirmation = listModel.enhancedConfirmationKey?.let {
-                    EnhancedConfirmation(
-                        key = it,
-                        packageName = record.app.packageName)
-                })
-        }
+                packageName = record.app.packageName,
+            )
         val restrictedMode by restrictionsProviderFactory.rememberRestrictedMode(restrictions)
         val allowed = listModel.isAllowed(record)
         return RestrictedSwitchPreferenceModel.getSummary(
             context = context,
-            restrictedModeSupplier = { restrictedMode },
             summaryIfNoRestricted = { getSummaryIfNoRestricted(allowed()) },
-            checked = allowed,
+            checkedIfNoRestricted = allowed,
+            checkedIfBlockedByAdmin = listModel.switchifBlockedByAdminOverrideCheckedValueTo,
+            restrictedModeSupplier = { restrictedMode },
         )
     }
 
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt
index cd72025..5fec110 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt
@@ -25,12 +25,25 @@
 import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl
 import com.android.settingslib.spaprivileged.template.preference.RestrictedSwitchPreferenceModel.Companion.RestrictedSwitchWrapper
 
+/**
+ * @param ifBlockedByAdminOverrideCheckedValueTo if this is not null and there is an admin
+ *   restriction, the switch's checked status will be overridden.
+ *
+ *   And if there is an admin summary, such as "Enabled by admin" or "Disabled by admin", will also
+ *   be overridden.
+ */
 @Composable
 fun RestrictedSwitchPreference(
     model: SwitchPreferenceModel,
     restrictions: Restrictions,
+    ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null,
 ) {
-    RestrictedSwitchPreference(model, restrictions, ::RestrictionsProviderImpl)
+    RestrictedSwitchPreference(
+        model = model,
+        restrictions = restrictions,
+        ifBlockedByAdminOverrideCheckedValueTo = ifBlockedByAdminOverrideCheckedValueTo,
+        restrictionsProviderFactory = ::RestrictionsProviderImpl,
+    )
 }
 
 @VisibleForTesting
@@ -38,13 +51,18 @@
 internal fun RestrictedSwitchPreference(
     model: SwitchPreferenceModel,
     restrictions: Restrictions,
+    ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null,
     restrictionsProviderFactory: RestrictionsProviderFactory,
 ) {
     if (restrictions.isEmpty()) {
         SwitchPreference(model)
         return
     }
-    restrictionsProviderFactory.RestrictedSwitchWrapper(model, restrictions) {
+    restrictionsProviderFactory.RestrictedSwitchWrapper(
+        model = model,
+        restrictions = restrictions,
+        ifBlockedByAdminOverrideCheckedValueTo = ifBlockedByAdminOverrideCheckedValueTo,
+    ) {
         SwitchPreference(it)
     }
 }
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt
index fb23637..0bb92ce 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt
@@ -42,26 +42,29 @@
     context: Context,
     model: SwitchPreferenceModel,
     private val restrictedMode: RestrictedMode?,
+    private val ifBlockedByAdminOverrideCheckedValueTo: Boolean?,
 ) : SwitchPreferenceModel {
     override val title = model.title
 
-    override val summary = getSummary(
-        context = context,
-        restrictedModeSupplier = { restrictedMode },
-        summaryIfNoRestricted = model.summary,
-        checked = model.checked,
-    )
+    override val checked =
+        when (restrictedMode) {
+            null -> ({ null })
+            is NoRestricted -> model.checked
+            is BaseUserRestricted -> ({ false })
+            is BlockedByAdmin -> ({ ifBlockedByAdminOverrideCheckedValueTo ?: model.checked() })
+            is BlockedByEcm -> model.checked
+        }
+
+    override val summary =
+        getSummary(
+            context = context,
+            restrictedModeSupplier = { restrictedMode },
+            summaryIfNoRestricted = model.summary,
+            checkedIfNoRestricted = checked,
+        )
 
     override val icon = model.icon
 
-    override val checked = when (restrictedMode) {
-        null -> ({ null })
-        is NoRestricted -> model.checked
-        is BaseUserRestricted -> ({ false })
-        is BlockedByAdmin -> model.checked
-        is BlockedByEcm -> model.checked
-    }
-
     override val changeable = restrictedMode.restrictEnabled(model.changeable)
 
     override val onCheckedChange = restrictedMode.restrictOnClick(model.onCheckedChange)
@@ -112,12 +115,20 @@
         fun RestrictedSwitchWrapper(
             model: SwitchPreferenceModel,
             restrictedMode: RestrictedMode?,
+            ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null,
             content: @Composable (SwitchPreferenceModel) -> Unit,
         ) {
             val context = LocalContext.current
-            val restrictedSwitchPreferenceModel = remember(restrictedMode, model) {
-                RestrictedSwitchPreferenceModel(context, model, restrictedMode)
-            }
+            val restrictedSwitchPreferenceModel =
+                remember(restrictedMode, model) {
+                    RestrictedSwitchPreferenceModel(
+                        context = context,
+                        model = model,
+                        restrictedMode = restrictedMode,
+                        ifBlockedByAdminOverrideCheckedValueTo =
+                            ifBlockedByAdminOverrideCheckedValueTo,
+                    )
+                }
             restrictedSwitchPreferenceModel.RestrictionWrapper {
                 content(restrictedSwitchPreferenceModel)
             }
@@ -127,23 +138,31 @@
         fun RestrictionsProviderFactory.RestrictedSwitchWrapper(
             model: SwitchPreferenceModel,
             restrictions: Restrictions,
+            ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null,
             content: @Composable (SwitchPreferenceModel) -> Unit,
         ) {
-            RestrictedSwitchWrapper(model, rememberRestrictedMode(restrictions).value, content)
+            RestrictedSwitchWrapper(
+                model = model,
+                restrictedMode = rememberRestrictedMode(restrictions).value,
+                ifBlockedByAdminOverrideCheckedValueTo = ifBlockedByAdminOverrideCheckedValueTo,
+                content = content,
+            )
         }
 
         fun getSummary(
             context: Context,
-            restrictedModeSupplier: () -> RestrictedMode?,
             summaryIfNoRestricted: () -> String,
-            checked: () -> Boolean?,
+            checkedIfNoRestricted: () -> Boolean?,
+            checkedIfBlockedByAdmin: Boolean? = null,
+            restrictedModeSupplier: () -> RestrictedMode?,
         ): () -> String = {
             when (val restrictedMode = restrictedModeSupplier()) {
                 is NoRestricted -> summaryIfNoRestricted()
                 is BaseUserRestricted ->
                     context.getString(com.android.settingslib.R.string.disabled)
 
-                is BlockedByAdmin -> restrictedMode.getSummary(checked())
+                is BlockedByAdmin ->
+                    restrictedMode.getSummary(checkedIfBlockedByAdmin ?: checkedIfNoRestricted())
                 is BlockedByEcm ->
                     context.getString(com.android.settingslib.R.string.disabled)
 
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt
index bf0ad0b..e736115 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt
@@ -26,9 +26,11 @@
 import androidx.compose.ui.test.performClick
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.RestrictedLockUtils
 import com.android.settingslib.spa.testutils.FakeNavControllerWrapper
 import com.android.settingslib.spaprivileged.R
 import com.android.settingslib.spaprivileged.framework.compose.getPlaceholder
+import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdminImpl
 import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted
 import com.android.settingslib.spaprivileged.tests.testutils.FakeRestrictionsProvider
 import com.android.settingslib.spaprivileged.tests.testutils.TestAppRecord
@@ -97,6 +99,26 @@
     }
 
     @Test
+    fun summary_whenAllowedButAdminOverrideToNotAllowed() {
+        fakeRestrictionsProvider.restrictedMode =
+            BlockedByAdminImpl(context = context, enforcedAdmin = ENFORCED_ADMIN)
+        val listModel =
+            TestTogglePermissionAppListModel(
+                isAllowed = true,
+                switchifBlockedByAdminOverrideCheckedValueTo = false,
+            )
+
+        val summary = getSummary(listModel)
+
+        assertThat(summary)
+            .isEqualTo(
+                context.getString(
+                    com.android.settingslib.widget.restricted.R.string.disabled_by_admin
+                )
+            )
+    }
+
+    @Test
     fun appListItem_onClick_navigate() {
         val listModel = TestTogglePermissionAppListModel()
         composeTestRule.setContent {
@@ -162,8 +184,9 @@
         const val PACKAGE_NAME = "package.name"
         const val LABEL = "Label"
         const val SUMMARY = "Summary"
-        val APP = ApplicationInfo().apply {
-            packageName = PACKAGE_NAME
-        }
+        val APP = ApplicationInfo().apply { packageName = PACKAGE_NAME }
+        const val RESTRICTION = "restriction"
+        val ENFORCED_ADMIN: RestrictedLockUtils.EnforcedAdmin =
+            RestrictedLockUtils.EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(RESTRICTION)
     }
 }
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt
index b88d1c5..1fd7ecf 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt
@@ -121,7 +121,7 @@
     }
 
     @Test
-    fun whenBlockedByAdmin_disabled() {
+    fun whenBlockedByAdmin_notOverrideChecked() {
         val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY))
         fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin
 
@@ -133,6 +133,18 @@
     }
 
     @Test
+    fun whenBlockedByAdmin_overrideCheckedToFalse() {
+        val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY))
+        fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin
+
+        setContent(restrictions, ifBlockedByAdminOverrideCheckedValueTo = false)
+
+        composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled()
+        composeTestRule.onNodeWithText(FakeBlockedByAdmin.SUMMARY).assertIsDisplayed()
+        composeTestRule.onNode(isOff()).assertIsDisplayed()
+    }
+
+    @Test
     fun whenBlockedByAdmin_click() {
         val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY))
         fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin
@@ -166,9 +178,16 @@
         assertThat(fakeBlockedByEcm.showRestrictedSettingsDetailsIsCalled).isTrue()
     }
 
-    private fun setContent(restrictions: Restrictions) {
+    private fun setContent(
+        restrictions: Restrictions,
+        ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null,
+    ) {
         composeTestRule.setContent {
-            RestrictedSwitchPreference(switchPreferenceModel, restrictions) { _, _ ->
+            RestrictedSwitchPreference(
+                model = switchPreferenceModel,
+                restrictions = restrictions,
+                ifBlockedByAdminOverrideCheckedValueTo = ifBlockedByAdminOverrideCheckedValueTo,
+            ) { _, _ ->
                 fakeRestrictionsProvider
             }
         }
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt
index 1790313..000743e 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt
@@ -28,6 +28,7 @@
 class TestTogglePermissionAppListModel(
     isAllowed: Boolean? = null,
     private val isChangeable: Boolean = false,
+    override val switchifBlockedByAdminOverrideCheckedValueTo: Boolean? = null,
 ) : TogglePermissionAppListModel<TestAppRecord> {
     override val pageTitleResId = R.string.test_permission_title
     override val switchTitleResId = R.string.test_permission_switch_title
diff --git a/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml b/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
index ea033a3..7d366f3 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
+++ b/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
@@ -22,9 +22,9 @@
     android:layout_height="wrap_content"
     android:gravity="center_vertical"
     android:orientation="vertical"
-    android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
-    android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:paddingBottom="16dp">
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingBottom="@dimen/settingslib_expressive_space_small1">
 
     <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig
index 076f82a..89de995 100644
--- a/packages/SettingsLib/aconfig/settingslib.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib.aconfig
@@ -178,3 +178,10 @@
     description: "Enable the input routing control in device details and hearing devices dialog."
     bug: "349255906"
 }
+
+flag {
+    name: "hearing_device_set_connection_status_report"
+    namespace: "accessibility"
+    description: "Enable the connection status report for a set of hearing device."
+    bug: "357878944"
+}
diff --git a/packages/SettingsLib/res/drawable/ic_bt_le_audio_sharing.xml b/packages/SettingsLib/res/drawable/ic_bt_le_audio_sharing.xml
index 6186773..9127570 100644
--- a/packages/SettingsLib/res/drawable/ic_bt_le_audio_sharing.xml
+++ b/packages/SettingsLib/res/drawable/ic_bt_le_audio_sharing.xml
@@ -15,73 +15,12 @@
   -->
 
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:height="24dp"
-        android:width="24dp"
-        android:viewportHeight="24"
-        android:viewportWidth="24"
-        android:tint="?android:attr/colorControlNormal">
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="960"
+    android:viewportWidth="960">
     <path
-        android:fillColor="#000000"
-        android:pathData="M16.984,24H7.279L12.131,15.508L16.984,24ZM10.481,22.144H13.781L12.131,19.257L10.481,22.144Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.131,14.295C13.471,14.295 14.558,13.209 14.558,11.869C14.558,10.529 13.471,9.442 12.131,9.442C10.791,9.442 9.705,10.529 9.705,11.869C9.705,13.209 10.791,14.295 12.131,14.295Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M4.573,21.368C4.052,20.943 3.967,20.179 4.379,19.657C4.804,19.136 5.568,19.051 6.09,19.463C6.611,19.876 6.696,20.64 6.284,21.174C6.041,21.465 5.689,21.623 5.338,21.623C5.071,21.623 4.804,21.538 4.573,21.368Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17.991,21.162C17.579,20.628 17.663,19.876 18.185,19.451C18.707,19.039 19.471,19.124 19.896,19.646C20.308,20.167 20.223,20.931 19.702,21.344C19.471,21.526 19.204,21.611 18.949,21.611C18.586,21.611 18.234,21.453 17.991,21.162Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M1.213,17.145C0.91,16.551 1.165,15.823 1.771,15.532C2.378,15.241 3.093,15.495 3.397,16.09C3.688,16.697 3.433,17.424 2.827,17.715C2.657,17.8 2.475,17.837 2.305,17.837C1.844,17.837 1.419,17.582 1.213,17.145Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.449,17.691C20.842,17.4 20.588,16.684 20.879,16.077C21.17,15.471 21.898,15.216 22.504,15.507C23.099,15.798 23.354,16.526 23.062,17.133C22.856,17.557 22.419,17.812 21.971,17.812C21.789,17.812 21.619,17.776 21.449,17.691Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M0,11.892C0,11.225 0.546,10.679 1.213,10.679C1.88,10.679 2.426,11.212 2.426,11.892C2.426,12.559 1.88,13.105 1.213,13.105C0.546,13.105 0,12.559 0,11.892Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.837,11.869C21.837,11.857 21.837,11.845 21.837,11.833C21.824,11.153 22.37,10.62 23.05,10.607C23.717,10.607 24.251,11.153 24.263,11.821C24.263,11.833 24.263,11.845 24.263,11.845C24.263,11.857 24.263,11.869 24.263,11.869C24.263,12.536 23.717,13.082 23.05,13.082C22.382,13.082 21.837,12.536 21.837,11.869Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M1.759,8.242C1.152,7.963 0.898,7.235 1.189,6.628C1.48,6.022 2.196,5.767 2.802,6.058C3.409,6.349 3.664,7.077 3.372,7.684C3.166,8.108 2.729,8.363 2.281,8.363C2.099,8.363 1.929,8.327 1.759,8.242Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20.866,7.622C20.563,7.028 20.818,6.3 21.424,6.009C22.019,5.706 22.747,5.96 23.038,6.567C23.038,6.567 23.038,6.567 23.05,6.567C23.341,7.161 23.087,7.889 22.48,8.181C22.31,8.265 22.128,8.302 21.958,8.302C21.509,8.302 21.073,8.059 20.866,7.622Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M4.355,4.104C3.931,3.582 4.016,2.818 4.537,2.406C5.071,1.981 5.823,2.066 6.248,2.588C6.672,3.109 6.588,3.874 6.066,4.298C5.835,4.48 5.569,4.565 5.302,4.565C4.95,4.565 4.598,4.407 4.355,4.104Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.161,4.262C17.627,3.838 17.542,3.073 17.955,2.552C18.379,2.03 19.132,1.945 19.666,2.358C20.187,2.77 20.272,3.534 19.86,4.068C19.617,4.359 19.265,4.517 18.913,4.517C18.646,4.517 18.379,4.432 18.161,4.262Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M8.492,1.497C8.334,0.854 8.747,0.199 9.402,0.041C10.057,-0.105 10.7,0.308 10.858,0.963C11.003,1.606 10.591,2.261 9.948,2.407C9.851,2.431 9.754,2.443 9.669,2.443C9.123,2.443 8.613,2.067 8.492,1.497Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14.267,2.395C13.599,2.249 13.199,1.606 13.345,0.951C13.49,0.296 14.133,-0.116 14.788,0.029C15.443,0.175 15.856,0.83 15.71,1.485C15.589,2.043 15.08,2.431 14.534,2.431C14.437,2.431 14.352,2.419 14.267,2.395Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M7,17.037C6.527,16.564 6.527,15.8 7,15.326C7.473,14.841 8.237,14.841 8.71,15.314C9.196,15.787 9.196,16.552 8.723,17.025C8.48,17.267 8.177,17.389 7.861,17.389C7.546,17.389 7.242,17.267 7,17.037Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15.565,17.012C15.092,16.539 15.092,15.762 15.565,15.289C16.038,14.816 16.814,14.816 17.288,15.289C17.761,15.762 17.761,16.539 17.288,17.012C17.045,17.243 16.742,17.364 16.426,17.364C16.111,17.364 15.807,17.243 15.565,17.012Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M4.853,11.917C4.853,11.237 5.386,10.691 6.054,10.691C6.721,10.691 7.279,11.225 7.279,11.892C7.279,12.56 6.745,13.106 6.078,13.118C5.398,13.118 4.853,12.584 4.853,11.917Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.984,11.868C16.984,11.856 16.984,11.844 16.984,11.832C16.984,11.832 16.984,11.82 16.984,11.807C16.972,11.14 17.506,10.582 18.185,10.582C18.852,10.57 19.398,11.116 19.41,11.783C19.41,11.795 19.41,11.82 19.41,11.832C19.41,11.844 19.41,11.856 19.41,11.868C19.41,12.535 18.865,13.081 18.197,13.081C17.53,13.081 16.984,12.535 16.984,11.868Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M6.952,8.471C6.478,7.997 6.478,7.233 6.952,6.76C6.952,6.76 6.952,6.76 6.939,6.76C7.413,6.275 8.189,6.275 8.662,6.748C9.135,7.221 9.147,7.985 8.674,8.458C8.432,8.701 8.116,8.822 7.813,8.822C7.497,8.822 7.194,8.701 6.952,8.471Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15.529,8.399C15.043,7.938 15.043,7.161 15.504,6.688C15.977,6.203 16.742,6.203 17.227,6.664C17.7,7.137 17.712,7.901 17.239,8.387C17.009,8.629 16.693,8.751 16.378,8.751C16.075,8.751 15.759,8.629 15.529,8.399Z"/>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10.87,5.815C10.858,5.148 11.392,4.59 12.071,4.59C12.738,4.578 13.284,5.124 13.284,5.791C13.296,6.458 12.762,7.016 12.083,7.016C11.416,7.016 10.87,6.483 10.87,5.815Z"/>
-</vector>
+        android:fillColor="@android:color/white"
+        android:pathData="M320,880L480,596L640,880L320,880ZM480,560Q447,560 423.5,536.5Q400,513 400,480Q400,447 423.5,423.5Q447,400 480,400Q513,400 536.5,423.5Q560,447 560,480Q560,513 536.5,536.5Q513,560 480,560ZM339,661Q322,661 310.5,649.5Q299,638 299,621Q299,604 310.5,592.5Q322,581 339,581Q356,581 367.5,592.5Q379,604 379,621Q379,638 367.5,649.5Q356,661 339,661ZM280,520Q263,520 251.5,508.5Q240,497 240,480Q240,463 251.5,451.5Q263,440 280,440Q297,440 308.5,451.5Q320,463 320,480Q320,497 308.5,508.5Q297,520 280,520ZM339,379Q322,379 310.5,367.5Q299,356 299,339Q299,322 310.5,310.5Q322,299 339,299Q356,299 367.5,310.5Q379,322 379,339Q379,356 367.5,367.5Q356,379 339,379ZM480,320Q463,320 451.5,308.5Q440,297 440,280Q440,263 451.5,251.5Q463,240 480,240Q497,240 508.5,251.5Q520,263 520,280Q520,297 508.5,308.5Q497,320 480,320ZM621,379Q604,379 592.5,367.5Q581,356 581,339Q581,322 592.5,310.5Q604,299 621,299Q638,299 649.5,310.5Q661,322 661,339Q661,356 649.5,367.5Q638,379 621,379ZM680,520Q663,520 651.5,508.5Q640,497 640,480Q640,463 651.5,451.5Q663,440 680,440Q697,440 708.5,451.5Q720,463 720,480Q720,497 708.5,508.5Q697,520 680,520ZM621,661Q604,661 592.5,649.5Q581,638 581,621Q581,604 592.5,592.5Q604,581 621,581Q638,581 649.5,592.5Q661,604 661,621Q661,638 649.5,649.5Q638,661 621,661ZM255,801Q238,801 226,788.5Q214,776 214,759Q214,742 226,730Q238,718 255,718Q272,718 284.5,730Q297,742 297,759Q297,776 284.5,788.5Q272,801 255,801ZM156,676Q139,676 127.5,664Q116,652 116,635Q116,618 127.5,606.5Q139,595 156,595Q173,595 185,606.5Q197,618 197,635Q197,652 185,664Q173,676 156,676ZM120,520Q103,520 91.5,508.5Q80,497 80,480Q80,463 91.5,451.5Q103,440 120,440Q137,440 148.5,451.5Q160,463 160,480Q160,497 148.5,508.5Q137,520 120,520ZM156,363Q139,363 127.5,351.5Q116,340 116,323Q116,306 127.5,294.5Q139,283 156,283Q173,283 184.5,294.5Q196,306 196,323Q196,340 184.5,351.5Q173,363 156,363ZM256,239Q239,239 227.5,227.5Q216,216 216,199Q216,182 227.5,170.5Q239,159 256,159Q273,159 284.5,170.5Q296,182 296,199Q296,216 284.5,227.5Q273,239 256,239ZM400,169Q383,169 371.5,157.5Q360,146 360,129Q360,112 371.5,100.5Q383,89 400,89Q417,89 428.5,100.5Q440,112 440,129Q440,146 428.5,157.5Q417,169 400,169ZM560,169Q543,169 531.5,157.5Q520,146 520,129Q520,112 531.5,100.5Q543,89 560,89Q577,89 588.5,100.5Q600,112 600,129Q600,146 588.5,157.5Q577,169 560,169ZM705,239Q688,239 676.5,227.5Q665,216 665,199Q665,182 676.5,170.5Q688,159 705,159Q722,159 733.5,170.5Q745,182 745,199Q745,216 733.5,227.5Q722,239 705,239ZM805,364Q788,364 776.5,352.5Q765,341 765,324Q765,307 776.5,295.5Q788,284 805,284Q822,284 833.5,295.5Q845,307 845,324Q845,341 833.5,352.5Q822,364 805,364ZM840,520Q823,520 811.5,508.5Q800,497 800,480Q800,463 811.5,451.5Q823,440 840,440Q857,440 868.5,451.5Q880,463 880,480Q880,497 868.5,508.5Q857,520 840,520ZM805,676Q788,676 776.5,664.5Q765,653 765,636Q765,619 776.5,607.5Q788,596 805,596Q822,596 833.5,607.5Q845,619 845,636Q845,653 833.5,664.5Q822,676 805,676ZM705,801Q688,801 676.5,789.5Q665,778 665,761Q665,744 676.5,732.5Q688,721 705,721Q722,721 733.5,732.5Q745,744 745,761Q745,778 733.5,789.5Q722,801 705,801Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/drawable/ic_tv_box_internal_speaker.xml b/packages/SettingsLib/res/drawable/ic_tv_box_internal_speaker.xml
new file mode 100644
index 0000000..2a90e05
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_tv_box_internal_speaker.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ 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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?android:attr/textColorPrimary"
+    android:autoMirrored="true">
+    <path android:fillColor="#FFFFFFFF"
+        android:pathData="M14,20.725V18.675Q16.25,18.025 17.625,16.175Q19,14.325 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,15.15 19.05,17.587Q17.1,20.025 14,20.725ZM3,15V9H7L12,4V20L7,15ZM14,16V7.95Q15.175,8.5 15.838,9.6Q16.5,10.7 16.5,12Q16.5,13.275 15.838,14.362Q15.175,15.45 14,16ZM10,8.85 L7.85,11H5V13H7.85L10,15.15ZM7.5,12Z"/>
+</vector>
\ 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 6f6a357..3225985 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimenteel) Laat Linux-terminale op Android loop"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"As jy deaktiveer, sal Linux se terminale data uitgevee word"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Eksterne toestel"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Gekoppelde toestel"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Hierdie foon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AANVULLENDE"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan nie op hierdie toestel speel nie"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Gradeer rekening op om oor te skakel"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan nie aflaaie hier speel nie"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 4d7731c..34f37b4 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(የሙከራ) Android ላይ Linux ተርሚናል ያሂዱ"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ካሰናከሉ የLinux ተርሚናል ውሂብ ይሰርዛል"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"የHDCP ምልከታ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"የHDCP መመልከቻ ጠባይ አዘጋጅ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ስህተት በማስወገድ ላይ"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"የውጭ መሣሪያ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"የተገናኘ መሣሪያ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ይህ ስልክ"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"አናሎግ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ተጨማሪ"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"በዚህ መሣሪያ ላይ ማጫወት አልተቻለም"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"ለመቀየር መለያ ያልቁ"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ውርዶችን እዚህ ማጫወት አይቻልም"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 8b81313..2ea1486 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"‏(تجريبي) تشغيل تطبيق وحدة Linux الطرفية على Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"‏في حال إيقاف تطبيق وحدة Linux الطرفية، سيتم محو بياناتها"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"‏التحقق من HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏تعيين سلوك التحقق من HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"تصحيح الأخطاء"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"جهاز خارجي"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"جهاز متّصل"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"هذا الهاتف"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"مصدر إخراج صوت تناظري"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"لا يمكن تشغيل الوسائط هنا"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"يجب ترقية الحساب للتبديل"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"المحتوى المنزَّل غير متوافق"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 02324de..432d443 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(পৰীক্ষামূলক) Androidত Linux টাৰ্মিনেল চলাওক"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"আপুনি যদি অক্ষম কৰে, Linux টাৰ্মিনেলৰ ডেটা মচি পেলোৱা হ’ব"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP পৰীক্ষণ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP পৰীক্ষণ আচৰণ ছেট কৰক"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ডিবাগিং"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"বাহ্যিক ডিভাইচ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"সংযোগ হৈ থকা ডিভাইচ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"এই ফ’নটো"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"এনালগ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"অক্স"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"এই ডিভাইচটো প্লে\' কৰিব নোৱাৰি"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"সলনি কৰিবলৈ একাউণ্ট আপগ্ৰে’ড কৰক"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ইয়াত ডাউনল’ডসমূহ প্লে’ কৰিব নোৱাৰি"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 25e85d5..330532e 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Təcrübi) Android-də Linux terminalını işlədin"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Deaktiv etsəniz, Linux terminal datası silinəcək"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Xarici cihaz"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Qoşulmuş cihaz"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Bu telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoq"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu cihazda oxutmaq olmur"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Keçirmək üçün hesabı güncəllə"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Burada endirmələri oxutmaq olmur"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 4214a40..4dfd253 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentalno) Pokrenite Linux terminal na Android-u"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ako onemogućite, podaci Linux terminala se briš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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Spoljni uređaj"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Povezani uređaj"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogni"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ne možete da pustite na ovom uređaju"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite nalog radi prebacivanja"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Preuzimanja ne mogu da se puštaju ovde"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 3e645b3..de25460 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"Запусціць тэрмінал Linux на прыладзе Android (эксперыментальная функцыя)"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Калі адключыць гэту функцыю, даныя тэрмінала Linux будуць сцёрты"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Праверка HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Усталяваць рэжым праверкі HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Адладка"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Знешняя прылада"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Падключаная прылада"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Гэты тэлефон"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналагавы"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не ўдаецца прайграць на гэтай прыладзе"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Для пераключэння перайдзіце на іншую версію ўліковага запісу"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Тут не ўдаецца прайграць спампоўкі"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 8bdd17e..47ce37c 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Експериментално) Стартиране на терминала на Linux под Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ако деактивир., данните в терминала на Linux ще бъдат изчистени"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка с HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Проверка с HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Отстраняване на грешки"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Външно устройство"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Свързано устройство"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Този телефон"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогов"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Възпроизвеждането не е възможно на това устройство"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Надстройте профила, за да превключите"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Изтеглянията не могат да се възпроизвеждат тук"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 834eb1e..3b77cfd 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(পরীক্ষামূলক) Android-এ Linux টার্মিনাল চালান"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"আপনি বন্ধ করে দিলে, Linux টার্মিনাল ডেটা মুছে যাবে"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP পরীক্ষণ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP চেক করার আচরণ সেট করুন"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ডিবাগিং"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"এক্সটার্নাল ডিভাইস"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"কানেক্ট থাকা ডিভাইস"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"এই ফোনটি"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"অ্যানালগ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"এই ডিভাইসে চালানো যাবে না"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"পাল্টাতে অ্যাকাউন্ট আপগ্রেড করুন"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"এতে ডাউনলোড করা কন্টেন্ট প্লে করা যাবে না"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 75fe818..65eb681 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentalno) Pokreni Linux terminal na Androidu"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ako onemogućite ovo, podaci Linux terminala će se obrisati"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Vanjski uređaj"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Povezani uređaj"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogni"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nije moguće reproducirati na uređaju"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite račun da promijenite"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Nije moguće reproducirati preuzimanja ovdje"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 2c41b1a..a7c3faf 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executa el terminal de Linux a Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Si desactives l\'app, les dades del terminal de Linux s\'esborraran"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositiu extern"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositiu connectat"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Aquest telèfon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analògic"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"No es pot reproduir en aquest dispositiu"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualitza el compte per canviar"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Les baixades no es poden reproduir aquí"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index a4b491b..832d320 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimentální) Spustit terminál Linux na Androidu"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Při deaktivaci se vymažou data terminálu 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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externí zařízení"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Připojené zařízení"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogové"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"V zařízení nelze přehrávat"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Účet je třeba upgradovat"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Stažený obsah zde nelze přehrát"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index f740273..708d5df 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentelt) Kør Linux-terminal i Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Hvis du deaktiverer Linux-terminaldata, ryddes dataene."</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ekstern enhed"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Forbundet enhed"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Denne telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan ikke afspilles på denne enhed"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Opgrader kontoen for at skifte"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Downloads kan ikke afspilles her"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index c8d8cb5..069201a 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -358,7 +358,8 @@
     <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>
     <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-Entwicklungsumgebung"</string>
-    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linux-Terminal unter Android ausführen"</string>
+    <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimentell) Linux-Terminal unter Android ausführen"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Wenn du die Linux-Terminal App deaktivierst, werden die Daten darin gelöscht"</string>
     <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>
@@ -503,7 +504,7 @@
     <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Wird geladen"</string>
     <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATUS">%2$s</xliff:g> – Vollständig geladen in <xliff:g id="TIME">%3$s</xliff:g>"</string>
     <string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> – Vollständig geladen in <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Vollständig geladen in <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Vollständig geladen um <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Vollständig geladen bis <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Unbekannt"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Wird aufgeladen"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externes Gerät"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Verbundenes Gerät"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Dieses Smartphone"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Wiedergabe auf diesem Gerät nicht möglich"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Zum Umstellen Kontoupgrade durchführen"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Downloads können hier nicht abgespielt werden"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index c773372..8577a9a 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Πειραματικό) Εκτέλεση τερματικού Linux σε Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Εάν απενεργοποιηθεί, τα δεδομένα τερματικού Linux θα διαγραφούν"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Έλεγχος HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Ρύθμιση συμπεριφοράς ελέγχου HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Εντοπισμός σφαλμάτων"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Εξωτερική συσκευή"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Συνδεδεμένη συσκευή"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Αυτό το τηλέφ."</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Αναλογικός"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Δεν είναι δυνατή η αναπαραγωγή σε αυτήν τη συσκευή"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Αναβαθμίστε τον λογαριασμό για εναλλαγή"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Δεν είναι δυνατή η αναπαραγωγή των λήψεων εδώ"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 8fe1435..f9d2f08 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Run Linux terminal on Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"If you disable, Linux terminal data will be cleared"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"External device"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Connected device"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogue"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Can\'t play downloads here"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 0d560ea..2cf98ef 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Run Linux terminal on Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"If you disable, Linux terminal data will be cleared"</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 8fe1435..f9d2f08 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Run Linux terminal on Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"If you disable, Linux terminal data will be cleared"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"External device"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Connected device"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogue"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Can\'t play downloads here"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 8fe1435..f9d2f08 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Run Linux terminal on Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"If you disable, Linux terminal data will be cleared"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"External device"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Connected device"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogue"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Can\'t play downloads here"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 99dd4d9..a4834d8 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Ejecuta la terminal de Linux en Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Si lo inhabilitas, se borrarán los datos de la terminal de Linux"</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>
@@ -490,7 +491,7 @@
     <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g> según el uso"</string>
     <string name="power_discharge_by" msgid="4113180890060388350">"Duración aproximada hasta: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta la(s) <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Es posible que la batería se agote para las <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
     <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"No se puede reproducir en este dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualiza la cuenta para cambiar"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"No se pueden reproducir las descargas aquí"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index cbbadd4..1792fd1 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Ejecutar un terminal de Linux en Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Si la inhabilitas, se borrarán los datos del terminal de Linux"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"No se puede reproducir en este dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualiza la cuenta para cambiar"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"No se pueden reproducir descargas aquí"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 3c33793..5411d0b 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Katseline) Linuxi terminal Androidis"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Keelamisel kustutatakse Linuxi terminali andmed"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Väline seade"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Ühendatud seade"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"See telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/SPDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Selles seadmes ei saa esitada"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Lülitamiseks täiendage kontot"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Siin ei saa allalaaditud faile esitada"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index c994748..090d99d 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"Exekutatu Linux terminala Android-en (esperimentala)"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Desgaitzen baduzu, Linux-eko terminaleko datuak garbituko dira"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Kanpoko gailua"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Konektatutako gailua"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Telefono hau"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogikoa"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ezin da erreproduzitu gailu honetan"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Aldatzeko, bertsio-berritu kontua"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Deskargak ezin dira hemen erreproduzitu"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 75b8051..c350175 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"‏(آزمایشی) اجرا کردن «پایانه Linux» در Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"‏اگر پایانه Linux را غیرفعال کنید، داده‌های آن پاک خواهد شد"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"‏بررسی HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏تنظیم عملکرد بررسی HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"اشکال‌زدایی"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"دستگاه خارجی"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"دستگاه متصل"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"این تلفن"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"آنالوگ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"نمی‌توان در این دستگاه پخش کرد"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"برای تغییر، حساب را ارتقا دهید"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"نمی‌توان بارگیری‌ها را در اینجا پخش کرد"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 9cc33b0..18a84b5 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Kokeellinen) Käynnistä Linux-pääte Androidilla"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jos poistat tämän käytöstä, Linux-päätteen data tyhjennetään"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ulkoinen laite"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Yhdistetty laite"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Tämä puhelin"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoginen"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ei voi toistaa tällä laitteella"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Vaihda päivittämällä tili"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Latauksia ei voi toistaa täällä"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 28692d0..066244a 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Expérimental) Exécutez le terminal Linux sur Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"La désactivation effacera les données du terminal Linux"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Appareil externe"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Appareil connecté"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ce téléphone"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogique"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossible de faire jouer le contenu sur cet appareil"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Mettez à jour le compte pour passer à la version payante"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Lecture des téléchargements impossible ici"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 4e7abc93..84c2f15 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Version expérimentale) Exécuter le terminal Linux sur Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"La désactivation entraîne la suppression des données du terminal Linux"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Appareil externe"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Appareil connecté"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ce téléphone"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogique"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossible de lire du contenu sur cet appareil"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Mettez à niveau le compte pour changer"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Impossible de lire les téléchargements ici"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index a4d3a0a..d15b6e2 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executa o terminal de Linux en Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se desactivas a opción, borraranse os datos do terminal de Linux"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analóxica"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Non se pode reproducir contido neste dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Cambia a conta a un plan superior para facer a modificación"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Non se poden reproducir as descargas neste dispositivo"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 7a26463..5fd187f 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(પ્રાયોગિક) Android પર Linux ટર્મિનલ ચલાવો"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Linux ટર્મિનલ ઍપને બંધ કરવાથી તેનો ડેટા સાફ કરવામાં આવશે"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP તપાસણી"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP તપાસણીની વર્તણૂક બદલો"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ડીબગિંગ"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"બહારનું ડિવાઇસ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"કનેક્ટ કરેલું ડિવાઇસ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"આ ફોન"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"એનાલોગ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ઑગ્ઝિલરી"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"આ ડિવાઇસ પર ચલાવી શકતા નથી"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"સ્વિચ કરવા માટે એકાઉન્ટ અપગ્રેડ કરો"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ડાઉનલોડ કરેલું કન્ટેન્ટ અહીં ચલાવી શકતા નથી"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 83cb398..fa0716e 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(एक्सपेरिमेंट के तौर पर) Android पर Linux का टर्मिनल ऐप्लिकेशन चलाएं"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Linux टर्मिनल ऐप्लिकेशन को बंद करने पर, उसका डेटा मिट जाएगा"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP जांच"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP जाँच व्‍यवहार सेट करें"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"डीबग करना"</string>
@@ -584,19 +585,16 @@
     <string name="time_unit_just_now" msgid="3006134267292728099">"अभी-अभी"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"यह फ़ोन"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"यह टैबलेट"</string>
-    <string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"इस कंप्यूटर पर (इंटरनल)"</string>
+    <string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"यह कंप्यूटर (इंटरनल)"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
     <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"डॉक स्पीकर"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"बाहरी डिवाइस"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"कनेक्ट किया गया डिवाइस"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"यह फ़ोन"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ऐनालॉग"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ऑक्स"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"इस डिवाइस पर मीडिया नहीं चलाया जा सकता"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"प्रीमियम खाते में स्विच करने के लिए, अपना खाता अपग्रेड करें"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"डाउनलोड किए गए वीडियो यहां नहीं चलाए जा सकते"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index e78884d..8ad5c9d 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentalno) Pokreni Linux terminal na Androidu"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ako to onemogućite, podaci Linux terminala će se izbrisati"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Vanjski uređaj"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Povezani uređaj"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogni"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ne može se reproducirati ovdje"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite i prebacite se"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ne može se tu reproducirati"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index ca18ac2..18c6ea3 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Kísérleti) Linux-terminál futtatása Androidon"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Letiltás esetén törlődnek a Linux-terminál adatai"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Külső eszköz"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Csatlakoztatott eszköz"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ez a telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analóg"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nem játszható le ezen az eszközön"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"A váltáshoz frissítse fiókját"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Itt nem játszhatók le a letöltések"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 0749d60..593479a 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"Գործարկել Լինուքս տերմինալը Android-ում (փորձնական)"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Եթե անջատեք, Լինուքս տերմինալի տվյալները կջնջվեն"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Արտաքին սարք"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Միացված սարք"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Այս հեռախոսը"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Անալոգային"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Հնարավոր չէ նվագարկել այս սարքում"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Փոխելու համար անցեք հաշվի պրեմիում տարբերակին"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ներբեռնումները չեն նվագարկվում այստեղ"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 7d652c9..6522e22 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimental) Jalankan terminal Linux di Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jika dinonaktifkan, data terminal Linux akan dihapus"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Perangkat Eksternal"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Perangkat yang terhubung"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ponsel ini"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Tidak dapat memutar di perangkat ini"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade akun untuk beralih"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tidak dapat memutar hasil download di sini"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 67f4fe1b..4a10fb3 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Á tilraunastigi) Keyrðu Linux-útstöð í Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ef þú slekkur á þessu verður gögnum í Linux-útstöð eytt"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ytra tæki"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Tengt tæki"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Þessi sími"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Hliðrænt"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ekki er hægt að spila í þessu tæki"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Uppfærðu reikninginn til að skipta"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ekki er hægt að spila niðurhal hér"</string>
@@ -739,7 +737,7 @@
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ef þú sendir út <xliff:g id="SWITCHAPP">%1$s</xliff:g> eða skiptir um úttak lýkur yfirstandandi útsendingu"</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Senda út <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Skipta um úttak"</string>
-    <string name="back_navigation_animation" msgid="8105467568421689484">"Hreyfimyndir flýtiritunar við bendinguna „til baka“"</string>
+    <string name="back_navigation_animation" msgid="8105467568421689484">"Hreyfimyndir flýtiritunar við bendinguna „Til baka“"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Kveikja á hreyfimyndum í kerfinu til að sýna hreyfimyndir þegar bendingin „til baka“ er gerð."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Þessi stilling kveikir á hreyfimyndum í kerfinu til að sýna hreyfimyndir flýtiritunar með bendingum. Stillingin krefst þess að kveikt sé á enableOnBackInvokedCallback í upplýsingaskránni fyrir hvert forrit."</string>
     <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 9f7f41b..21f78dd 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Sperimentale) Esegui il terminale Linux su Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se disattivi l\'opzione, i dati del terminale Linux verranno cancellati"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo esterno"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo connesso"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Questo smartphone"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogico"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossibile riprodurre su questo dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Esegui l\'upgrade dell\'account per cambiare"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Qui non è possibile riprodurre i download"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 056aae1..3b28bd2 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"‏(ניסיוני) הפעלת טרמינל Linux ב-Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"‏אם ההגדרה תושבת, הנתונים של טרמינל Linux יימחקו"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"‏בדיקת HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏הגדרת האופן של בדיקת HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ניפוי באגים"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"מכשיר חיצוני"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"המכשיר המחובר"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"הטלפון הזה"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"אנלוגי"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"לא ניתן להפעיל במכשיר"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"יש לשדרג חשבון כדי לעבור"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"לא ניתן להפעיל הורדות"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 833d1dc..a826810 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(試験運用版)Android で Linux ターミナルを実行する"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"無効にすると、Linux ターミナルのデータが消去されます"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP チェック"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP チェック動作を設定"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"デバッグ"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部デバイス"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"接続済みのデバイス"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"このデバイス"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"アナログ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"このデバイスでは再生できません"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"アカウントを更新して切り替えてください"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"再生不可: ダウンロードしたコンテンツ"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index acad174..f321371 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(ექსპერიმენტული) Linux ტერმინალის გაშვება Android-ზე"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"გათიშვის შემთხვევაში, წაიშლება Linux ტერმინალის მონაცემები"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP შემოწმება"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"დააყენე HDCP შემოწმების ქცევა"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"გამართვა"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"გარე მოწყობილობა"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"დაკავშირებული მოწყობილობა"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ეს ტელეფონი"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ანალოგური"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"ამ მოწყობილობაზე დაკვრა შეუძლებელია"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"გადასართავად განაახლეთ ანგარიში"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"შეუძლებელია აქ ჩამოტვირ. თამაში"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index e2ce5b0..85b86d4 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Эксперименттік) Linux терминалын Android-та іске қосу"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Өшірсеңіз, Linux терминалының деректері өшіріледі."</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP тексерісі"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP (кең жолақты цифрлық контент қорғау) тексеру мүмкіндігін орнату"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Түзету"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Сыртқы құрылғы"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Жалғанған құрылғы"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Осы телефон"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогтік"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Осы құрылғыда ойнату мүмкін емес."</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Ауысу үшін аккаунтты жаңартыңыз."</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Жүктеп алынғандарды осы жерде ойнату мүмкін емес."</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index c06aaee..12d35cf 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(ពិសោធន៍) ដំណើរការទែមីណាល់ Linux នៅលើ Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ប្រសិនបើអ្នកបិទ ទិន្នន័យទែមីណាល់ Linux នឹងត្រូវបានសម្អាត"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"ពិនិត្យ HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"កំណត់​ឥរិយាបថ​ពិនិត្យ HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ការជួសជុល"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"ឧបករណ៍ខាងក្រៅ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"​ឧបករណ៍ដែលបាន​ភ្ជាប់"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ទូរសព្ទនេះ"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"អាណាឡូក"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"មិនអាចចាក់នៅលើ​ឧបករណ៍នេះបានទេ"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"ដំឡើងកម្រិតគណនី ដើម្បីប្ដូរ"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"មិនអាចចាក់ខ្លឹមសារដែលបានទាញយកនៅទីនេះបានទេ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 2c25501..d95846f 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -237,7 +237,7 @@
     <string name="choose_profile" msgid="343803890897657450">"ಪ್ರೊಫೈಲ್ ಆಯ್ಕೆ ಮಾಡಿ"</string>
     <string name="category_personal" msgid="6236798763159385225">"ವೈಯಕ್ತಿಕ"</string>
     <string name="category_work" msgid="4014193632325996115">"ಕೆಲಸ"</string>
-    <string name="category_private" msgid="4244892185452788977">"ಖಾಸಗಿ"</string>
+    <string name="category_private" msgid="4244892185452788977">"ಪ್ರೈವೆಟ್"</string>
     <string name="category_clone" msgid="1554511758987195974">"ಕ್ಲೋನ್"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(ಪ್ರಾಯೋಗಿಕ) Android ನಲ್ಲಿ Linux ಟರ್ಮಿನಲ್ ಅನ್ನು ರನ್ ಮಾಡಿ"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ನೀವು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದರೆ, Linux ಟರ್ಮಿನಲ್ ಡೇಟಾ ತೆರವುಗೊಳಿಸಲಾಗುತ್ತದೆ"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ಪರೀಕ್ಷಿಸುವಿಕೆ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ಪರಿಶೀಲನಾ ನಡವಳಿಕೆಯನ್ನು ಹೊಂದಿಸಿ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"ಬಾಹ್ಯ ಸಾಧನ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"ಕನೆಕ್ಟ್ ಮಾಡಿರುವ ಸಾಧನ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ಈ ಫೋನ್"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ಅನಲಾಗ್"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"ಈ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"ಬದಲಾಯಿಸಲು ಖಾತೆಯನ್ನು ಅಪ್‌ಗ್ರೇಡ್ ಮಾಡಿ"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ಇಲ್ಲಿ ಡೌನ್‌ಲೋಡ್‌ಗಳನ್ನು ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index f7dc6ae..f82a6a6 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(실험용) Android에서 Linux 터미널 실행"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"사용 중지하면 Linux 터미널 데이터가 삭제됩니다."</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 확인"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP 확인 동작 설정"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"디버깅"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"외부 기기"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"연결된 기기"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"이 휴대전화"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"아날로그"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"이 기기에서 재생할 수 없음"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"계정을 업그레이드하여 전환하기"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"여기서 다운로드한 콘텐츠를 재생할 수 없습니다."</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 6105db0..ff63c19 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -237,7 +237,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Профиль тандоо"</string>
     <string name="category_personal" msgid="6236798763159385225">"Жеке"</string>
     <string name="category_work" msgid="4014193632325996115">"Жумуш"</string>
-    <string name="category_private" msgid="4244892185452788977">"Купуя"</string>
+    <string name="category_private" msgid="4244892185452788977">"Жеке профиль"</string>
     <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Иштеп чыгуучунун параметрлери"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Иштеп чыгуучунун параметрлерин иштетүү"</string>
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Cынамык) Linux терминалын Android\'де иштетүү"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Эгер өчүрүп койсоңуз, Linux терминалынын маалыматы тазаланат"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP текшерүү"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP текшерүү тартиби"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Мүчүлүштүктөрдү аныктоо"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Тышкы түзмөк"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Туташкан түзмөк"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ушул телефон"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналог"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"КШМЧ"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Бул түзмөктө ойнотууга болбойт"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Премиум аккаунтка которулуу керек"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Жүктөлүп алынгандар ойнотулбайт"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index df3689e..36d2ccf 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -358,7 +358,8 @@
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal ໃນໂຕເຄື່ອງ"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"ເປີດນຳໃຊ້ແອັບຯ Terminal ທີ່ໃຫ້ການເຂົ້າເຖິງ shell ໃນໂຕເຄື່ອງໄດ້"</string>
     <string name="enable_linux_terminal_title" msgid="5076044866895670637">"ສະພາບແວດລ້ອມໃນການພັດທະນາ Linux"</string>
-    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"ເອີ້ນໃຊ້ເທີມິນອນ Linux ຢູ່ Android"</string>
+    <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ເປັນການທົດລອງ) ເອີ້ນໃຊ້ເທີມິນອນ Linux ຢູ່ Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ຫາກທ່ານປິດການນຳໃຊ້, ລະບົບຈະລຶບລ້າງຂໍ້ມູນເທີມິນອນ Linux"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"ການກວດສອບ HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"ຕັ້ງວິທີການກວດສອບ HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ການດີບັກ"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"ອຸປະກອນພາຍນອກ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"ອຸປະກອນທີ່ເຊື່ອມຕໍ່"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ໂທລະສັບນີ້"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ໂມງເຂັມ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"ຫຼິ້ນຢູ່ອຸປະກອນນີ້ບໍ່ໄດ້"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"ອັບເກຣດບັນຊີເພື່ອສະຫຼັບ"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ບໍ່ສາມາດຫຼິ້ນເນື້ອຫາທີ່ດາວໂຫຼດຢູ່ນີ້ໄດ້"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 4d98587..5b20db3 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentas) „Linux“ terminalo paleidimas sistemoje „Android“"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jei išjungsite, „Linux“ terminalo duomenys bus išvalyti"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Išorinis įrenginys"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Prijungtas įrenginys"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Šis telefonas"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoginis"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Negalima leisti šiame įrenginyje"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Jei norite perjungti, naujovinkite paskyrą"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Čia negalima paleisti atsisiuntimų"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 5829826..620318a 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -235,9 +235,9 @@
     <item msgid="6946761421234586000">"400%"</item>
   </string-array>
     <string name="choose_profile" msgid="343803890897657450">"Profila izvēlēšanās"</string>
-    <string name="category_personal" msgid="6236798763159385225">"Privāts"</string>
+    <string name="category_personal" msgid="6236798763159385225">"Personīgais"</string>
     <string name="category_work" msgid="4014193632325996115">"Darba"</string>
-    <string name="category_private" msgid="4244892185452788977">"Privāti"</string>
+    <string name="category_private" msgid="4244892185452788977">"Privāts"</string>
     <string name="category_clone" msgid="1554511758987195974">"Klons"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Izstrādātāju opcijas"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Izstrādātāju opciju iespējošana"</string>
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentāls) Palaist Linux termināli Android ierīcē"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ja atspējosiet, Linux termināļa dati tiks notīrīti"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ārēja ierīce"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Pievienotā ierīce"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Šis tālrunis"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogā"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nevar atskaņot šajā ierīcē."</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Lai pārslēgtu, jauniniet kontu"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Šeit nevar atskaņot lejupielādes"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 5d5d480..0331ece 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -235,9 +235,9 @@
     <item msgid="6946761421234586000">"400 %"</item>
   </string-array>
     <string name="choose_profile" msgid="343803890897657450">"Изберете профил"</string>
-    <string name="category_personal" msgid="6236798763159385225">"Лично"</string>
+    <string name="category_personal" msgid="6236798763159385225">"Личен"</string>
     <string name="category_work" msgid="4014193632325996115">"Работа"</string>
-    <string name="category_private" msgid="4244892185452788977">"Приватно"</string>
+    <string name="category_private" msgid="4244892185452788977">"Приватен"</string>
     <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Програмерски опции"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Овозможете ги програмерските опции"</string>
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Експериментално) Вклучете го Linux-терминалот на Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ако оневозможите, податоците за Linux-терминалот ќе се избришат"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка со HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Постави однесување на проверка на HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Отстранување грешки"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Надворешен уред"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Поврзан уред"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Овој телефон"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогно"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не може да се пушти на уредов"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Надградете ја сметката за да се префрлите"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Не може да се пуштаат преземања тука"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 7140623..aaebe4c 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(പരീക്ഷണാത്മകം) Android-ൽ Linux ടെർമിനൽ റൺ ചെയ്യുക"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"പ്രവർത്തനരഹിതമാക്കുകയാണെങ്കിൽ, Linux ടെർമിനൽ ഡാറ്റ മായ്ക്കും"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP പരിശോധന"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ചെക്കിംഗ്‌രീതി സജ്ജമാക്കുക"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ഡീബഗ്ഗിംഗ്"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"ബാഹ്യ ഉപകരണം"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"കണക്‌റ്റ് ചെയ്‌ത ഉപകരണം"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ഈ ഫോൺ"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"അനലോഗ്"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"ഈ ഉപകരണത്തിൽ പ്ലേ ചെയ്യാൻ കഴിയില്ല"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"അക്കൗണ്ട് മാറാൻ അപ്‌ഗ്രേഡ് ചെയ്യുക"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ഡൗൺലോഡുകൾ പ്ലേ ചെയ്യാനാകില്ല"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index c9e0178..fb2b729 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Туршилтын) Android дээр Linux терминалыг ажиллуулах"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Хэрэв та идэвхгүй болговол Linux терминалын өгөгдлийг арилгана"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP шалгах"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP шалгах авирыг тохируулах"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Дебаг"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Гадаад төхөөрөмж"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Холбогдсон төхөөрөмж"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Энэ утас"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Aналог"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"НЭМЭЛТ"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Энэ төхөөрөмжид тоглуулах боломжгүй"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Сэлгэхийн тулд бүртгэлийг сайжруулна уу"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Татаж авсан файлыг энд тоглуулах боломжгүй"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index a6596cd..023a2e4 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(प्रायोगिक) Android वर Linux टर्मिनल रन करा"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"तुम्ही Linux टर्मिनल बंद केल्यास, डेटा साफ केला जाईल"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP तपासणी"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP तपासणी वर्तन सेट करा"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"डीबग करणे"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"बाह्य डिव्हाइस"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"कनेक्ट केलेले डिव्हाइस"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"हा फोन"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"अ‍ॅनालॉग"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"या डिव्हाइसवर प्ले करू शकत नाही"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"स्विच करण्यासाठी खाते अपग्रेड करा"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"येथे डाउनलोड प्ले केले जाऊ शकत नाहीत"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index ebde331..4212eb4 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Percubaan) Jalankan terminal Linux pada Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jika dilumpuhkan, data terminal Linux akan dikosongkan"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Peranti Luar"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Peranti yang disambungkan"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Telefon ini"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Tidak dapat dimainkan pada peranti ini"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Tingkatkan akaun untuk beralih"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tidak dapat memainkan muat turun di sini"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 1131007..df13e6c 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(စမ်းသပ်) Android တွင် Linux တာမီနယ်ကို လုပ်ဆောင်ရန်"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ပိတ်လိုက်ပါက Linux တာမီနယ်ဒေတာကို ရှင်းထုတ်ပါမည်"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP စစ်ဆေးမှု"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP စစ်ဆေးပုံကို သတ်မှတ်မည်"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"အမှားရှာဖွေဖယ်ရှားခြင်း"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"ပြင်ပစက်"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"ချိတ်ဆက်ကိရိယာ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ဤဖုန်း"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ရိုးရိုး"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"ဤစက်ပစ္စည်းတွင် ဖွင့်၍မရပါ"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"ပြောင်းရန် အကောင့်အဆင့်ကိုမြှင့်ပါ"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ဤနေရာတွင် ဒေါင်းလုဒ်များ ဖွင့်မရပါ"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 1a71ec0..8126663 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(På forsøksstadiet) Kjør Linux-terminal på Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Hvis du slår av dette, slettes Linux-terminaldataene"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ekstern enhet"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Tilkoblet enhet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Denne telefonen"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan ikke spille på denne enheten"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Oppgrader kontoen for å bytte"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan ikke spille av nedlastinger her"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index dea9fcc..a233622 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -167,7 +167,7 @@
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"कम्प्युटर"</string>
     <string name="bluetooth_talkback_headset" msgid="3406852564400882682">"हेडसेट"</string>
     <string name="bluetooth_talkback_phone" msgid="868393783858123880">"फोन"</string>
-    <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"छवि सम्बन्धी"</string>
+    <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"फोटो सम्बन्धी"</string>
     <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"हेडफोन"</string>
     <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"इनपुट सम्बन्धी बाह्य यन्त्र"</string>
     <string name="bluetooth_talkback_hearing_aids" msgid="3983279945542595479">"हियरिङ डिभाइसहरू"</string>
@@ -237,7 +237,7 @@
     <string name="choose_profile" msgid="343803890897657450">"प्रोफाइल रोज्नुहोस्"</string>
     <string name="category_personal" msgid="6236798763159385225">"व्यक्तिगत"</string>
     <string name="category_work" msgid="4014193632325996115">"काम"</string>
-    <string name="category_private" msgid="4244892185452788977">"निजी"</string>
+    <string name="category_private" msgid="4244892185452788977">"निजी स्पेस"</string>
     <string name="category_clone" msgid="1554511758987195974">"क्लोन"</string>
     <string name="development_settings_title" msgid="140296922921597393">"विकासकर्ताका विकल्पहरू"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"विकासकर्ता विकल्प सक्रिया गर्नुहोस्"</string>
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(परीक्षणको चरणमा रहेको) Android मा Linux टर्मिनल रन गर्नुहोस्"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"तपाईंले Linux टर्मिनल डिसएबल गर्नुभयो भने त्यसमा भएको डेटा मेटिने छ"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP जाँच"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP जाँच व्यवहार सेट गर्नुहोस्"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"डिबग गरिँदै छ"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"बाह्य डिभाइस"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"कनेक्ट गरिएको डिभाइस"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"यो फोन"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"एनालग"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"यो डिभाइसमा मिडिया प्ले गर्न मिल्दैन"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"आफूले प्रयोग गर्न चाहेको खाता अपग्रेड गर्नुहोस्"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"डाउनलोड गरिएका सामग्री यसमा प्ले गर्न मिल्दैन"</string>
@@ -713,7 +711,7 @@
     <string name="data_connection_lte" msgid="7675461204366364124">"LTE"</string>
     <string name="data_connection_lte_plus" msgid="6643158654804916653">"LTE+"</string>
     <string name="data_connection_carrier_wifi" msgid="8932949159370130465">"W+"</string>
-    <string name="cell_data_off_content_description" msgid="2280700839891636498">"मोबाइल डेटा निष्क्रिय छ"</string>
+    <string name="cell_data_off_content_description" msgid="2280700839891636498">"मोबाइल डेटा अफ छ"</string>
     <string name="not_default_data_content_description" msgid="6517068332106592887">"डेटा प्रयोग गर्ने गरी सेट गरिएन"</string>
     <string name="accessibility_no_phone" msgid="2687419663127582503">"फोन छैन्।"</string>
     <string name="accessibility_phone_one_bar" msgid="5719721147018970063">"फोन एउटा पट्टि।"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index e3be507..551097d 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimenteel) Linux-terminal uitvoeren op Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Als je dit uitzet, worden Linux-terminalgegevens gewist"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Extern apparaat"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Verbonden apparaat"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Deze telefoon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan niet afspelen op dit apparaat"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade het account om te schakelen"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan hier geen downloads afspelen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index ea6fdba..790acff 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(ପରୀକ୍ଷାମୂଳକ) Androidରେ Linux ଟର୍ମିନାଲ ଚଲାନ୍ତୁ"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ଯଦି ଆପଣ ଅକ୍ଷମ କରନ୍ତି, ତେବେ Linux ଟର୍ମିନାଲ ଡାଟା ଖାଲି ହୋଇଯିବ"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ଯାଞ୍ଚ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCPର ଯାଞ୍ଚ ଗତିବିଧି ସେଟ୍‍ କରନ୍ତୁ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ଡିବଗ୍‌ କରୁଛି"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"ଏକ୍ସଟର୍ନଲ ଡିଭାଇସ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"କନେକ୍ଟ କରାଯାଇଥିବା ଡିଭାଇସ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ଏହି ଫୋନ୍"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ଆନାଲଗ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ଅକ୍ସିଲାରି"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"ଏହି ଡିଭାଇସରେ ପ୍ଲେ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"ସ୍ୱିଚ କରିବା ପାଇଁ ଆକାଉଣ୍ଟକୁ ଅପଗ୍ରେଡ କରନ୍ତୁ"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ଏଠାରେ ଡାଉନଲୋଡଗୁଡ଼ିକୁ ପ୍ଲେ କରାଯାଇପାରିବ ନାହିଁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 8534051..c20e0d8 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(ਪ੍ਰਯੋਗਮਈ) Android \'ਤੇ Linux ਟਰਮੀਨਲ ਚਲਾਓ"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ਜੇ ਤੁਸੀਂ ਬੰਦ ਕਰਦੇ ਹੋ, ਤਾਂ Linux ਟਰਮੀਨਲ ਡਾਟਾ ਕਲੀਅਰ ਹੋ ਜਾਵੇਗਾ"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ਜਾਂਚ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ਜਾਂਚ ਵਿਵਹਾਰ ਸੈੱਟ ਕਰੋ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ਡੀਬੱਗਿੰਗ"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"ਬਾਹਰੀ ਡੀਵਾਈਸ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"ਕਨੈਕਟ ਕੀਤਾ ਡੀਵਾਈਸ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ਇਹ ਫ਼ੋਨ"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ਐਨਾਲੌਗ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਨਹੀਂ ਚਲਾਇਆ ਜਾ ਸਕਦਾ"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"ਸਵਿੱਚ ਕਰਨ ਲਈ ਖਾਤੇ ਨੂੰ ਅੱਪਗ੍ਰੇਡ ਕਰੋ"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ਡਾਊਨਲੋਡਾਂ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਚਲਾਇਆ ਜਾ ਸਕਦਾ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index a9d4dcb..f6ab8a7 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Wersja eksperymentalna) Uruchom terminal Linuxa na Androidzie"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jeśli wyłączysz tę funkcję, dane terminala Linuxa będą usunięte"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Urządzenie zewnętrzne"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Połączone urządzenie"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ten telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogowe"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nie można odtworzyć na tym urządzeniu"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Aby przełączyć, potrzebujesz konta premium"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tutaj nie można odtworzyć pobranych plików"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index eac646f..dedc65c 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executar terminal Linux no Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se desativar o app, os dados do terminal Linux serão removidos"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Neste telefone"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Faça upgrade da conta para trocar"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Não é possível abrir os downloads aqui"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index d8d172d..f1ac88b 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executar terminal do Linux no Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se desativar a app, os dados do terminal do Linux são limpos"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo associado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telemóvel"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Atualize a conta para mudar"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Não é possível reproduzir as transferências aqui"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index eac646f..dedc65c 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executar terminal Linux no Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se desativar o app, os dados do terminal Linux serão removidos"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Neste telefone"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Faça upgrade da conta para trocar"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Não é possível abrir os downloads aqui"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index d507b85..cafb788 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Rulează terminalul Linux pe Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Dacă dezactivezi, datele terminalului Linux vor fi șterse"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispozitiv extern"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispozitiv conectat"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Acest telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogic"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nu se poate reda pe acest dispozitiv"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Fă upgrade contului pentru a comuta"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Aici nu se pot reda descărcări"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 8d07c57..951f3a0 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"Запустить терминал Linux в Android (экспериментальная функция)"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Если отключить эту функцию, данные терминала Linux будут удалены"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Порядок проверки HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Отладка"</string>
@@ -584,19 +585,16 @@
     <string name="time_unit_just_now" msgid="3006134267292728099">"Только что"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Этот смартфон"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Этот планшет"</string>
-    <string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Встроенный динамик компьютера"</string>
+    <string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Встроенное"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
     <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Колонка с док-станцией"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Внешнее устройство"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Подключенное устройство"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Этот смартфон"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналоговый выход"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Невозможно воспроизвести на этом устройстве."</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Для переключения требуется премиум-аккаунт"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Не удается воспроизвести скачанные файлы"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 6694bc5..8427064 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -237,7 +237,7 @@
     <string name="choose_profile" msgid="343803890897657450">"පැතිකඩ තෝරන්න"</string>
     <string name="category_personal" msgid="6236798763159385225">"පෞද්ගලික"</string>
     <string name="category_work" msgid="4014193632325996115">"කාර්යාලය"</string>
-    <string name="category_private" msgid="4244892185452788977">"පෞද්ගලික"</string>
+    <string name="category_private" msgid="4244892185452788977">"රහසිගත"</string>
     <string name="category_clone" msgid="1554511758987195974">"ක්ලෝන කරන්න"</string>
     <string name="development_settings_title" msgid="140296922921597393">"වර්ධක විකල්ප"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"සංවර්ධක විකල්ප සබල කිරීම"</string>
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(පර්යේෂණාත්මක) Android මත Linux ටර්මිනලය ධාවනය කරන්න"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ඔබ අබල කරන්නේ නම්, Linux ටර්මිනල් දත්ත හිස් වනු ඇත"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP පරික්ෂාව"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP පරික්ෂා හැසිරීම සකසන්න"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"නිදොස්කරණය"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"බාහිර උපාංගය"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"සම්බන්ධ කළ උපාංගය"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"මෙම දුරකථනය"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ප්‍රතිසමය"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"මෙම උපාංගය මත ධාවනය කළ නොහැක"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"මාරු වීමට ගිණුම උත්ශ්‍රේණි කරන්න"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"මෙහි බාගැනීම් වාදනය කළ නොහැක"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index fa525a2..aca07e5 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimentálne) Spúšťať terminál systému Linux v Androide"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ak túto možnosť vypnete, údaje terminálu systému Linux sa vymažú"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externé zariadenie"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Pripojené zariadenie"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefón"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógový"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"V tomto zariadení sa nedá prehrávať obsah"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Inovujte účet a prejdite naň"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tu sa nedajú prehrať stiahnuté súbory"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 9b426aa..00d93a6 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Preizkusno) Zagon terminala Linux v Androidu"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Če to onemogočite, bodo podatki terminala Linux izbrisani."</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Zunanja naprava"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Povezana naprava"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ta telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogno"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ni mogoče predvajati v tej napravi."</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Za preklop je potrebna nadgradnja računa"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Prenosov tu ni mogoče predvajati"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 73cc518..c907e22 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -358,7 +358,8 @@
     <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>
     <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambienti i zhvillimit për Linux"</string>
-    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Ekzekuto terminalin e Linux në Android"</string>
+    <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentale) Ekzekuto terminalin e Linux në Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Nëse e çaktivizon, të dhënat e terminalit të Linux do të pastrohen"</string>
     <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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Pajisja e jashtme"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Pajisja e lidhur"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ky telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoge"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nuk mund të luhet në këtë pajisje"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Përmirëso llogarinë për të ndryshuar"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Shkarkimet nuk mund të luhen këtu"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index d8003d7..65000e4 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Експериментално) Покрените Linux терминал на Android-у"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ако онемогућите, подаци Linux терминала се бришу"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP провера"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Подешавање понашања HDCP провере"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Отклањање грешака"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Спољни уређај"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Повезани уређај"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Овај телефон"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогни"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не можете да пустите на овом уређају"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Надоградите налог ради пребацивања"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Преузимања не могу да се пуштају овде"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index f9bd295..12c1729 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimentellt) Kör Linux-terminalen på Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Om du inaktiverar detta rensas data i Linux-terminalen"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Extern enhet"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Ansluten enhet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Den här telefonen"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan inte spelas på denna enhet"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Uppgradera kontot för att byta"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Det går inte att spela upp nedladdningar här"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index b86be31..1bf5677 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Ya majaribio) Tumia temino ya Linux kwenye Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ukizima, data ya kituo cha Linux itafutwa"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Kifaa cha Nje"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Kifaa kilichounganishwa"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Simu hii"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogi"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Huwezi kucheza maudhui kwenye kifaa hiki"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Pata toleo jipya la akaunti ili ubadilishe"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Imeshindwa kucheza maudhui yaliyopakuliwa hapa"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 1fd78d3..8ee8fa2 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(பரிசோதனை) Androidடில் Linux டெர்மினலை இயக்கலாம்"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"நீங்கள் முடக்கினால், Linux டெர்மினல் தரவு அழிக்கப்படும்"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP சரிபார்ப்பு"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP சரிபார்க்கும் செயல்பாடுகளை அமை"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"பிழைதிருத்தம்"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"வெளிப்புறச் சாதனம்"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"இணைக்கப்பட்டுள்ள சாதனம்"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"இந்த மொபைல்"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"அனலாக்"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"இந்தச் சாதனத்தில் பிளே செய்ய முடியவில்லை"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"மாற்ற, கணக்கை மேம்படுத்துங்கள்"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"பதிவிறக்கங்களை இங்கே பிளே செய்ய முடியாது"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index fc45d2c..46350d5 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(ప్రయోగాత్మకం) Linux టెర్మినల్‌ను Androidలో రన్ చేయండి"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"మీరు డిజేబుల్ చేస్తే, Linux టెర్మినల్ డేటా క్లియర్ అవుతుంది"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP చెకింగ్‌"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP తనిఖీ ప్రవర్తనను సెట్ చేయండి"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"డీబగ్గింగ్"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"ఎక్స్‌టర్నల్ పరికరం"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"కనెక్ట్ చేసిన పరికరం"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ఈ ఫోన్"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"అనలాగ్"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"ఈ పరికరంలో ప్లే చేయడం సాధ్యపడదు"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"మారడానికి ఖాతాను అప్‌గ్రేడ్ చేయండి"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ఇక్కడ డౌన్‌లోడ్‌లను ప్లే చేయడం సాధ్యపడదు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index d525bc5..460782a 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(ทดลอง) เรียกใช้เทอร์มินัล Linux ใน Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"หากปิดใช้ ระบบจะล้างข้อมูลเทอร์มินัล Linux"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"การตรวจสอบ HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"ตั้งค่าการตรวจสอบ HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"การแก้ไขข้อบกพร่อง"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"อุปกรณ์ภายนอก"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"อุปกรณ์ที่เชื่อมต่อ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"โทรศัพท์เครื่องนี้"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"แอนะล็อก"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"เล่นในอุปกรณ์นี้ไม่ได้"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"อัปเกรดบัญชีเพื่อเปลี่ยน"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"เล่นเนื้อหาที่ดาวน์โหลดที่นี่ไม่ได้"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 1df7473..986b7771 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Pang-eksperimento) Patakbuhin ang terminal ng Linux sa Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Kung idi-disable mo, maki-clear ang data ng terminal ng Linux"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"External na Device"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Nakakonektang device"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ang teleponong ito"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Hindi ma-play sa device na ito"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"I-upgrade ang account para lumipat"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Hindi mape-play ang mga download dito"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index d622696..df47dac 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Deneysel) Android\'de Linux terminali çalıştırın"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Devre dışı bırakırsanız Linux terminali verileri temizlenir"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Harici Cihaz"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Bağlı cihaz"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Bu telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu cihazda oynatılamıyor"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Geçiş yapmak için hesabı yükseltin"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"İndirilenler burada oynatılamaz"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index eb10cb2..3ba99a2 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Експериментальна функція) Запуск термінала Linux на Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Якщо вимкнути, дані термінала Linux буде видалено"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Перевірка HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Порядок перевірки HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Налагодження"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Зовнішній пристрій"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Підключений пристрій"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Цей телефон"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналоговий"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не можна відтворювати тут"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Потрібний платний обліковий запис"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Завантаження не відтворюватимуться"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 8b2eb3f..e5e29fa 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -237,7 +237,7 @@
     <string name="choose_profile" msgid="343803890897657450">"پروفائل منتخب کریں"</string>
     <string name="category_personal" msgid="6236798763159385225">"ذاتی"</string>
     <string name="category_work" msgid="4014193632325996115">"دفتر"</string>
-    <string name="category_private" msgid="4244892185452788977">"نجی"</string>
+    <string name="category_private" msgid="4244892185452788977">"پرائیویٹ"</string>
     <string name="category_clone" msgid="1554511758987195974">"کلون کریں"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ڈویلپر کے اختیارات"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ڈویلپر کے اختیارات فعال کریں"</string>
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"‏(تجرباتی) Android پر Linux ٹرمینل چلائیں"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"‏اگر آپ غیر فعال کرتے ہیں تو Linux ٹرمینل کا ڈیٹا صاف ہو جائے گا"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"‏HDCP چیکنگ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏HDCP چیکنگ برتاؤ سیٹ کریں"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ڈیبگ کرنا"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"بیرونی آلہ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"منسلک آلہ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"یہ فون"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"اینالاگ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"اس آلے پر چلایا نہیں جا سکتا"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"سوئچ کرنے کے لیے اکاؤنٹ اپ گریڈ کریں"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ڈاؤن لوڈز کو یہاں چلایا نہیں جا سکتا"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 62a6303..2417d55 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Tajribaviy) Linux terminalini Android tizimida ishga tushiring"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Agar faolsizlantirsangiz, Linux terminal maʼlumotlari tozalanadi"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Tashqi qurilma"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Ulangan qurilma"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Shu telefon"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu qurilmada ijro etilmaydi"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Oʻtish uchun hisobingizni yangilang"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Yuklab olingan fayllar ijro etilmaydi"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 1b90818..0239a3f 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Thử nghiệm) Chạy cửa sổ dòng lệnh Linux trên Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Nếu bạn tắt, dữ liệu trên cửa sổ dòng lệnh Linux sẽ bị xoá"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Thiết bị bên ngoài"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Thiết bị đã kết nối"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Điện thoại này"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Không phát được trên thiết bị này"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nâng cấp tài khoản để chuyển đổi"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Không thể phát các tệp đã tải xuống tại đây"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 9491565..22bfda4 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(实验性)在 Android 上运行 Linux 终端"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"如果您停用它,Linux 终端数据会被清除"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 检查"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"设置 HDCP 检查行为"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"调试"</string>
@@ -490,7 +491,7 @@
     <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"根据您的使用情况,估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by" msgid="4113180890060388350">"目前电量为 <xliff:g id="LEVEL">%2$s</xliff:g>,估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only" msgid="92545648425937000">"估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharge_by_only_short" msgid="5883041507426914446">"可以用到 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_only_short" msgid="5883041507426914446">"可用到 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"电池电量可能在<xliff:g id="TIME">%1$s</xliff:g> 前耗尽"</string>
     <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
     <string name="power_remaining_less_than_duration" msgid="318215464914990578">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部设备"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"连接的设备"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"这部手机"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"模拟"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"辅助"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"无法在此设备上播放"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"升级账号后才能切换"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"无法在此设备上播放下载的内容"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index aa3ac06..594273a 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(實驗性質) 在 Android 上執行 Linux 終端機"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"停用將清除 Linux 終端機資料"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 檢查"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"設定 HDCP 檢查行為"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"除錯"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部裝置"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"已連接的裝置"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"這部手機"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"類比"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"無法在此裝置上播放"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"請升級要切換的帳戶"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"無法在此播放下載內容"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index b5eb87d..483dbf3 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(實驗功能) 在 Android 上執行 Linux 終端機"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"如果停用,系統會清除 Linux 終端機資料"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 檢查"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"設定 HDCP 檢查行為"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"偵錯"</string>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部裝置"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"已連結的裝置"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"這支手機"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"類比"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"無法在這部裝置上播放"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"請升級要切換的帳戶"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"這裡無法播放下載內容"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 57e0b8d..2bb3f22 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -358,7 +358,8 @@
     <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="enable_linux_terminal_summary" msgid="2029479880888108902">"(Ukuhlola) Qalisa itheminali yeLinux ku-Android"</string>
+    <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Uma ukhubazekile, idatha egciniwe yeLinux izosuswa"</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>
@@ -591,12 +592,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Idivayisi Yangaphandle"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Idivayisi exhunyiwe"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Le foni"</string>
-    <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
-    <skip />
-    <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
-    <skip />
-    <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
-    <skip />
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"I-S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"I-Analog"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"I-AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ayikwazi ukudlala kule divayisi"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Thuthukisa i-akhawunti ukuze ushintshe"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Awukwazi ukudlala okudawunilodiwe lapha"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index f03014c..eaf155d 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1419,7 +1419,7 @@
     <!-- Name of the internal speaker and mic. [CHAR LIMIT=30] -->
     <string name="media_transfer_this_device_name_desktop">This computer (internal)</string>
     <!-- Name of the default media output of the TV. [CHAR LIMIT=30] -->
-    <string name="media_transfer_this_device_name_tv">@string/tv_media_transfer_default</string>
+    <string name="media_transfer_this_device_name_tv">This TV</string>
     <!-- Name of the dock device. [CHAR LIMIT=30] -->
     <string name="media_transfer_dock_speaker_device_name">Dock speaker</string>
     <!-- Default name of the external device. [CHAR LIMIT=30] -->
@@ -1462,12 +1462,11 @@
     <!-- Media output switcher. Subtitle for devices connected through HDMI EARC if a device name is available. [CHAR LIMIT=NONE] -->
     <string name="tv_media_transfer_earc_subtitle">Connected via eARC</string>
 
-    <!-- TV media output switcher. Title for the default audio output of the device [CHAR LIMIT=NONE] -->
-    <string name="tv_media_transfer_default">TV default</string>
-    <!-- TV media output switcher. Subtitle for default audio output which is HDMI, e.g. TV dongle [CHAR LIMIT=NONE] -->
-    <string name="tv_media_transfer_hdmi">HDMI output</string>
-    <!-- TV media output switcher. Subtitle for default audio output which is internal speaker, i.e. panel VTs [CHAR LIMIT=NONE] -->
-    <string name="tv_media_transfer_internal_speakers">Internal speakers</string>
+    <!-- TV media output switcher. Subtitle for default audio output which is internal speaker [CHAR LIMIT=NONE] -->
+    <string name="tv_media_transfer_internal_speakers">Built-in speaker</string>
+
+    <!-- TV media output switcher. Title for default audio output which is HDMI, e.g. TV dongle [CHAR LIMIT=NONE] -->
+    <string name="tv_media_transfer_hdmi_title">TV Audio</string>
 
     <!-- Warning message to tell user is have problem during profile connect, it need to turn off device and back on. [CHAR_LIMIT=NONE] -->
     <string name="profile_connect_timeout_subtext">Problem connecting. Turn device off &amp; back on</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppIconCacheManager.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppIconCacheManager.java
index c0117b9..30ce13b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/AppIconCacheManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppIconCacheManager.java
@@ -22,6 +22,7 @@
 import android.util.Log;
 import android.util.LruCache;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
 /**
@@ -33,7 +34,7 @@
     @VisibleForTesting
     static final int MAX_CACHE_SIZE_IN_KB = getMaxCacheInKb();
     private static final String DELIMITER = ":";
-    private static AppIconCacheManager sAppIconCacheManager;
+    private static volatile AppIconCacheManager sAppIconCacheManager;
     private final LruCache<String, Drawable> mDrawableCache;
 
     private AppIconCacheManager() {
@@ -52,11 +53,18 @@
     /**
      * Get an {@link AppIconCacheManager} instance.
      */
-    public static synchronized AppIconCacheManager getInstance() {
-        if (sAppIconCacheManager == null) {
-            sAppIconCacheManager = new AppIconCacheManager();
+    public static @NonNull AppIconCacheManager getInstance() {
+        AppIconCacheManager result = sAppIconCacheManager;
+        if (result == null) {
+            synchronized (AppIconCacheManager.class) {
+                result = sAppIconCacheManager;
+                if (result == null) {
+                    result = new AppIconCacheManager();
+                    sAppIconCacheManager = result;
+                }
+            }
         }
-        return sAppIconCacheManager;
+        return result;
     }
 
     /**
@@ -118,7 +126,7 @@
      *
      * @see android.content.ComponentCallbacks2#onTrimMemory(int)
      */
-    public void trimMemory(int level) {
+    public static void trimMemory(int level) {
         if (level >= android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
             // Time to clear everything
             if (sAppIconCacheManager != null) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
index b3e48b2..fa28cf6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
@@ -94,6 +94,14 @@
     boolean setSubDeviceIfNeeded(CachedBluetoothDevice newDevice) {
         final long hiSyncId = newDevice.getHiSyncId();
         if (isValidHiSyncId(hiSyncId)) {
+            // The remote device supports CSIP, the other ear should be processed as a member
+            // device. Ignore hiSyncId grouping from ASHA here.
+            if (newDevice.getProfiles().stream().anyMatch(
+                    profile -> profile instanceof CsipSetCoordinatorProfile)) {
+                Log.w(TAG, "Skip ASHA grouping since this device supports CSIP");
+                return false;
+            }
+
             final CachedBluetoothDevice hearingAidDevice = getCachedDevice(hiSyncId);
             // Just add one of the hearing aids from a pair in the list that is shown in the UI.
             // Once there is another device with the same hiSyncId, to add new device as sub
@@ -161,6 +169,7 @@
             // device. Ignore hiSyncId grouping from ASHA here.
             if (cachedDevice.getProfiles().stream().anyMatch(
                     profile -> profile instanceof CsipSetCoordinatorProfile)) {
+                Log.w(TAG, "Skip ASHA grouping since this device supports CSIP");
                 continue;
             }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastCallbackExt.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastCallbackExt.kt
index 07abb6b..888f54f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastCallbackExt.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastCallbackExt.kt
@@ -69,8 +69,8 @@
             }
             .buffer(capacity = Channel.CONFLATED)
 
-/** [Flow] for [BluetoothLeBroadcast.Callback] onPlaybackStarted event */
-val LocalBluetoothLeBroadcast.onPlaybackStarted: Flow<Unit>
+/** [Flow] for [BluetoothLeBroadcast.Callback] onBroadcastMetadataChanged event */
+val LocalBluetoothLeBroadcast.onBroadcastMetadataChanged: Flow<Unit>
     get() =
         callbackFlow {
             val listener =
@@ -87,7 +87,6 @@
                     }
 
                     override fun onPlaybackStarted(reason: Int, broadcastId: Int) {
-                        launch { trySend(Unit) }
                     }
 
                     override fun onPlaybackStopped(reason: Int, broadcastId: Int) {
@@ -100,7 +99,9 @@
                     override fun onBroadcastMetadataChanged(
                         broadcastId: Int,
                         metadata: BluetoothLeBroadcastMetadata
-                    ) {}
+                    ) {
+                        trySend(Unit)
+                    }
                 }
             registerServiceCallBack(
                 ConcurrentUtils.DIRECT_EXECUTOR,
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java b/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java
index 717a8ee..aa2ede31 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java
@@ -33,6 +33,8 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
 import android.media.MediaRoute2Info;
 import android.os.SystemProperties;
 import android.util.SparseIntArray;
@@ -116,14 +118,15 @@
 
     @SuppressLint("SwitchIntDef")
     @DrawableRes
-    private static int getIconResourceIdForTv(@MediaRoute2Info.Type int type) {
+    private int getIconResourceIdForTv(@MediaRoute2Info.Type int type) {
         return switch (type) {
             case MediaRoute2Info.TYPE_USB_DEVICE, MediaRoute2Info.TYPE_USB_HEADSET ->
                     R.drawable.ic_headphone;
             case MediaRoute2Info.TYPE_USB_ACCESSORY -> R.drawable.ic_usb;
             case MediaRoute2Info.TYPE_DOCK -> R.drawable.ic_dock_device;
-            case MediaRoute2Info.TYPE_HDMI, MediaRoute2Info.TYPE_BUILTIN_SPEAKER ->
-                    R.drawable.ic_tv;
+            case MediaRoute2Info.TYPE_BUILTIN_SPEAKER ->
+                    isPanelTv() ? R.drawable.ic_tv : R.drawable.ic_tv_box_internal_speaker;
+            case MediaRoute2Info.TYPE_HDMI -> R.drawable.ic_tv;
             case MediaRoute2Info.TYPE_HDMI_ARC, MediaRoute2Info.TYPE_HDMI_EARC ->
                     R.drawable.ic_hdmi;
             case MediaRoute2Info.TYPE_WIRED_HEADSET, MediaRoute2Info.TYPE_WIRED_HEADPHONES ->
@@ -132,6 +135,23 @@
         };
     }
 
+    private boolean isPanelTv() {
+        if (mContext == null) {
+            // This should only happen during testing.
+            return true;
+        }
+        AudioManager audioManager = mContext.getSystemService(AudioManager.class);
+        AudioDeviceInfo[] devices = audioManager.getDevices(
+                AudioManager.GET_DEVICES_OUTPUTS);
+        // If we have an HDMI output (not ARC/eARC) we can assume it's a dongle / set top box.
+        for (AudioDeviceInfo device : devices) {
+            if (device.getType() == TYPE_HDMI) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     static {
         AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_USB_DEVICE, MediaRoute2Info.TYPE_USB_DEVICE);
         AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_USB_HEADSET, MediaRoute2Info.TYPE_USB_HEADSET);
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 2321097..b01b7c9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -390,6 +390,16 @@
     }
 
     /**
+     * Get the {@link MediaRoute2Info.Type} of the device.
+     */
+    public int getRouteType() {
+        if (mRouteInfo == null) {
+            return TYPE_UNKNOWN;
+        }
+        return mRouteInfo.getType();
+    }
+
+    /**
      * Checks if route's volume is fixed, if true, we should disable volume control for the device.
      *
      * @return route for this device is fixed.
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index 4766a86..6ff1a99 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -29,6 +29,7 @@
 import static android.media.MediaRoute2Info.TYPE_LINE_DIGITAL;
 import static android.media.MediaRoute2Info.TYPE_LINE_ANALOG;
 import static android.media.MediaRoute2Info.TYPE_AUX_LINE;
+
 import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER;
 
 import android.Manifest;
@@ -40,6 +41,7 @@
 import android.hardware.hdmi.HdmiPortInfo;
 import android.media.MediaRoute2Info;
 import android.media.RouteListingPreference;
+import android.os.Build;
 import android.os.SystemProperties;
 import android.util.Log;
 
@@ -72,7 +74,7 @@
     /** Returns this device name for media transfer. */
     public static @NonNull String getMediaTransferThisDeviceName(@NonNull Context context) {
         if (isTv(context)) {
-            return context.getString(R.string.media_transfer_this_device_name_tv);
+            return Build.MODEL;
         } else if (isTablet()) {
             return context.getString(R.string.media_transfer_this_device_name_tablet);
         } else if (inputRoutingEnabledAndIsDesktop(context)) {
@@ -110,7 +112,7 @@
                 name = getMediaTransferThisDeviceName(context);
                 break;
             case TYPE_HDMI:
-                name = context.getString(isTv ? R.string.tv_media_transfer_default :
+                name = context.getString(isTv ? R.string.tv_media_transfer_hdmi_title :
                         R.string.media_transfer_external_device_name);
                 break;
             case TYPE_HDMI_ARC:
@@ -223,8 +225,6 @@
         switch (mRouteInfo.getType()) {
             case TYPE_BUILTIN_SPEAKER:
                 return mContext.getString(R.string.tv_media_transfer_internal_speakers);
-            case TYPE_HDMI:
-                return mContext.getString(R.string.tv_media_transfer_hdmi);
             case TYPE_HDMI_ARC:
                 if (getHdmiOutDeviceName(mContext) == null) {
                     // Connection type is already part of the title.
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppIconCacheManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppIconCacheManagerTest.java
index 1b0e1f1..013ff92 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppIconCacheManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppIconCacheManagerTest.java
@@ -16,11 +16,14 @@
 
 package com.android.settingslib.applications;
 
+import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.doReturn;
 
 import android.graphics.drawable.Drawable;
+import android.util.Log;
 
 import org.junit.After;
 import org.junit.Before;
@@ -30,9 +33,12 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 @RunWith(RobolectricTestRunner.class)
 public class AppIconCacheManagerTest {
 
+    private static final String TAG = "AppIconCacheManagerTest";
     private static final String APP_PACKAGE_NAME = "com.test.app";
     private static final String APP_PACKAGE_NAME1 = "com.test.app1";
     private static final String APP_PACKAGE_NAME2 = "com.test.app2";
@@ -176,4 +182,28 @@
         assertThat(mAppIconCacheManager.get(APP_PACKAGE_NAME2, APP_UID)).isNull();
         assertThat(mAppIconCacheManager.get(APP_PACKAGE_NAME3, APP_UID)).isNull();
     }
+
+    @Test
+    public void trimMemory_multiThread_shouldNotCrash() {
+        int numberOfTasks = 10;
+        AtomicInteger completedTasks = new AtomicInteger(0);
+
+        Runnable task =
+                () -> {
+                    String threadName = Thread.currentThread().getName();
+                    Log.i(TAG, "Starting thread: " + threadName);
+                    AppIconCacheManager.getInstance().trimMemory(TRIM_MEMORY_BACKGROUND);
+                    completedTasks.incrementAndGet();
+                    Log.i(TAG, "Ending thread: " + threadName);
+                };
+
+        for (Integer i = 0; i < numberOfTasks; i++) {
+            Thread thread = new Thread(task);
+            thread.start();
+        }
+
+        while (completedTasks.get() < numberOfTasks) {
+            // Wait until all threads are finished.
+        }
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java
index 883640d..5ac22a7 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java
@@ -173,7 +173,7 @@
     public void getIconResIdFromMediaRouteType_tv_builtinSpeaker_isTv() {
         assertThat(new DeviceIconUtil(/* isTv */ true)
                 .getIconResIdFromMediaRouteType(MediaRoute2Info.TYPE_BUILTIN_SPEAKER))
-                .isEqualTo(R.drawable.ic_tv);
+                .isAnyOf(R.drawable.ic_tv, R.drawable.ic_tv_box_internal_speaker);
     }
 
     @Test
@@ -331,7 +331,7 @@
     public void getIconResIdFromAudioDeviceType_tv_builtinSpeaker_isTv() {
         assertThat(new DeviceIconUtil(/* isTv */ true)
                 .getIconResIdFromAudioDeviceType(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER))
-                .isEqualTo(R.drawable.ic_tv);
+                .isAnyOf(R.drawable.ic_tv, R.drawable.ic_tv_box_internal_speaker);
     }
 
     @Test
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 927a1c59..1f291cd 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -107,6 +107,8 @@
         Settings.Secure.DISPLAY_WHITE_BALANCE_ENABLED,
         Settings.Secure.SYNC_PARENT_SOUNDS,
         Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
+        Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED,
+        Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
         Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
         Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
         // ACCESSIBILITY_QS_TARGETS needs to be restored after ENABLED_ACCESSIBILITY_SERVICES
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index 3530e0f..8e7180c 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -78,6 +78,7 @@
                 Settings.System.SHOW_WEB_SUGGESTIONS,
                 Settings.System.SIP_CALL_OPTIONS,
                 Settings.System.SIP_RECEIVE_CALLS,
+                Settings.System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION,
                 Settings.System.POINTER_SPEED,
                 Settings.System.POINTER_FILL_STYLE,
                 Settings.System.POINTER_STROKE_STYLE,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 6d73ee2..abd5b9a 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -160,6 +160,9 @@
         VALIDATORS.put(Secure.DISPLAY_WHITE_BALANCE_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.SYNC_PARENT_SOUNDS, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
+                new InclusiveIntegerRangeValidator(0, 1));
         VALIDATORS.put(Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.QS_TILES, TILE_LIST_VALIDATOR);
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 509b88b..cfc7743 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -213,6 +213,8 @@
         VALIDATORS.put(System.SIP_ADDRESS_ONLY, BOOLEAN_VALIDATOR);
         VALIDATORS.put(System.SIP_ASK_ME_EACH_TIME, BOOLEAN_VALIDATOR);
         VALIDATORS.put(System.POINTER_SPEED, new InclusiveFloatRangeValidator(-7, 7));
+        VALIDATORS.put(System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION,
+                NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(System.POINTER_FILL_STYLE,
                 new InclusiveIntegerRangeValidator(POINTER_ICON_VECTOR_STYLE_FILL_BEGIN,
                         POINTER_ICON_VECTOR_STYLE_FILL_END));
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/OWNERS b/packages/SettingsProvider/src/com/android/providers/settings/OWNERS
index 0b71816..b0086c1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/OWNERS
+++ b/packages/SettingsProvider/src/com/android/providers/settings/OWNERS
@@ -1 +1,2 @@
-per-file WritableNamespacePrefixes.java = cbrubaker@google.com,tedbauer@google.com
+per-file WritableNamespacePrefixes.java = mpgroover@google.com,tedbauer@google.com
+per-file WritableNamespaces.java = mpgroover@google.com,tedbauer@google.com
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index fb0aaf8..5ae11ba 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2124,6 +2124,15 @@
                 SecureSettingsProto.Display.SCREEN_RESOLUTION_MODE);
         p.end(displayToken);
 
+        final long doubleTapPowerButtonToken = p.start(SecureSettingsProto.DOUBLE_TAP_POWER_BUTTON);
+        dumpSetting(s, p,
+                Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED,
+                SecureSettingsProto.DoubleTapPowerButton.GESTURE_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
+                SecureSettingsProto.DoubleTapPowerButton.GESTURE);
+        p.end(doubleTapPowerButtonToken);
+
         final long dozeToken = p.start(SecureSettingsProto.DOZE);
         dumpSetting(s, p,
                 Settings.Secure.DOZE_ENABLED,
@@ -3037,6 +3046,9 @@
         dumpSetting(s, p,
                 Settings.System.TOUCHPAD_TAP_DRAGGING,
                 SystemSettingsProto.Touchpad.TAP_DRAGGING);
+        dumpSetting(s, p,
+                Settings.System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION,
+                SystemSettingsProto.Touchpad.THREE_FINGER_TAP_CUSTOMIZATION);
         p.end(touchpadToken);
 
         dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 03fea37..6128d45 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -130,10 +130,12 @@
 
 import libcore.util.HexEncoding;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -380,6 +382,8 @@
     @GuardedBy("mLock")
     private Handler mHandler;
 
+    private static final Set<String> sDeviceConfigAllowlistedNamespaces = new ArraySet<>();
+
     // We have to call in the user manager with no lock held,
     private volatile UserManager mUserManager;
 
@@ -2442,6 +2446,10 @@
         if (!isRestrictedShell && hasWritePermission) {
             assertCallingUserDenyList(flags);
         } else if (hasAllowlistPermission) {
+            Set<String> allowlistedDeviceConfigNamespaces = null;
+            if (isRestrictedShell) {
+                allowlistedDeviceConfigNamespaces = getAllowlistedDeviceConfigNamespaces();
+            }
             for (String flag : flags) {
                 boolean namespaceAllowed = false;
                 if (isRestrictedShell) {
@@ -2452,7 +2460,7 @@
                     } else {
                         flagNamespace = flag;
                     }
-                    if (WritableNamespaces.ALLOWLIST.contains(flagNamespace)) {
+                    if (allowlistedDeviceConfigNamespaces.contains(flagNamespace)) {
                         namespaceAllowed = true;
                     }
                 } else {
@@ -2513,6 +2521,60 @@
         }
     }
 
+    /**
+     * Returns a Set of DeviceConfig allowlisted namespaces in which all flags can be modified
+     * by a caller with the {@code WRITE_ALLOWLISTED_DEVICE_CONFIG} permission.
+     * <p>
+     * This method also supports mainline modules that introduce their own allowlisted
+     * namespaces within the {@code etc/writable_namespaces} file under their directory.
+     */
+    private Set<String> getAllowlistedDeviceConfigNamespaces() {
+        synchronized (sDeviceConfigAllowlistedNamespaces) {
+            if (!sDeviceConfigAllowlistedNamespaces.isEmpty()) {
+                return sDeviceConfigAllowlistedNamespaces;
+            }
+            if (android.provider.flags.Flags.deviceConfigWritableNamespacesApi()) {
+                sDeviceConfigAllowlistedNamespaces.addAll(DeviceConfig.getAdbWritableNamespaces());
+            } else {
+                sDeviceConfigAllowlistedNamespaces.addAll(WritableNamespaces.ALLOWLIST);
+            }
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                List<String> apexDirectories;
+                try {
+                    apexDirectories = mPackageManager.getAllApexDirectories();
+                } catch (RemoteException e) {
+                    Slog.e(LOG_TAG, "Caught a RemoteException obtaining APEX directories: ", e);
+                    return sDeviceConfigAllowlistedNamespaces;
+                }
+                for (int i = 0; i < apexDirectories.size(); i++) {
+                    String apexDirectory = apexDirectories.get(i);
+                    File namespaceFile = Environment.buildPath(new File(apexDirectory), "etc",
+                            "writable_namespaces");
+                    if (namespaceFile.exists() && namespaceFile.isFile()) {
+                        try (BufferedReader reader = new BufferedReader(
+                                new FileReader(namespaceFile))) {
+                            String namespace;
+                            while ((namespace = reader.readLine()) != null) {
+                                namespace = namespace.trim();
+                                // Support comments by ignoring any lines that start with '#'.
+                                if (!namespace.isEmpty() && !namespace.startsWith("#")) {
+                                    sDeviceConfigAllowlistedNamespaces.add(namespace);
+                                }
+                            }
+                        } catch (IOException e) {
+                            Slog.e(LOG_TAG, "Caught an exception parsing file: " + namespaceFile,
+                                    e);
+                        }
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+            return sDeviceConfigAllowlistedNamespaces;
+        }
+    }
+
     private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
             int targetSdkVersion, String name) {
         // If the app targets Lollipop MR1 or older SDK we warn, otherwise crash.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java b/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
index d835c5f..5ce97eb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
@@ -33,6 +33,16 @@
 final class WritableNamespaces {
     public static final Set<String> ALLOWLIST =
             new ArraySet<String>(Arrays.asList(
-                    "exo"
+                    "adservices",
+                    "captive_portal_login",
+                    "connectivity",
+                    "exo",
+                    "nearby",
+                    "netd_native",
+                    "network_security",
+                    "on_device_personalization",
+                    "tethering",
+                    "tethering_u_or_later_native",
+                    "thread_network"
             ));
 }
diff --git a/packages/Shell/Android.bp b/packages/Shell/Android.bp
index 3350efc..5f81085 100644
--- a/packages/Shell/Android.bp
+++ b/packages/Shell/Android.bp
@@ -27,6 +27,7 @@
     ],
     flags_packages: [
         "android.security.flags-aconfig",
+        "android.permission.flags-aconfig",
     ],
     platform_apis: true,
     certificate: "platform",
@@ -51,5 +52,6 @@
     manifest: "AndroidManifest.xml",
     flags_packages: [
         "android.security.flags-aconfig",
+        "android.permission.flags-aconfig",
     ],
 }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index b8b5ed8..0ec5571 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -151,7 +151,8 @@
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <uses-permission android:name="android.permission.LOCATION_BYPASS" />
     <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
-    <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
+    <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"
+        android:featureFlag="!android.security.protect_device_config_flags"/>
     <uses-permission android:name="android.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG" />
     <uses-permission android:name="android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG" />
     <uses-permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS" />
@@ -179,6 +180,7 @@
     <uses-permission android:name="android.permission.SET_ORIENTATION" />
     <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
     <uses-permission android:name="android.permission.INSTALL_PACKAGE_UPDATES" />
+    <uses-permission android:name="android.permission.INSTALL_DEPENDENCY_SHARED_LIBRARIES" />
     <uses-permission android:name="android.permission.ENFORCE_UPDATE_OWNERSHIP" />
     <uses-permission android:name="android.permission.INSTALL_DPC_PACKAGES" />
     <uses-permission android:name="com.android.permission.USE_INSTALLER_V2" />
@@ -937,7 +939,6 @@
 
     <!-- Permission required for CTS test - CtsPackageManagerTestCases-->
     <uses-permission android:name="android.permission.DOMAIN_VERIFICATION_AGENT" />
-    <uses-permission android:name="android.permission.VERIFICATION_AGENT" />
 
     <!-- Permission required for Cts test - CtsInputTestCases -->
     <uses-permission
@@ -956,7 +957,7 @@
     <!-- Permission required for CTS test - CtsNfcTestCases -->
     <uses-permission android:name="android.permission.NFC_SET_CONTROLLER_ALWAYS_ON" />
     <!-- Permission required for CTS test - AdvancedProtectionManagerTest -->
-    <uses-permission android:name="android.permission.SET_ADVANCED_PROTECTION_MODE"
+    <uses-permission android:name="android.permission.MANAGE_ADVANCED_PROTECTION_MODE"
         android:featureFlag="android.security.aapm_api"/>
     <uses-permission android:name="android.permission.QUERY_ADVANCED_PROTECTION_MODE"
         android:featureFlag="android.security.aapm_api"/>
@@ -974,13 +975,21 @@
     <!-- Permission required for CTS test - CtsTelephonyTestCases -->
     <uses-permission android:name="android.permission.READ_BASIC_PHONE_STATE" />
 
-    <!-- Permission required for ExecutableMethodFileOffsetsTest -->
+    <!-- Permission required for CTS test - CtsDynamicInstrumentationManagerTest -->
     <uses-permission android:name="android.permission.DYNAMIC_INSTRUMENTATION" />
 
     <!-- Permissions required for CTS test - SettingsPreferenceServiceClientTest -->
     <uses-permission android:name="android.permission.READ_SYSTEM_PREFERENCES" />
     <uses-permission android:name="android.permission.WRITE_SYSTEM_PREFERENCES" />
 
+    <!-- Permissions required for CTS test - ActivityManagerForegroundServiceTypeTest -->
+    <uses-permission android:name="android.permission.health.READ_HEART_RATE"
+        android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+    <uses-permission android:name="android.permission.health.READ_OXYGEN_SATURATION"
+        android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+    <uses-permission android:name="android.permission.health.READ_SKIN_TEMPERATURE"
+        android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+
     <application
         android:label="@string/app_label"
         android:theme="@android:style/Theme.DeviceDefault.DayNight"
diff --git a/packages/Shell/aconfig/wear.aconfig b/packages/Shell/aconfig/wear.aconfig
index e07bd96..d88fd46 100644
--- a/packages/Shell/aconfig/wear.aconfig
+++ b/packages/Shell/aconfig/wear.aconfig
@@ -5,5 +5,5 @@
     name: "handle_bugreports_for_wear"
     namespace: "wear_services"
     description: "This flag enables Shell to propagate bugreport results to WearServices."
-    bug: "378060870"
+    bug: "338029043"
 }
\ No newline at end of file
diff --git a/packages/StatementService/Android.bp b/packages/StatementService/Android.bp
index 90e1808..39b0302 100644
--- a/packages/StatementService/Android.bp
+++ b/packages/StatementService/Android.bp
@@ -38,8 +38,10 @@
         "StatementServiceParser",
         "androidx.appcompat_appcompat",
         "androidx.collection_collection-ktx",
+        "androidx.room_room-runtime",
         "androidx.work_work-runtime",
         "androidx.work_work-runtime-ktx",
         "kotlinx-coroutines-android",
     ],
+    plugins: ["androidx.room_room-compiler-plugin"],
 }
diff --git a/packages/StatementService/src/com/android/statementservice/database/Converters.kt b/packages/StatementService/src/com/android/statementservice/database/Converters.kt
new file mode 100644
index 0000000..21ecc8b
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/database/Converters.kt
@@ -0,0 +1,130 @@
+/*
+ * 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.statementservice.database
+
+import android.content.UriRelativeFilter
+import android.content.UriRelativeFilterGroup
+import android.util.JsonReader
+import androidx.room.TypeConverter
+import org.json.JSONArray
+import org.json.JSONObject
+import java.io.StringReader
+import java.util.ArrayList
+
+class Converters {
+    companion object {
+        private const val ACTION_NAME = "action"
+        private const val FILTERS_NAME = "filters"
+        private const val URI_PART_NAME = "uriPart"
+        private const val PATTERN_TYPE_NAME = "patternType"
+        private const val FILTER_NAME = "filter"
+    }
+
+    @TypeConverter
+    fun groupsToJson(groups: List<UriRelativeFilterGroup>): String {
+        val json = JSONArray()
+        for (group in groups) {
+            json.put(groupToJson(group))
+        }
+        return json.toString()
+    }
+
+    @TypeConverter
+    fun stringToGroups(json: String): List<UriRelativeFilterGroup> {
+        val groups = ArrayList<UriRelativeFilterGroup>()
+        StringReader(json).use { stringReader ->
+            JsonReader(stringReader).use { reader ->
+                reader.beginArray()
+                while (reader.hasNext()) {
+                    groups.add(parseGroup(reader))
+                }
+                reader.endArray()
+            }
+        }
+        return groups
+    }
+
+    private fun groupToJson(group: UriRelativeFilterGroup): JSONObject {
+        val jsonObject = JSONObject()
+        jsonObject.put(ACTION_NAME, group.action)
+        val filters = JSONArray()
+        for (filter in group.uriRelativeFilters) {
+            filters.put(filterToJson(filter))
+        }
+        jsonObject.put(FILTERS_NAME, filters)
+        return jsonObject
+    }
+
+    private fun filterToJson(filter: UriRelativeFilter): JSONObject {
+        val jsonObject = JSONObject()
+        jsonObject.put(URI_PART_NAME, filter.uriPart)
+        jsonObject.put(PATTERN_TYPE_NAME, filter.patternType)
+        jsonObject.put(FILTER_NAME, filter.filter)
+        return jsonObject
+    }
+
+    private fun parseGroup(reader: JsonReader): UriRelativeFilterGroup {
+        val jsonObject = JSONObject()
+        reader.beginObject()
+        while (reader.hasNext()) {
+            val name = reader.nextName()
+            when (name) {
+                ACTION_NAME -> jsonObject.put(ACTION_NAME, reader.nextInt())
+                FILTERS_NAME -> jsonObject.put(FILTERS_NAME, parseFilters(reader))
+                else -> reader.skipValue()
+            }
+        }
+        reader.endObject()
+
+        val group = UriRelativeFilterGroup(jsonObject.getInt(ACTION_NAME))
+        val filters = jsonObject.getJSONArray(FILTERS_NAME)
+        for (i in 0 until filters.length()) {
+            val filter = filters.getJSONObject(i)
+            group.addUriRelativeFilter(UriRelativeFilter(
+                filter.getInt(URI_PART_NAME),
+                filter.getInt(PATTERN_TYPE_NAME),
+                filter.getString(FILTER_NAME)
+            ))
+        }
+        return group
+    }
+
+    private fun parseFilters(reader: JsonReader): JSONArray {
+        val filters = JSONArray()
+        reader.beginArray()
+        while (reader.hasNext()) {
+            filters.put(parseFilter(reader))
+        }
+        reader.endArray()
+        return filters
+    }
+
+    private fun parseFilter(reader: JsonReader): JSONObject {
+        reader.beginObject()
+        val jsonObject = JSONObject()
+        while (reader.hasNext()) {
+            val name = reader.nextName()
+            when (name) {
+                URI_PART_NAME, PATTERN_TYPE_NAME -> jsonObject.put(name, reader.nextInt())
+                FILTER_NAME -> jsonObject.put(name, reader.nextString())
+                else -> reader.skipValue()
+            }
+        }
+        reader.endObject()
+        return jsonObject
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/StatementService/src/com/android/statementservice/database/DomainGroups.kt
similarity index 67%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/StatementService/src/com/android/statementservice/database/DomainGroups.kt
index 5a04169..c616669 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/StatementService/src/com/android/statementservice/database/DomainGroups.kt
@@ -14,8 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.statementservice.database
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+import android.content.UriRelativeFilterGroup
+import androidx.room.Entity
+
+@Entity(primaryKeys = ["packageName", "domain"])
+data class DomainGroups(
+    val packageName: String,
+    val domain: String,
+    val groups: List<UriRelativeFilterGroup>
+)
\ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDao.kt b/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDao.kt
new file mode 100644
index 0000000..3b4dcea
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDao.kt
@@ -0,0 +1,36 @@
+/*
+ * 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.statementservice.database
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.Query
+
+@Dao
+interface DomainGroupsDao {
+    @Query("SELECT * FROM DomainGroups WHERE packageName = :packageName")
+    fun getDomainGroups(packageName: String): List<DomainGroups>
+
+    @Insert
+    fun insertDomainGroups(vararg domainGroups: DomainGroups)
+
+    @Query("DELETE FROM DomainGroups WHERE packageName = :packageName AND domain = :domain")
+    fun clear(packageName: String, domain: String)
+
+    @Query("DELETE FROM DomainGroups WHERE packageName = :packageName")
+    fun clear(packageName: String)
+}
\ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDatabase.kt b/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDatabase.kt
new file mode 100644
index 0000000..39833f6
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDatabase.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.statementservice.database
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverters
+
+@Database(entities = [DomainGroups::class], version = 1)
+@TypeConverters(Converters::class)
+abstract class DomainGroupsDatabase : RoomDatabase() {
+    companion object {
+        private const val DATABASE_NAME = "domain-groups"
+        @Volatile
+        private var instance: DomainGroupsDatabase? = null
+
+        fun getInstance(context: Context) = instance ?: synchronized(this) {
+            instance ?: Room.databaseBuilder(
+                context,
+                DomainGroupsDatabase::class.java, DATABASE_NAME
+            ).build().also { instance = it }
+        }
+    }
+    abstract fun domainGroupsDao(): DomainGroupsDao
+}
\ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt b/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt
index acb54f6..0d7a1fd 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt
@@ -22,6 +22,7 @@
 import androidx.work.ExistingWorkPolicy
 import androidx.work.WorkManager
 import com.android.statementservice.domain.worker.CollectV1Worker
+import com.android.statementservice.domain.worker.GroupUpdateV1Worker
 import com.android.statementservice.domain.worker.SingleV1RequestWorker
 
 /**
@@ -67,7 +68,7 @@
             }
         }
 
-        //clear sp before enqueue unique work since policy is REPLACE
+        // clear sp before enqueue unique work since policy is REPLACE
         val deContext = context.createDeviceProtectedStorageContext()
         val editor = deContext?.getSharedPreferences(packageName, Context.MODE_PRIVATE)?.edit()
         editor?.clear()?.apply()
@@ -78,6 +79,7 @@
                 workRequests
             )
             .then(CollectV1Worker.buildRequest(verificationId, packageName))
+            .then(GroupUpdateV1Worker.buildRequest(packageName))
             .enqueue()
     }
 }
diff --git a/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt b/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt
index 29f844f..6914347 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt
@@ -24,6 +24,7 @@
 import com.android.statementservice.network.retriever.StatementRetriever
 import com.android.statementservice.retriever.AbstractAsset
 import com.android.statementservice.retriever.AbstractAssetMatcher
+import com.android.statementservice.retriever.Statement
 import com.android.statementservice.utils.Result
 import com.android.statementservice.utils.StatementUtils
 import com.android.statementservice.utils.component1
@@ -87,10 +88,10 @@
         host: String,
         packageName: String,
         network: Network? = null
-    ): Pair<WorkResult, VerifyStatus> {
+    ): Triple<WorkResult, VerifyStatus, Statement?> {
         val assetMatcher = synchronized(targetAssetCache) { targetAssetCache[packageName] }
             .takeIf { it!!.isPresent }
-            ?: return WorkResult.failure() to VerifyStatus.FAILURE_PACKAGE_MANAGER
+            ?: return Triple(WorkResult.failure(), VerifyStatus.FAILURE_PACKAGE_MANAGER, null)
         return verifyHost(host, assetMatcher.get(), network)
     }
 
@@ -98,34 +99,34 @@
         host: String,
         assetMatcher: AbstractAssetMatcher,
         network: Network? = null
-    ): Pair<WorkResult, VerifyStatus> {
+    ): Triple<WorkResult, VerifyStatus, Statement?> {
         var exception: Exception? = null
         val resultAndStatus = try {
             val sourceAsset = StatementUtils.createWebAssetString(host)
                 .let(AbstractAsset::create)
             val result = retriever.retrieve(sourceAsset, network)
-                ?: return WorkResult.success() to VerifyStatus.FAILURE_UNKNOWN
+                ?: return Triple(WorkResult.success(), VerifyStatus.FAILURE_UNKNOWN, null)
             when (result.responseCode) {
                 HttpURLConnection.HTTP_MOVED_PERM,
                 HttpURLConnection.HTTP_MOVED_TEMP -> {
-                    WorkResult.failure() to VerifyStatus.FAILURE_REDIRECT
+                    Triple(WorkResult.failure(), VerifyStatus.FAILURE_REDIRECT, null)
                 }
                 else -> {
-                    val isVerified = result.statements.any { statement ->
+                    val statement = result.statements.firstOrNull { statement ->
                         (StatementUtils.RELATION.matches(statement.relation) &&
                                 assetMatcher.matches(statement.target))
                     }
 
-                    if (isVerified) {
-                        WorkResult.success() to VerifyStatus.SUCCESS
+                    if (statement != null) {
+                        Triple(WorkResult.success(), VerifyStatus.SUCCESS, statement)
                     } else {
-                        WorkResult.failure() to VerifyStatus.FAILURE_REJECTED_BY_SERVER
+                        Triple(WorkResult.failure(), VerifyStatus.FAILURE_REJECTED_BY_SERVER, statement)
                     }
                 }
             }
         } catch (e: Exception) {
             exception = e
-            WorkResult.retry() to VerifyStatus.FAILURE_UNKNOWN
+            Triple(WorkResult.retry(), VerifyStatus.FAILURE_UNKNOWN, null)
         }
 
         if (DEBUG) {
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/BaseRequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/BaseRequestWorker.kt
index a17f9c9..64d2d98 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/BaseRequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/BaseRequestWorker.kt
@@ -17,9 +17,12 @@
 package com.android.statementservice.domain.worker
 
 import android.content.Context
+import android.content.UriRelativeFilterGroup
+import android.content.pm.verify.domain.DomainVerificationInfo
 import android.content.pm.verify.domain.DomainVerificationManager
 import androidx.work.CoroutineWorker
 import androidx.work.WorkerParameters
+import com.android.statementservice.database.DomainGroupsDatabase
 import com.android.statementservice.domain.DomainVerifier
 
 abstract class BaseRequestWorker(
@@ -27,8 +30,19 @@
     protected val params: WorkerParameters
 ) : CoroutineWorker(appContext, params) {
 
+    protected val database = DomainGroupsDatabase.getInstance(appContext).domainGroupsDao()
+
     protected val verificationManager =
         appContext.getSystemService(DomainVerificationManager::class.java)!!
 
     protected val verifier = DomainVerifier.getInstance(appContext)
+
+    protected fun updateUriRelativeFilterGroups(packageName: String, domainGroupUpdates: Map<String, List<UriRelativeFilterGroup>>) {
+        val verifiedDomains = verificationManager.getDomainVerificationInfo(packageName)?.hostToStateMap?.filterValues {
+            it == DomainVerificationInfo.STATE_SUCCESS || it == DomainVerificationInfo.STATE_MODIFIABLE_VERIFIED
+        }?.keys?.toList() ?: emptyList()
+        val domainGroups = verificationManager.getUriRelativeFilterGroups(packageName, verifiedDomains)
+        domainGroupUpdates.forEach { (domain, groups) -> domainGroups[domain] = groups }
+        verificationManager.setUriRelativeFilterGroups(packageName, domainGroups)
+    }
 }
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/GroupUpdateV1Worker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/GroupUpdateV1Worker.kt
new file mode 100644
index 0000000..f53dfc4
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/GroupUpdateV1Worker.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.statementservice.domain.worker
+
+import android.content.Context
+import androidx.work.Data
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.WorkerParameters
+import kotlinx.coroutines.coroutineScope
+
+class GroupUpdateV1Worker(appContext: Context, params: WorkerParameters) :
+    BaseRequestWorker(appContext, params) {
+
+    companion object {
+
+        private const val PACKAGE_NAME_KEY = "packageName"
+
+        fun buildRequest(packageName: String) = OneTimeWorkRequestBuilder<GroupUpdateV1Worker>()
+            .setInputData(
+                Data.Builder()
+                    .putString(PACKAGE_NAME_KEY, packageName)
+                    .build()
+            )
+            .build()
+    }
+
+    override suspend fun doWork() = coroutineScope {
+        val packageName = params.inputData.getString(PACKAGE_NAME_KEY)!!
+        updateUriRelativeFilterGroups(packageName)
+        Result.success()
+    }
+
+    private fun updateUriRelativeFilterGroups(packageName: String) {
+        val groupUpdates = database.getDomainGroups(packageName)
+        updateUriRelativeFilterGroups(
+            packageName,
+            groupUpdates.associateBy({it.domain}, {it.groups})
+        )
+        database.clear(packageName)
+    }
+}
\ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt
index 61ab2c2..f83601a 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt
@@ -17,10 +17,13 @@
 package com.android.statementservice.domain.worker
 
 import android.content.Context
+import android.content.UriRelativeFilterGroup
+import android.content.pm.verify.domain.DomainVerificationManager
 import androidx.work.NetworkType
 import androidx.work.WorkerParameters
 import com.android.statementservice.domain.VerifyStatus
 import com.android.statementservice.utils.AndroidUtils
+import com.android.statementservice.utils.StatementUtils
 import kotlinx.coroutines.async
 import kotlinx.coroutines.awaitAll
 import kotlinx.coroutines.coroutineScope
@@ -36,7 +39,13 @@
     params: WorkerParameters
 ) : BaseRequestWorker(appContext, params) {
 
-    data class VerifyResult(val domainSetId: UUID, val host: String, val status: VerifyStatus)
+    data class VerifyResult(
+        val domainSetId: UUID,
+        val host: String,
+        val status: VerifyStatus,
+        val packageName: String,
+        val groups: List<UriRelativeFilterGroup>
+    )
 
     override suspend fun doWork() = coroutineScope {
         if (!AndroidUtils.isReceiverV2Enabled(appContext)) {
@@ -49,8 +58,11 @@
             .map { (domainSetId, packageName, host) ->
                 async {
                     if (isActive && !isStopped) {
-                        val (_, status) = verifier.verifyHost(host, packageName, params.network)
-                        VerifyResult(domainSetId, host, status)
+                        val (_, status, statement) = verifier.verifyHost(host, packageName, params.network)
+                        val groups = statement?.dynamicAppLinkComponents.orEmpty().map {
+                            StatementUtils.createUriRelativeFilterGroup(it)
+                        }
+                        VerifyResult(domainSetId, host, status, packageName, groups)
                     } else {
                         // If the job gets cancelled, stop the remaining hosts, but continue the
                         // job to commit the results for hosts that were already requested.
@@ -60,17 +72,25 @@
             }
             .awaitAll()
             .filterNotNull() // TODO(b/159952358): Fast fail packages which can't be retrieved.
-            .groupBy { it.domainSetId }
-            .forEach { (domainSetId, resultsById) ->
-                resultsById.groupBy { it.status }
-                    .mapValues { it.value.map(VerifyResult::host).toSet() }
-                    .forEach { (status, hosts) ->
-                        verificationManager.setDomainVerificationStatus(
-                            domainSetId,
-                            hosts,
-                            status.value
-                        )
+            .groupBy { it.packageName }
+            .forEach { (packageName, resultsByName) ->
+                val groupUpdates = mutableMapOf<String, List<UriRelativeFilterGroup>>()
+                resultsByName.groupBy { it.domainSetId }
+                    .forEach { (domainSetId, resultsById) ->
+                        resultsById.groupBy { it.status }
+                            .forEach { (status, verifyResults) ->
+                                val error = verificationManager.setDomainVerificationStatus(
+                                    domainSetId,
+                                    verifyResults.map(VerifyResult::host).toSet(),
+                                    status.value
+                                )
+                                if (error == DomainVerificationManager.STATUS_OK
+                                    && status == VerifyStatus.SUCCESS) {
+                                    verifyResults.forEach { groupUpdates[it.host] = it.groups }
+                                }
+                            }
                     }
+                updateUriRelativeFilterGroups(packageName, groupUpdates)
             }
 
         // Succeed regardless of results since this retry is best effort and not required
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt
index 7a198cb..253a162 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt
@@ -22,7 +22,9 @@
 import androidx.work.OneTimeWorkRequest
 import androidx.work.OneTimeWorkRequestBuilder
 import androidx.work.WorkerParameters
+import com.android.statementservice.database.DomainGroups
 import com.android.statementservice.utils.AndroidUtils
+import com.android.statementservice.utils.StatementUtils
 import kotlinx.coroutines.coroutineScope
 
 class SingleV1RequestWorker(appContext: Context, params: WorkerParameters) :
@@ -60,7 +62,9 @@
         val packageName = params.inputData.getString(PACKAGE_NAME_KEY)!!
         val host = params.inputData.getString(HOST_KEY)!!
 
-        val (result, status) = verifier.verifyHost(host, packageName, params.network)
+        database.clear(packageName, host)
+
+        val (result, status, statement) = verifier.verifyHost(host, packageName, params.network)
 
         if (DEBUG) {
             Log.d(
@@ -75,6 +79,10 @@
                 val deContext = appContext.createDeviceProtectedStorageContext()
                 val sp = deContext?.getSharedPreferences(packageName, Context.MODE_PRIVATE)
                 sp?.edit()?.putInt("$HOST_SUCCESS_PREFIX$host", status.value)?.apply()
+                val groups = statement?.dynamicAppLinkComponents.orEmpty().map {
+                    StatementUtils.createUriRelativeFilterGroup(it)
+                }
+                database.insertDomainGroups(DomainGroups(packageName, host, groups))
                 Result.success()
             }
             is Result.Failure -> {
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV2RequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV2RequestWorker.kt
index 562b132..8b1347a 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV2RequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV2RequestWorker.kt
@@ -22,6 +22,7 @@
 import androidx.work.OneTimeWorkRequestBuilder
 import androidx.work.WorkerParameters
 import com.android.statementservice.utils.AndroidUtils
+import com.android.statementservice.utils.StatementUtils
 import kotlinx.coroutines.coroutineScope
 import java.util.UUID
 
@@ -59,9 +60,13 @@
         val packageName = params.inputData.getString(PACKAGE_NAME_KEY)!!
         val host = params.inputData.getString(HOST_KEY)!!
 
-        val (result, status) = verifier.verifyHost(host, packageName, params.network)
+        val (result, status, statement) = verifier.verifyHost(host, packageName, params.network)
 
         verificationManager.setDomainVerificationStatus(domainSetId, setOf(host), status.value)
+        val groups = statement?.dynamicAppLinkComponents.orEmpty().map {
+            StatementUtils.createUriRelativeFilterGroup(it)
+        }
+        updateUriRelativeFilterGroups(packageName, mapOf(host to groups))
 
         result
     }
diff --git a/packages/StatementService/src/com/android/statementservice/network/retriever/StatementParser.kt b/packages/StatementService/src/com/android/statementservice/network/retriever/StatementParser.kt
index ad137400..d10cb0f 100644
--- a/packages/StatementService/src/com/android/statementservice/network/retriever/StatementParser.kt
+++ b/packages/StatementService/src/com/android/statementservice/network/retriever/StatementParser.kt
@@ -39,6 +39,11 @@
 
     private const val FIELD_NOT_STRING_FORMAT_STRING = "Expected %s to be string."
     private const val FIELD_NOT_ARRAY_FORMAT_STRING = "Expected %s to be array."
+    private const val COMMENTS_NAME = "comments"
+    private const val EXCLUDE_NAME = "exclude"
+    private const val FRAGMENT_NAME = "#"
+    private const val QUERY_NAME = "?"
+    private const val PATH_NAME = "/"
 
     /**
      * Parses a JSON array of statements.
@@ -99,9 +104,7 @@
                 FIELD_NOT_ARRAY_FORMAT_STRING.format(StatementUtils.ASSET_DESCRIPTOR_FIELD_RELATION)
             )
         val target = AssetFactory.create(targetObject)
-        val dynamicAppLinkComponents = parseDynamicAppLinkComponents(
-            statement.optJSONObject(StatementUtils.ASSET_DESCRIPTOR_FIELD_RELATION_EXTENSIONS)
-        )
+        val dynamicAppLinkComponents = parseDynamicAppLinkComponents(statement)
 
         val statements = (0 until relations.length())
             .map { relations.getString(it) }
@@ -129,13 +132,13 @@
     }
 
     private fun parseComponent(component: JSONObject): DynamicAppLinkComponent {
-        val query = component.optJSONObject("?")
+        val query = component.optJSONObject(QUERY_NAME)
         return DynamicAppLinkComponent.create(
-            component.optBoolean("exclude", false),
-            component.optString("#"),
-            component.optString("/"),
+            component.optBoolean(EXCLUDE_NAME, false),
+            if (component.has(FRAGMENT_NAME)) component.getString(FRAGMENT_NAME) else null,
+            if (component.has(PATH_NAME)) component.getString(PATH_NAME) else null,
             query?.keys()?.asSequence()?.associateWith { query.getString(it) },
-            component.optString("comments")
+            component.optString(COMMENTS_NAME)
         )
     }
 
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/DynamicAppLinkComponent.java b/packages/StatementService/src/com/android/statementservice/retriever/DynamicAppLinkComponent.java
index dc27e12..c32f194 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/DynamicAppLinkComponent.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/DynamicAppLinkComponent.java
@@ -130,7 +130,7 @@
     @Override
     public String toString() {
         StringBuilder statement = new StringBuilder();
-        statement.append("HandleAllUriRule: ");
+        statement.append("DynamicAppLinkComponent: ");
         statement.append(mExclude);
         statement.append(", ");
         statement.append(mFragment);
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/JsonParser.java b/packages/StatementService/src/com/android/statementservice/retriever/JsonParser.java
index 7635e82..ab1853c 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/JsonParser.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/JsonParser.java
@@ -24,8 +24,6 @@
 import org.json.JSONObject;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * A helper class that creates a {@link JSONObject} from a {@link JsonReader}.
@@ -48,7 +46,7 @@
 
             JsonToken token = reader.peek();
             if (token.equals(JsonToken.BEGIN_ARRAY)) {
-                output.put(fieldName, new JSONArray(parseArray(reader)));
+                output.put(fieldName, parseArray(reader));
             } else if (token.equals(JsonToken.STRING)) {
                 output.put(fieldName, reader.nextString());
             } else if (token.equals(JsonToken.BEGIN_OBJECT)) {
@@ -57,9 +55,11 @@
                 } catch (JSONException e) {
                     errorMsg = e.getMessage();
                 }
+            } else if (token.equals(JsonToken.BOOLEAN)) {
+                output.put(fieldName, reader.nextBoolean());
             } else {
                 reader.skipValue();
-                errorMsg = "Unsupported value type.";
+                errorMsg = "Unsupported value type: " + token;
             }
         }
         reader.endObject();
@@ -72,17 +72,36 @@
     }
 
     /**
-     * Parses one string array from the {@link JsonReader}.
+     * Parses one JSON array from the {@link JsonReader}.
      */
-    public static List<String> parseArray(JsonReader reader) throws IOException {
-        ArrayList<String> output = new ArrayList<>();
+    public static JSONArray parseArray(JsonReader reader) throws IOException, JSONException {
+        JSONArray output = new JSONArray();
+        String errorMsg = null;
 
         reader.beginArray();
         while (reader.hasNext()) {
-            output.add(reader.nextString());
+            JsonToken token = reader.peek();
+            if (token.equals(JsonToken.BEGIN_ARRAY)) {
+                output.put(parseArray(reader));
+            } else if (token.equals(JsonToken.STRING)) {
+                output.put(reader.nextString());
+            } else if (token.equals(JsonToken.BEGIN_OBJECT)) {
+                try {
+                    output.put(parse(reader));
+                } catch (JSONException e) {
+                    errorMsg = e.getMessage();
+                }
+            } else {
+                reader.skipValue();
+                errorMsg = "Unsupported value type: " + token;
+            }
         }
         reader.endArray();
 
+        if (errorMsg != null) {
+            throw new JSONException(errorMsg);
+        }
+
         return output;
     }
 }
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index d1a22e8..3d250fd 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -81,33 +81,37 @@
     visibility: ["//visibility:private"],
 }
 
-// Tests where robolectric conversion caused errors in SystemUITests at runtime
-filegroup {
-    name: "SystemUI-tests-broken-robofiles-sysui-run",
-    srcs: [
-        "tests/src/**/systemui/broadcast/BroadcastDispatcherTest.kt",
-        "tests/src/**/systemui/broadcast/ActionReceiverTest.kt",
-        "tests/src/**/systemui/globalactions/GlobalActionsDialogLiteTest.java",
-        "tests/src/**/systemui/globalactions/GlobalActionsImeTest.java",
-        "tests/src/**/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt",
-        "tests/src/**/systemui/media/dialog/MediaOutputAdapterTest.java",
-        "tests/src/**/systemui/media/dialog/MediaOutputBaseDialogTest.java",
-        "tests/src/**/systemui/media/dialog/MediaOutputBroadcastDialogTest.java",
-        "tests/src/**/systemui/media/dialog/MediaOutputDialogTest.java",
-        "tests/src/**/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt",
-        "tests/src/**/systemui/settings/brightness/BrightnessDialogTest.kt",
-    ],
-}
-
 // Tests where robolectric failed at runtime. (go/central-multivalent)
 filegroup {
     name: "SystemUI-tests-broken-robofiles-run",
     srcs: [
-        "tests/src/**/systemui/ExpandHelperTest.java",
+        "tests/src/**/systemui/shade/NotificationShadeWindowViewControllerTest.kt",
+        "tests/src/**/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt",
+        "tests/src/**/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt",
+        "tests/src/**/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt",
+        "tests/src/**/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt",
+        "tests/src/**/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt",
+        "tests/src/**/systemui/education/domain/ui/view/ContextualEduDialogTest.kt",
+        "tests/src/**/systemui/screenshot/ActionIntentCreatorTest.kt",
+        "tests/src/**/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt",
+        "tests/src/**/systemui/accessibility/WindowMagnificationControllerTest.java",
+        "tests/src/**/systemui/broadcast/BroadcastDispatcherTest.kt",
+        "tests/src/**/systemui/globalactions/GlobalActionsDialogLiteTest.java",
+        "tests/src/**/systemui/globalactions/GlobalActionsImeTest.java",
+        "tests/src/**/systemui/media/dialog/MediaOutputBaseDialogTest.java",
+        "tests/src/**/systemui/media/dialog/MediaOutputBroadcastDialogTest.java",
+        "tests/src/**/systemui/media/dialog/MediaOutputDialogTest.java",
+        "tests/src/**/systemui/settings/brightness/BrightnessDialogTest.kt",
+        "tests/src/**/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt",
+        "tests/src/**/systemui/statusbar/policy/SecurityControllerTest.java",
+        "tests/src/**/systemui/lifecycle/SysUiViewModelTest.kt",
+        "tests/src/**/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt",
+        "tests/src/**/systemui/graphics/ImageLoaderContentProviderTest.kt",
+        "tests/src/**/systemui/flags/FakeFeatureFlagsTest.kt",
+        "tests/src/**/systemui/communal/data/backup/CommunalBackupUtilsTest.kt",
         "tests/src/**/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java",
         "tests/src/**/systemui/accessibility/AccessibilityGestureTargetsObserverTest.java",
         "tests/src/**/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java",
-        "tests/src/**/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java",
         "tests/src/**/systemui/screenshot/appclips/AppClipsActivityTest.java",
         "tests/src/**/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java",
         "tests/src/**/systemui/screenshot/appclips/AppClipsViewModelTest.java",
@@ -124,36 +128,27 @@
         "tests/src/**/systemui/classifier/FalsingDataProviderTest.java",
         "tests/src/**/systemui/screenshot/ImageExporterTest.java",
         "tests/src/**/systemui/bouncer/data/repository/KeyguardBouncerRepositoryTest.kt",
-        "tests/src/**/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt",
         "tests/src/**/systemui/logcat/LogAccessDialogActivityTest.java",
         "tests/src/**/systemui/media/controls/domain/pipeline/MediaDeviceManagerTest.kt",
         "tests/src/**/systemui/media/controls/domain/pipeline/MediaSessionBasedFilterTest.kt",
         "tests/src/**/systemui/accessibility/floatingmenu/MenuNotificationFactoryTest.java",
         "tests/src/**/systemui/accessibility/floatingmenu/MenuViewLayerTest.java",
-        "tests/src/**/systemui/accessibility/floatingmenu/MenuViewTest.java",
         "tests/src/**/systemui/classifier/PointerCountClassifierTest.java",
         "tests/src/**/systemui/accessibility/floatingmenu/RadiiAnimatorTest.java",
         "tests/src/**/systemui/screenrecord/RecordingControllerTest.java",
         "tests/src/**/systemui/screenshot/RequestProcessorTest.kt",
         "tests/src/**/systemui/media/controls/domain/resume/ResumeMediaBrowserTest.kt",
-        "tests/src/**/systemui/screenshot/SaveImageInBackgroundTaskTest.kt",
         "tests/src/**/systemui/screenshot/scroll/ScrollCaptureClientTest.java",
         "tests/src/**/systemui/accessibility/SecureSettingsContentObserverTest.java",
         "tests/src/**/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt",
         "tests/src/**/systemui/qs/external/TileServicesTest.java",
         "tests/src/**/systemui/ambient/touch/TouchMonitorTest.java",
-        "tests/src/**/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java",
         "tests/src/**/systemui/accessibility/WindowMagnificationSettingsTest.java",
-        "tests/src/androidx/core/animation/AnimatorTestRuleIsolationTest.kt",
         "tests/src/**/systemui/CameraProtectionLoaderImplTest.kt",
-        "tests/src/**/systemui/DependencyTest.java",
-        "tests/src/**/systemui/InitControllerTest.java",
         "tests/src/**/systemui/SliceBroadcastRelayHandlerTest.java",
         "tests/src/**/systemui/SystemUIApplicationTest.kt",
         "tests/src/**/systemui/SysUICutoutProviderTest.kt",
-        "tests/src/**/keyguard/ActiveUnlockConfigTest.kt",
         "tests/src/**/keyguard/AdminSecondaryLockScreenControllerTest.java",
-        "tests/src/**/keyguard/KeyguardClockAccessibilityDelegateTest.java",
         "tests/src/**/keyguard/KeyguardStatusViewControllerTest.java",
         "tests/src/**/systemui/accessibility/AccessibilityButtonModeObserverTest.java",
         "tests/src/**/systemui/accessibility/AccessibilityButtonTargetsObserverTest.java",
@@ -164,16 +159,12 @@
         "tests/src/**/systemui/animation/TextAnimatorTest.kt",
         "tests/src/**/systemui/animation/TextInterpolatorTest.kt",
         "tests/src/**/systemui/animation/ActivityTransitionAnimatorTest.kt",
-        "tests/src/**/systemui/animation/AnimatorTestRuleOrderTest.kt",
         "tests/src/**/systemui/animation/DialogTransitionAnimatorTest.kt",
-        "tests/src/**/systemui/broadcast/ActionReceiverTest.kt",
         "tests/src/**/systemui/broadcast/BroadcastDispatcherTest.kt",
-        "tests/src/**/systemui/compose/ComposeInitializerTest.kt",
         "tests/src/**/systemui/controls/ui/ControlsActivityTest.kt",
         "tests/src/**/systemui/controls/management/ControlsEditingActivityTest.kt",
         "tests/src/**/systemui/controls/management/ControlsRequestDialogTest.kt",
         "tests/src/**/systemui/controls/ui/DetailDialogTest.kt",
-        "tests/src/**/systemui/fontscaling/FontScalingDialogDelegateTest.kt",
         "tests/src/**/systemui/keyguard/CustomizationProviderTest.kt",
         "tests/src/**/systemui/globalactions/GlobalActionsColumnLayoutTest.java",
         "tests/src/**/systemui/globalactions/GlobalActionsDialogLiteTest.java",
@@ -182,10 +173,6 @@
         "tests/src/**/systemui/keyguard/CustomizationProviderTest.kt",
         "tests/src/**/systemui/keyguard/KeyguardViewMediatorTest.java",
         "tests/src/**/systemui/keyguard/LifecycleTest.java",
-        "tests/src/**/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt",
-        "tests/src/**/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt",
-        "tests/src/**/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryTest.kt",
-        "tests/src/**/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModelTest.kt",
         "tests/src/**/systemui/lifecycle/RepeatWhenAttachedTest.kt",
         "tests/src/**/systemui/log/LogBufferTest.kt",
         "tests/src/**/systemui/media/dialog/MediaOutputBaseDialogTest.java",
@@ -193,52 +180,35 @@
         "tests/src/**/systemui/media/dialog/MediaOutputDialogTest.java",
         "tests/src/**/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt",
         "tests/src/**/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt",
-        "tests/src/**/systemui/navigationbar/views/NavigationBarButtonTest.java",
         "tests/src/**/systemui/people/PeopleProviderTest.java",
         "tests/src/**/systemui/people/PeopleSpaceUtilsTest.java",
         "tests/src/**/systemui/people/widget/PeopleSpaceWidgetManagerTest.java",
         "tests/src/**/systemui/people/PeopleTileViewHelperTest.java",
         "tests/src/**/systemui/power/data/repository/PowerRepositoryImplTest.kt",
-        "tests/src/**/systemui/privacy/PrivacyConfigFlagsTest.kt",
-        "tests/src/**/systemui/privacy/PrivacyDialogV2Test.kt",
-        "tests/src/**/systemui/qs/external/TileRequestDialogEventLoggerTest.kt",
-        "tests/src/**/systemui/qs/AutoAddTrackerTest.kt",
-        "tests/src/**/systemui/qs/external/TileRequestDialogEventLoggerTest.kt",
         "tests/src/**/systemui/qs/tiles/DndTileTest.kt",
         "tests/src/**/systemui/qs/tiles/DreamTileTest.java",
-        "tests/src/**/systemui/qs/FgsManagerControllerTest.java",
         "tests/src/**/systemui/qs/QSPanelTest.kt",
         "tests/src/**/systemui/reardisplay/RearDisplayCoreStartableTest.kt",
         "tests/src/**/systemui/reardisplay/RearDisplayDialogControllerTest.java",
         "tests/src/**/systemui/reardisplay/RearDisplayInnerDialogDelegateTest.kt",
         "tests/src/**/systemui/statusbar/KeyboardShortcutListSearchTest.java",
         "tests/src/**/systemui/statusbar/KeyboardShortcutsTest.java",
-        "tests/src/**/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt",
-        "tests/src/**/systemui/statusbar/notification/AssistantFeedbackControllerTest.java",
         "tests/src/**/systemui/statusbar/notification/collection/NotificationEntryTest.java",
-        "tests/src/**/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt",
         "tests/src/**/systemui/statusbar/notification/collection/ShadeListBuilderTest.java",
-        "tests/src/**/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java",
         "tests/src/**/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java",
         "tests/src/**/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt",
         "tests/src/**/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt",
-        "tests/src/**/systemui/statusbar/NotificationLockscreenUserManagerTest.java",
         "tests/src/**/systemui/statusbar/notification/logging/NotificationLoggerTest.java",
         "tests/src/**/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java",
-        "tests/src/**/systemui/statusbar/notification/row/NotificationContentInflaterTest.java",
         "tests/src/**/systemui/statusbar/notification/row/NotificationContentViewTest.kt",
         "tests/src/**/systemui/statusbar/notification/row/NotificationConversationInfoTest.java",
-        "tests/src/**/systemui/statusbar/notification/row/NotificationGutsManagerTest.java",
         "tests/src/**/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt",
         "tests/src/**/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt",
         "tests/src/**/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java",
-        "tests/src/**/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt",
-        "tests/src/**/systemui/statusbar/phone/AutoTileManagerTest.java",
         "tests/src/**/systemui/statusbar/phone/CentralSurfacesImplTest.java",
         "tests/src/**/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java",
         "tests/src/**/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt",
         "tests/src/**/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt",
-        "tests/src/**/systemui/statusbar/phone/PhoneStatusBarView.java",
         "tests/src/**/systemui/statusbar/phone/PhoneStatusBarViewTest.kt",
         "tests/src/**/systemui/statusbar/phone/StatusBarBoundsProviderTest.kt",
         "tests/src/**/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt",
@@ -252,13 +222,9 @@
         "tests/src/**/systemui/statusbar/policy/LocationControllerImplTest.java",
         "tests/src/**/systemui/statusbar/policy/RemoteInputViewTest.java",
         "tests/src/**/systemui/statusbar/policy/SmartReplyViewTest.java",
-        "tests/src/**/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt",
-        "tests/src/**/systemui/statusbar/StatusBarStateControllerImplTest.kt",
         "tests/src/**/systemui/theme/ThemeOverlayApplierTest.java",
         "tests/src/**/systemui/touch/TouchInsetManagerTest.java",
         "tests/src/**/systemui/util/LifecycleFragmentTest.java",
-        "tests/src/**/systemui/util/kotlin/PairwiseFlowTest",
-        "tests/src/**/systemui/util/sensors/AsyncManagerTest.java",
         "tests/src/**/systemui/util/sensors/ThresholdSensorImplTest.java",
         "tests/src/**/systemui/volume/VolumeDialogImplTest.java",
         "tests/src/**/systemui/wallet/controller/QuickAccessWalletControllerTest.java",
@@ -271,26 +237,17 @@
         "tests/src/**/systemui/clipboardoverlay/ClipboardListenerTest.java",
         "tests/src/**/systemui/communal/data/db/CommunalDatabaseMigrationsTest.kt",
         "tests/src/**/systemui/communal/data/db/CommunalWidgetDaoTest.kt",
-        "tests/src/**/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt",
         "tests/src/**/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt",
         "tests/src/**/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt",
         "tests/src/**/systemui/lifecycle/ActivatableTest.kt",
-        "tests/src/**/systemui/lifecycle/HydratorTest.kt",
         "tests/src/**/systemui/media/dialog/MediaSwitchingControllerTest.java",
         "tests/src/**/systemui/qs/QSImplTest.java",
         "tests/src/**/systemui/qs/panels/ui/compose/DragAndDropTest.kt",
         "tests/src/**/systemui/qs/panels/ui/compose/ResizingTest.kt",
         "tests/src/**/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java",
-        "tests/src/**/systemui/accessibility/floatingmenu/PositionTest.java",
         "tests/src/**/systemui/animation/TransitionAnimatorTest.kt",
-        "tests/src/**/systemui/screenshot/scroll/ScrollCaptureControllerTest.java",
-        "tests/src/**/systemui/lifecycle/SysuiViewModelTest.kt",
-        "tests/src/**/systemui/flags/FakeFeatureFlags.kt",
         "tests/src/**/systemui/animation/TransitionAnimatorTest.kt",
-        "tests/src/**/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java",
         "tests/src/**/systemui/statusbar/connectivity/NetworkControllerSignalTest.java",
-        "tests/src/**/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt",
-        "tests/src/**/systemui/statusbar/policy/RotationLockControllerImplTest.java",
         "tests/src/**/systemui/statusbar/phone/ScrimControllerTest.java",
         "tests/src/**/systemui/toast/ToastUITest.java",
         "tests/src/**/systemui/statusbar/policy/FlashlightControllerImplTest.kt",
@@ -329,47 +286,48 @@
         "tests/src/**/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java",
         "tests/src/**/systemui/qs/external/TileLifecycleManagerTest.java",
         "tests/src/**/systemui/ScreenDecorationsTest.java",
+        "tests/src/**/systemui/statusbar/policy/BatteryControllerStartableTest.java",
         "tests/src/**/keyguard/CarrierTextManagerTest.java",
         "tests/src/**/keyguard/KeyguardUpdateMonitorTest.java",
     ],
 }
 
-// Tests where robolectric failed at compile time. (go/multivalent-tests)
+// Tests where compilation failed due to kotlin internal references.
 filegroup {
-    name: "SystemUI-tests-broken-robofiles-compile",
+    name: "SystemUI-tests-broken-robofiles-internal",
     srcs: [
-        "tests/src/**/systemui/statusbar/notification/icon/IconManagerTest.kt",
-        "tests/src/**/systemui/statusbar/KeyguardIndicationControllerTest.java",
-        "tests/src/**/systemui/doze/DozeScreenStateTest.java",
-        "tests/src/**/systemui/notetask/NoteTaskInitializerTest.kt",
-        "tests/src/**/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt",
-        "tests/src/**/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt",
-        "tests/src/**/systemui/controls/management/ControlsFavoritingActivityTest.kt",
-        "tests/src/**/systemui/controls/management/ControlsProviderSelectorActivityTest.kt",
-        "tests/src/**/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt",
-        "tests/src/**/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt",
-        "tests/src/**/systemui/qs/tileimpl/QSTileViewImplTest.kt",
+        "tests/src/**/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt",
+        "tests/src/**/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt",
+        "tests/src/**/android/systemui/statusbar/notification/icon/IconManagerTest.kt",
+        "tests/src/**/android/systemui/notetask/NoteTaskInitializerTest.kt",
+        "tests/src/**/systemui/statusbar/policy/VariableDateViewControllerTest.kt",
+        "tests/src/**/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt",
+        "tests/src/**/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt",
+        "tests/src/**/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt",
+        "tests/src/**/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt",
+        "tests/src/**/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt",
         "tests/src/**/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt",
+        "tests/src/**/systemui/statusbar/policy/WalletControllerImplTest.kt",
         "tests/src/**/keyguard/ClockEventControllerTest.kt",
-        "tests/src/**/systemui/bluetooth/qsdialog/BluetoothAutoOnRepositoryTest.kt",
+        "tests/src/**/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt",
         "tests/src/**/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt",
         "tests/src/**/systemui/bluetooth/qsdialog/BluetoothTileDialogRepositoryTest.kt",
         "tests/src/**/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt",
+        "tests/src/**/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt",
         "tests/src/**/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt",
         "tests/src/**/systemui/broadcast/UserBroadcastDispatcherTest.kt",
         "tests/src/**/systemui/charging/WiredChargingRippleControllerTest.kt",
         "tests/src/**/systemui/clipboardoverlay/ClipboardModelTest.kt",
         "tests/src/**/systemui/controls/controller/AuxiliaryPersistenceWrapperTest.kt",
-        "tests/src/**/systemui/controls/controller/ControlsBindingControllerImplTest.kt",
         "tests/src/**/systemui/controls/controller/ControlsControllerImplTest.kt",
         "tests/src/**/systemui/controls/controller/DeletionJobServiceTest.kt",
-        "tests/src/**/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt",
+        "tests/src/**/systemui/controls/management/ControlsFavoritingActivityTest.kt",
         "tests/src/**/systemui/controls/ui/ControlsUiControllerImplTest.kt",
-        "tests/src/**/systemui/controls/ui/ControlViewHolderTest.kt",
         "tests/src/**/systemui/controls/ui/SelectionItemTest.kt",
         "tests/src/**/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt",
         "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataFilterImplTest.kt",
-        "tests/src/**/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt",
+        "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt",
+        "tests/src/**/systemui/media/controls/ui/MediaPlayerDataTest.kt",
         "tests/src/**/systemui/media/controls/ui/animation/AnimationBindHandlerTest.kt",
         "tests/src/**/systemui/media/controls/ui/animation/ColorSchemeTransitionTest.kt",
         "tests/src/**/systemui/media/controls/ui/animation/MetadataAnimationHandlerTest.kt",
@@ -377,7 +335,6 @@
         "tests/src/**/systemui/media/controls/ui/controller/MediaControlPanelTest.kt",
         "tests/src/**/systemui/media/controls/ui/controller/MediaViewControllerTest.kt",
         "tests/src/**/systemui/media/controls/ui/drawable/SquigglyProgressTest.kt",
-        "tests/src/**/systemui/media/controls/ui/MediaPlayerDataTest.kt",
         "tests/src/**/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt",
         "tests/src/**/systemui/navigationbar/gestural/BackPanelControllerTest.kt",
         "tests/src/**/systemui/notetask/NoteTaskControllerTest.kt",
@@ -386,61 +343,61 @@
         "tests/src/**/systemui/qs/external/CustomTileStatePersisterTest.kt",
         "tests/src/**/systemui/qs/external/TileRequestDialogTest.kt",
         "tests/src/**/systemui/qs/external/TileServiceRequestControllerTest.kt",
-        "tests/src/**/systemui/qs/tileimpl/TilesStatesTextTest.kt",
+        "tests/src/**/systemui/qs/tileimpl/QSTileViewImplTest.kt",
         "tests/src/**/systemui/qs/tiles/AlarmTileTest.kt",
         "tests/src/**/systemui/qs/tiles/BluetoothTileTest.kt",
-        "tests/src/**/systemui/screenshot/ScreenshotPolicyImplTest.kt",
-        "tests/src/**/systemui/settings/DisplayTrackerImplTest.kt",
+        "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt",
+        "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt",
+        "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt",
+        "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt",
+        "tests/src/**/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt",
+        "tests/src/**/systemui/statusbar/phone/fragment/MultiSourceMinAlphaControllerTest.kt",
+        "tests/src/**/systemui/statusbar/phone/FoldStateListenerTest.kt",
+        "tests/src/**/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerTest.kt",
+        "tests/src/**/systemui/statusbar/notification/row/TextPrecomputerTest.kt",
+        "tests/src/**/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt",
+        "tests/src/**/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt",
+        "tests/src/**/systemui/statusbar/notification/row/SingleLineViewInflaterTest.kt",
+        "tests/src/**/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt",
+        "tests/src/**/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt",
+        "tests/src/**/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt",
+        "tests/src/**/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt",
+        "tests/src/**/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt",
+        "tests/src/**/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt",
+        "tests/src/**/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt",
+        "tests/src/**/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt",
+        "tests/src/**/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt",
+        "tests/src/**/systemui/statusbar/notification/RoundableTest.kt",
+        "tests/src/**/systemui/stylus/StylusUsiPowerUiTest.kt",
+        "tests/src/**/systemui/statusbar/gesture/GenericGestureDetectorTest.kt",
+        "tests/src/**/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt",
+        "tests/src/**/systemui/statusbar/connectivity/MobileStateTest.kt",
+        "tests/src/**/systemui/statusbar/commandline/CommandParserTest.kt",
+        "tests/src/**/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt",
+        "tests/src/**/systemui/statusbar/LightRevealScrimTest.kt",
+        "tests/src/**/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt",
+        "tests/src/**/systemui/shade/ShadeExpansionStateManagerTest.kt",
+        "tests/src/**/systemui/shade/ShadeHeaderControllerTest.kt",
+        "tests/src/**/systemui/shade/NotificationsQSContainerControllerTest.kt",
         "tests/src/**/systemui/settings/UserFileManagerImplTest.kt",
         "tests/src/**/systemui/settings/UserTrackerImplReceiveTest.kt",
         "tests/src/**/systemui/settings/UserTrackerImplTest.kt",
         "tests/src/**/systemui/shade/GlanceableHubContainerControllerTest.kt",
         "tests/src/**/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt",
-        "tests/src/**/systemui/shade/NotificationsQSContainerControllerTest.kt",
-        "tests/src/**/systemui/shade/ShadeExpansionStateManagerTest.kt",
-        "tests/src/**/systemui/shade/ShadeHeaderControllerTest.kt",
-        "tests/src/**/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt",
-        "tests/src/**/systemui/statusbar/commandline/CommandParserTest.kt",
-        "tests/src/**/systemui/statusbar/connectivity/MobileStateTest.kt",
-        "tests/src/**/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt",
-        "tests/src/**/systemui/statusbar/gesture/GenericGestureDetectorTest.kt",
-        "tests/src/**/systemui/statusbar/LightRevealScrimTest.kt",
-        "tests/src/**/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt",
-        "tests/src/**/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt",
-        "tests/src/**/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt",
-        "tests/src/**/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt",
-        "tests/src/**/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt",
-        "tests/src/**/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt",
-        "tests/src/**/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt",
-        "tests/src/**/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt",
-        "tests/src/**/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt",
-        "tests/src/**/systemui/statusbar/notification/RoundableTest.kt",
-        "tests/src/**/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt",
-        "tests/src/**/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt",
-        "tests/src/**/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt",
-        "tests/src/**/systemui/statusbar/notification/row/SingleLineViewInflaterTest.kt",
-        "tests/src/**/systemui/statusbar/notification/row/TextPrecomputerTest.kt",
-        "tests/src/**/systemui/statusbar/phone/FoldStateListenerTest.kt",
-        "tests/src/**/systemui/statusbar/phone/fragment/MultiSourceMinAlphaControllerTest.kt",
-        "tests/src/**/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt",
-        "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt",
-        "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt",
-        "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt",
-        "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt",
-        "tests/src/**/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt",
-        "tests/src/**/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt",
-        "tests/src/**/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt",
-        "tests/src/**/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt",
-        "tests/src/**/systemui/statusbar/policy/VariableDateViewControllerTest.kt",
-        "tests/src/**/systemui/statusbar/policy/WalletControllerImplTest.kt",
-        "tests/src/**/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt",
-        "tests/src/**/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt",
-        "tests/src/**/systemui/statusbar/policy/BatteryControllerStartableTest.java",
-        "tests/src/**/systemui/shared/plugins/PluginActionManagerTest.java",
-        "tests/src/**/systemui/statusbar/policy/SecurityControllerTest.java",
-        "tests/src/**/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt",
+        "tests/src/**/systemui/screenshot/ScreenshotPolicyImplTest.kt",
+        "tests/src/**/systemui/qs/tileimpl/TilesStatesTextTest.kt",
+        "tests/src/**/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt",
+        "tests/src/**/systemui/controls/ui/ControlViewHolderTest.kt",
+        "tests/src/**/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt",
+        "tests/src/**/systemui/controls/controller/ControlsBindingControllerImplTest.kt",
+        "tests/src/**/systemui/bluetooth/qsdialog/BluetoothAutoOnRepositoryTest.kt",
+        "tests/src/**/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt",
+        "tests/src/**/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt",
+        "tests/src/**/systemui/controls/management/ControlsProviderSelectorActivityTest.kt",
+        "tests/src/**/systemui/settings/DisplayTrackerImplTest.kt",
+        "tests/src/**/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt",
+        "tests/src/**/systemui/wmshell/BubblesTest.java",
     ],
-    visibility: ["//visibility:private"],
 }
 
 //Create a library to expose SystemUI's resources to other modules.
@@ -903,9 +860,8 @@
     ],
     exclude_srcs: [
         ":SystemUI-tests-broken-robofiles-mockito-extended",
-        ":SystemUI-tests-broken-robofiles-compile",
+        ":SystemUI-tests-broken-robofiles-internal",
         ":SystemUI-tests-broken-robofiles-run",
-        ":SystemUI-tests-broken-robofiles-sysui-run",
     ],
     static_libs: [
         "RoboTestLibraries",
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index e47704eb..cc01071 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -55,14 +55,6 @@
           "exclude-filter": "android.platform.tests.HomeTest#testAssistantWidget"
         }
       ]
-    },
-    {
-      "name": "AndroidAutomotiveNotificationsTests",
-      "options" : [
-        {
-          "include-filter": "android.platform.tests.NotificationTest"
-        }
-      ]
     }
   ],
 
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
index c71ef83..129dd9b 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
@@ -36,7 +36,6 @@
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceManager;
 
-import com.android.systemui.accessibility.accessibilitymenu.Flags;
 import com.android.systemui.accessibility.accessibilitymenu.R;
 
 /**
@@ -62,10 +61,8 @@
         ((TextView) findViewById(R.id.action_bar_title)).setText(
                 getResources().getString(R.string.accessibility_menu_settings_name)
         );
-        if (Flags.actionBarWrapContent()) {
-            setHeightWrapContent(findViewById(com.android.internal.R.id.action_bar));
-            setHeightWrapContent(findViewById(com.android.internal.R.id.action_bar_container));
-        }
+        setHeightWrapContent(findViewById(com.android.internal.R.id.action_bar));
+        setHeightWrapContent(findViewById(com.android.internal.R.id.action_bar_container));
     }
 
     private void setHeightWrapContent(View view) {
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
index 3db61a5..6bc0f42 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
@@ -220,9 +220,6 @@
 
     @SuppressLint("MissingPermission")
     private boolean isShortcutRestricted(int shortcutId) {
-        if (!Flags.hideRestrictedActions()) {
-            return false;
-        }
         final UserManager userManager = mService.getSystemService(UserManager.class);
         if (userManager == null) {
             return false;
@@ -366,12 +363,11 @@
         if (mLayout.getVisibility() == View.VISIBLE) {
             mLayout.setVisibility(View.GONE);
         } else {
-            if (Flags.hideRestrictedActions()) {
-                // Reconfigure the shortcut list in case the set of restricted actions has changed.
-                mA11yMenuViewPager.configureViewPagerAndFooter(
-                        mLayout, createShortcutList(), getPageIndex());
-                updateViewLayout();
-            }
+            // Reconfigure the shortcut list in case the set of restricted actions has changed.
+            mA11yMenuViewPager.configureViewPagerAndFooter(
+                    mLayout, createShortcutList(), getPageIndex());
+            updateViewLayout();
+
             mLayout.setVisibility(View.VISIBLE);
         }
     }
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
index 4ab771b..7172619 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
@@ -46,9 +46,6 @@
 import android.media.AudioManager;
 import android.os.PowerManager;
 import android.os.UserManager;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.platform.uiautomator_helpers.WaitUtils;
 import android.provider.Settings;
 import android.util.Log;
@@ -63,7 +60,6 @@
 import androidx.test.uiautomator.UiDevice;
 
 import com.android.compatibility.common.util.TestUtils;
-import com.android.systemui.accessibility.accessibilitymenu.Flags;
 import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut.ShortcutId;
 
 import org.junit.After;
@@ -71,7 +67,6 @@
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -82,9 +77,6 @@
 
 @RunWith(AndroidJUnit4.class)
 public class AccessibilityMenuServiceTest {
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
     private static final String TAG = "A11yMenuServiceTest";
     private static final int CLICK_ID = AccessibilityNodeInfo.ACTION_CLICK;
 
@@ -499,7 +491,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_HIDE_RESTRICTED_ACTIONS)
     public void testRestrictedActions_BrightnessNotAvailable() throws Throwable {
         try {
             setUserRestriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, true);
@@ -519,7 +510,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_HIDE_RESTRICTED_ACTIONS)
     public void testRestrictedActions_VolumeNotAvailable() throws Throwable {
         try {
             setUserRestriction(UserManager.DISALLOW_ADJUST_VOLUME, true);
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index c82c63c7..20b83e1 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1215,6 +1215,13 @@
 }
 
 flag {
+  name: "glanceable_hub_v2"
+  namespace: "systemui"
+  description: "Gates the refreshed glanceable hub experience that also brings the glanceable hub to mobile phones"
+  bug: "375689917"
+}
+
+flag {
     name: "dream_overlay_updated_font"
     namespace: "systemui"
     description: "Flag to enable updated font settings for dream overlay"
@@ -1502,6 +1509,16 @@
 }
 
 flag {
+   name: "sim_pin_use_slot_id"
+   namespace: "systemui"
+   description: "Reorient SIM data processing around slotId instead of subId"
+   bug: "376173142"
+   metadata {
+        purpose: PURPOSE_BUGFIX
+   }
+}
+
+flag {
    name: "use_transitions_for_keyguard_occluded"
    namespace: "systemui"
    description: "Use Keyguard Transitions to set Notification Shade occlusion state"
@@ -1780,6 +1797,16 @@
 }
 
 flag {
+    name: "notification_reentrant_dismiss"
+    namespace: "systemui"
+    description: "Posts to avoid a crashing reentrant pipeline run"
+    bug: "328328054"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+      }
+}
+
+flag {
     name: "stoppable_fgs_system_app"
     namespace: "systemui"
     description: "System app with foreground service can opt in to be stoppable."
@@ -1812,3 +1839,17 @@
     description: "Applies GSF font styles to Quick Settings surfaces."
     bug: "379364381"
 }
+
+flag {
+    name: "glanceable_hub_shortcut_button"
+    namespace: "systemui"
+    description: "Adds a shortcut button to lockscreen to show glanceable hub."
+    bug: "378173531"
+}
+
+flag {
+    name: "spatial_model_launcher_pushback"
+    namespace: "systemui"
+    description: "Implement the depth push scaling effect on Launcher when users pull down shade."
+    bug: "370562309"
+}
diff --git a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java
index 2b5ff7c..0f5e367 100644
--- a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java
+++ b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java
@@ -44,6 +44,7 @@
 /**
  * An implementation of {@link IRemoteTransition} that accepts a {@link UIComponent} as the origin
  * and automatically attaches it to the transition leash before the transition starts.
+ *
  * @hide
  */
 public class OriginRemoteTransition extends IRemoteTransition.Stub {
@@ -258,8 +259,7 @@
             // The transition didn't start. Ensure we apply the start transaction and report
             // finish afterwards.
             mStartTransaction
-                    .addTransactionCommittedListener(
-                            mContext.getMainExecutor(), this::finishInternal)
+                    .addTransactionCommittedListener(mHandler::post, this::finishInternal)
                     .apply();
             return;
         }
@@ -268,8 +268,7 @@
         mPlayer.onEnd(finished);
         // Detach the origin from the transition leash and report finish after it's done.
         mOriginTransaction
-                .detachFromTransitionLeash(
-                        mOrigin, mContext.getMainExecutor(), this::finishInternal)
+                .detachFromTransitionLeash(mOrigin, mHandler::post, this::finishInternal)
                 .commit();
     }
 
@@ -329,7 +328,9 @@
                 /* baseBounds= */ maxBounds);
     }
 
-    /** An interface that represents an origin transitions.
+    /**
+     * An interface that represents an origin transitions.
+     *
      * @hide
      */
     public interface TransitionPlayer {
diff --git a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
index 4c047d5..9cef43c 100644
--- a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
+++ b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
@@ -38,6 +38,7 @@
  * be changed to INVISIBLE in its view tree. This allows the {@link View} to transform in the
  * full-screen size leash without being constrained by the view tree's boundary or inheriting its
  * parent's alpha and transformation.
+ *
  * @hide
  */
 public class ViewUIComponent implements UIComponent {
@@ -98,9 +99,7 @@
         mView.getViewTreeObserver().addOnDrawListener(mOnDrawListener);
 
         // Make the view invisible AFTER the surface is shown.
-        t.addTransactionCommittedListener(
-                        mView.getContext().getMainExecutor(),
-                        () -> mView.setVisibility(View.INVISIBLE))
+        t.addTransactionCommittedListener(mView::post, () -> mView.setVisibility(View.INVISIBLE))
                 .apply();
     }
 
@@ -118,7 +117,7 @@
         SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         t.reparent(sc, null)
                 .addTransactionCommittedListener(
-                        mView.getContext().getMainExecutor(),
+                        mView::post,
                         () -> {
                             s.release();
                             sc.release();
@@ -235,41 +234,40 @@
         mView.post(this::draw);
     }
 
-    /**
-     * @hide
-     */
+    /** @hide */
     public static class Transaction implements UIComponent.Transaction<ViewUIComponent> {
         private final List<Runnable> mChanges = new ArrayList<>();
 
         @Override
         public Transaction setAlpha(ViewUIComponent ui, float alpha) {
-            mChanges.add(() -> ui.setAlpha(alpha));
+            mChanges.add(() -> ui.mView.post(() -> ui.setAlpha(alpha)));
             return this;
         }
 
         @Override
         public Transaction setVisible(ViewUIComponent ui, boolean visible) {
-            mChanges.add(() -> ui.setVisible(visible));
+            mChanges.add(() -> ui.mView.post(() -> ui.setVisible(visible)));
             return this;
         }
 
         @Override
         public Transaction setBounds(ViewUIComponent ui, Rect bounds) {
-            mChanges.add(() -> ui.setBounds(bounds));
+            mChanges.add(() -> ui.mView.post(() -> ui.setBounds(bounds)));
             return this;
         }
 
         @Override
         public Transaction attachToTransitionLeash(
                 ViewUIComponent ui, SurfaceControl transitionLeash, int w, int h) {
-            mChanges.add(() -> ui.attachToTransitionLeash(transitionLeash, w, h));
+            mChanges.add(
+                    () -> ui.mView.post(() -> ui.attachToTransitionLeash(transitionLeash, w, h)));
             return this;
         }
 
         @Override
         public Transaction detachFromTransitionLeash(
                 ViewUIComponent ui, Executor executor, Runnable onDone) {
-            mChanges.add(() -> ui.detachFromTransitionLeash(executor, onDone));
+            mChanges.add(() -> ui.mView.post(() -> ui.detachFromTransitionLeash(executor, onDone)));
             return this;
         }
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index eee0caf..38f0998 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.animation
 
 import android.app.ActivityManager
+import android.app.ActivityOptions
 import android.app.ActivityTaskManager
 import android.app.PendingIntent
 import android.app.TaskInfo
@@ -434,8 +435,7 @@
                     private fun cleanUp() {
                         cleanUpRunnable?.run()
                     }
-                },
-                initializeLazily = longLivedReturnAnimationsEnabled(),
+                }
             )
 
         // mTypeSet and mModes match back signals only, and not home. This is on purpose, because
@@ -478,8 +478,8 @@
     /** Create a new animation [Runner] controlled by [controller]. */
     @VisibleForTesting
     @JvmOverloads
-    fun createRunner(controller: Controller, initializeLazily: Boolean = false): Runner {
-        if (initializeLazily) assertLongLivedReturnAnimations()
+    fun createRunner(controller: Controller, longLived: Boolean = false): Runner {
+        if (longLived) assertLongLivedReturnAnimations()
 
         // Make sure we use the modified timings when animating a dialog into an app.
         val transitionAnimator =
@@ -489,13 +489,7 @@
                 transitionAnimator
             }
 
-        return Runner(
-            controller,
-            callback!!,
-            transitionAnimator,
-            lifecycleListener,
-            initializeLazily,
-        )
+        return Runner(controller, callback!!, transitionAnimator, lifecycleListener, longLived)
     }
 
     interface PendingIntentStarter {
@@ -699,7 +693,7 @@
             }
         val launchRemoteTransition =
             RemoteTransition(
-                OriginTransition(createRunner(controller, initializeLazily = true)),
+                OriginTransition(createRunner(controller, longLived = true)),
                 "${cookie}_launchTransition",
             )
         transitionRegister.register(launchFilter, launchRemoteTransition, includeTakeover = true)
@@ -708,6 +702,8 @@
             object : Controller by controller {
                 override val isLaunching: Boolean = false
             }
+        // Cross-task close transitions should not use this animation, so we only register it for
+        // when the opening window is Launcher.
         val returnFilter =
             TransitionFilter().apply {
                 mRequirements =
@@ -716,12 +712,16 @@
                             mActivityType = WindowConfiguration.ACTIVITY_TYPE_STANDARD
                             mModes = intArrayOf(TRANSIT_CLOSE, TRANSIT_TO_BACK)
                             mTopActivity = component
-                        }
+                        },
+                        TransitionFilter.Requirement().apply {
+                            mActivityType = WindowConfiguration.ACTIVITY_TYPE_HOME
+                            mModes = intArrayOf(TRANSIT_OPEN, TRANSIT_TO_FRONT)
+                        },
                     )
             }
         val returnRemoteTransition =
             RemoteTransition(
-                OriginTransition(createRunner(returnController, initializeLazily = true)),
+                OriginTransition(createRunner(returnController, longLived = true)),
                 "${cookie}_returnTransition",
             )
         transitionRegister.register(returnFilter, returnRemoteTransition, includeTakeover = true)
@@ -910,14 +910,22 @@
 
     @VisibleForTesting
     inner class Runner(
-        private val controller: Controller,
+        /**
+         * This can hold a reference to a view, so it needs to be cleaned up and can't be held on to
+         * forever when ![longLived].
+         */
+        private var controller: Controller?,
         private val callback: Callback,
         /** The animator to use to animate the window transition. */
         private val transitionAnimator: TransitionAnimator,
         /** Listener for animation lifecycle events. */
         private val listener: Listener? = null,
-        /** Whether the internal [delegate] should be initialized lazily. */
-        private val initializeLazily: Boolean = false,
+        /**
+         * Whether the internal should be kept around after execution for later usage. IMPORTANT:
+         * should always be false if this [Runner] is to be used directly with [ActivityOptions]
+         * (i.e. for ephemeral launches), or the controller will leak its view.
+         */
+        private val longLived: Boolean = false,
     ) : IRemoteAnimationRunner.Stub() {
         // This is being passed across IPC boundaries and cycles (through PendingIntentRecords,
         // etc.) are possible. So we need to make sure we drop any references that might
@@ -926,7 +934,7 @@
 
         init {
             delegate = null
-            if (!initializeLazily) {
+            if (!longLived) {
                 // Ephemeral launches bundle the runner with the launch request (instead of being
                 // registered ahead of time for later use). This means that there could be a timeout
                 // between creation and invocation, so the delegate needs to exist from the
@@ -1004,16 +1012,17 @@
 
         @AnyThread
         private fun maybeSetUp() {
-            if (!initializeLazily || delegate != null) return
+            if (!longLived || delegate != null) return
             createDelegate()
         }
 
         @AnyThread
         private fun createDelegate() {
+            if (controller == null) return
             delegate =
                 AnimationDelegate(
                     mainExecutor,
-                    controller,
+                    controller!!,
                     callback,
                     DelegatingAnimationCompletionListener(listener, this::dispose),
                     transitionAnimator,
@@ -1025,7 +1034,12 @@
         fun dispose() {
             // Drop references to animation controller once we're done with the animation
             // to avoid leaking.
-            mainExecutor.execute { delegate = null }
+            mainExecutor.execute {
+                delegate = null
+                // When long lived, the same Runner can be used more than once. In this case we need
+                // to keep the controller around so we can rebuild the delegate on demand.
+                if (!longLived) controller = null
+            }
         }
     }
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
index addabcc..a137891 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
@@ -34,66 +34,60 @@
 private const val FONT_ITALIC_ANIMATION_STEP = 0.1f
 private const val FONT_ITALIC_DEFAULT_VALUE = 0f
 
-// Benchmarked via Perfetto, difference between 10 and 50 entries is about 0.3ms in
-// frame draw time on a Pixel 6.
-@VisibleForTesting const val DEFAULT_FONT_CACHE_MAX_ENTRIES = 10
+/** Caches for font interpolation */
+interface FontCache {
+    val animationFrameCount: Int
 
-/** Provide interpolation of two fonts by adjusting font variation settings. */
-class FontInterpolator(
-    numberOfAnimationSteps: Int? = null,
-) {
-    /**
-     * Cache key for the interpolated font.
-     *
-     * This class is mutable for recycling.
-     */
-    private data class InterpKey(var l: Font?, var r: Font?, var progress: Float) {
-        fun set(l: Font, r: Font, progress: Float) {
-            this.l = l
-            this.r = r
-            this.progress = progress
-        }
-    }
+    fun get(key: InterpKey): Font?
 
-    /**
-     * Cache key for the font that has variable font.
-     *
-     * This class is mutable for recycling.
-     */
-    private data class VarFontKey(
-        var sourceId: Int,
-        var index: Int,
-        val sortedAxes: MutableList<FontVariationAxis>
-    ) {
-        constructor(
-            font: Font,
-            axes: List<FontVariationAxis>
-        ) : this(
-            font.sourceIdentifier,
-            font.ttcIndex,
-            axes.toMutableList().apply { sortBy { it.tag } }
-        )
+    fun get(key: VarFontKey): Font?
 
-        fun set(font: Font, axes: List<FontVariationAxis>) {
-            sourceId = font.sourceIdentifier
-            index = font.ttcIndex
-            sortedAxes.clear()
-            sortedAxes.addAll(axes)
-            sortedAxes.sortBy { it.tag }
-        }
-    }
+    fun put(key: InterpKey, font: Font)
 
+    fun put(key: VarFontKey, font: Font)
+}
+
+/** Cache key for the interpolated font. */
+data class InterpKey(val start: Font?, val end: Font?, val frame: Int)
+
+/** Cache key for the font that has variable font. */
+data class VarFontKey(val sourceId: Int, val index: Int, val sortedAxes: List<FontVariationAxis>) {
+    constructor(
+        font: Font,
+        axes: List<FontVariationAxis>,
+    ) : this(font.sourceIdentifier, font.ttcIndex, axes.sortedBy { it.tag })
+}
+
+class FontCacheImpl(override val animationFrameCount: Int = DEFAULT_FONT_CACHE_MAX_ENTRIES / 2) :
+    FontCache {
     // Font interpolator has two level caches: one for input and one for font with different
     // variation settings. No synchronization is needed since FontInterpolator is not designed to be
     // thread-safe and can be used only on UI thread.
-    val cacheMaxEntries = numberOfAnimationSteps?.let { it * 2 } ?: DEFAULT_FONT_CACHE_MAX_ENTRIES
+    val cacheMaxEntries = animationFrameCount * 2
     private val interpCache = LruCache<InterpKey, Font>(cacheMaxEntries)
     private val verFontCache = LruCache<VarFontKey, Font>(cacheMaxEntries)
 
-    // Mutable keys for recycling.
-    private val tmpInterpKey = InterpKey(null, null, 0f)
-    private val tmpVarFontKey = VarFontKey(0, 0, mutableListOf())
+    override fun get(key: InterpKey): Font? = interpCache[key]
 
+    override fun get(key: VarFontKey): Font? = verFontCache[key]
+
+    override fun put(key: InterpKey, font: Font) {
+        interpCache.put(key, font)
+    }
+
+    override fun put(key: VarFontKey, font: Font) {
+        verFontCache.put(key, font)
+    }
+
+    companion object {
+        // Benchmarked via Perfetto, difference between 10 and 50 entries is about 0.3ms in frame
+        // draw time on a Pixel 6.
+        @VisibleForTesting const val DEFAULT_FONT_CACHE_MAX_ENTRIES = 10
+    }
+}
+
+/** Provide interpolation of two fonts by adjusting font variation settings. */
+class FontInterpolator(val fontCache: FontCache = FontCacheImpl()) {
     /** Linear interpolate the font variation settings. */
     fun lerp(start: Font, end: Font, progress: Float): Font {
         if (progress == 0f) {
@@ -111,13 +105,12 @@
 
         // Check we already know the result. This is commonly happens since we draws the different
         // text chunks with the same font.
-        tmpInterpKey.set(start, end, progress)
-        val cachedFont = interpCache[tmpInterpKey]
-        if (cachedFont != null) {
+        val iKey = InterpKey(start, end, (progress * fontCache.animationFrameCount).toInt())
+        fontCache.get(iKey)?.let {
             if (DEBUG) {
-                Log.d(LOG_TAG, "[$progress] Interp. cache hit for $tmpInterpKey")
+                Log.d(LOG_TAG, "[$progress] Interp. cache hit for $iKey")
             }
-            return cachedFont
+            return it
         }
 
         // General axes interpolation takes O(N log N), this is came from sorting the axes. Usually
@@ -131,14 +124,14 @@
                         MathUtils.lerp(
                             startValue ?: FONT_WEIGHT_DEFAULT_VALUE,
                             endValue ?: FONT_WEIGHT_DEFAULT_VALUE,
-                            progress
+                            progress,
                         )
                     TAG_ITAL ->
                         adjustItalic(
                             MathUtils.lerp(
                                 startValue ?: FONT_ITALIC_DEFAULT_VALUE,
                                 endValue ?: FONT_ITALIC_DEFAULT_VALUE,
-                                progress
+                                progress,
                             )
                         )
                     else -> {
@@ -152,32 +145,31 @@
 
         // Check if we already make font for this axes. This is typically happens if the animation
         // happens backward.
-        tmpVarFontKey.set(start, newAxes)
-        val axesCachedFont = verFontCache[tmpVarFontKey]
-        if (axesCachedFont != null) {
-            interpCache.put(InterpKey(start, end, progress), axesCachedFont)
+        val vKey = VarFontKey(start, newAxes)
+        fontCache.get(vKey)?.let {
+            fontCache.put(iKey, it)
             if (DEBUG) {
-                Log.d(LOG_TAG, "[$progress] Axis cache hit for $tmpVarFontKey")
+                Log.d(LOG_TAG, "[$progress] Axis cache hit for $vKey")
             }
-            return axesCachedFont
+            return it
         }
 
         // This is the first time to make the font for the axes. Build and store it to the cache.
         // Font.Builder#build won't throw IOException since creating fonts from existing fonts will
         // not do any IO work.
         val newFont = Font.Builder(start).setFontVariationSettings(newAxes.toTypedArray()).build()
-        interpCache.put(InterpKey(start, end, progress), newFont)
-        verFontCache.put(VarFontKey(start, newAxes), newFont)
+        fontCache.put(iKey, newFont)
+        fontCache.put(vKey, newFont)
 
         // Cache misses are likely to create memory leaks, so this is logged at error level.
-        Log.e(LOG_TAG, "[$progress] Cache MISS for $tmpInterpKey / $tmpVarFontKey")
+        Log.e(LOG_TAG, "[$progress] Cache MISS for $iKey / $vKey")
         return newFont
     }
 
     private fun lerp(
         start: Array<FontVariationAxis>,
         end: Array<FontVariationAxis>,
-        filter: (tag: String, left: Float?, right: Float?) -> Float
+        filter: (tag: String, left: Float?, right: Float?) -> Float,
     ): List<FontVariationAxis> {
         // Safe to modify result of Font#getAxes since it returns cloned object.
         start.sortBy { axis -> axis.tag }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
index 978943ae..eef26b6 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
@@ -35,6 +35,8 @@
 typealias GlyphCallback = (TextAnimator.PositionedGlyph, Float) -> Unit
 
 interface TypefaceVariantCache {
+    val fontCache: FontCache
+    val animationFrameCount: Int
     fun getTypefaceForVariant(fvar: String?): Typeface?
 
     companion object {
@@ -57,8 +59,10 @@
 
 class TypefaceVariantCacheImpl(
     var baseTypeface: Typeface,
+    override val animationFrameCount: Int,
 ) : TypefaceVariantCache {
     private val cache = LruCache<String, Typeface>(TYPEFACE_CACHE_MAX_ENTRIES)
+    override val fontCache = FontCacheImpl(animationFrameCount)
     override fun getTypefaceForVariant(fvar: String?): Typeface? {
         if (fvar == null) {
             return baseTypeface
@@ -100,25 +104,17 @@
  */
 class TextAnimator(
     layout: Layout,
-    numberOfAnimationSteps: Int? = null, // Only do this number of discrete animation steps.
-    private val invalidateCallback: () -> Unit,
+    private val typefaceCache: TypefaceVariantCache,
+    private val invalidateCallback: () -> Unit = {},
 ) {
-    var typefaceCache: TypefaceVariantCache = TypefaceVariantCacheImpl(layout.paint.typeface)
-        get() = field
-        set(value) {
-            field = value
-            textInterpolator.typefaceCache = value
-        }
-
     // Following two members are for mutable for testing purposes.
-    public var textInterpolator: TextInterpolator =
-        TextInterpolator(layout, typefaceCache, numberOfAnimationSteps)
-    public var animator: ValueAnimator =
+    public var textInterpolator = TextInterpolator(layout, typefaceCache)
+    public var animator =
         ValueAnimator.ofFloat(1f).apply {
             duration = DEFAULT_ANIMATION_DURATION
             addUpdateListener {
                 textInterpolator.progress =
-                    calculateProgress(it.animatedValue as Float, numberOfAnimationSteps)
+                    calculateProgress(it.animatedValue as Float, typefaceCache.animationFrameCount)
                 invalidateCallback()
             }
             addListener(
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
index 02caeed..9c0c0ff 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
@@ -28,11 +28,7 @@
 import java.lang.Math.max
 
 /** Provide text style linear interpolation for plain text. */
-class TextInterpolator(
-    layout: Layout,
-    var typefaceCache: TypefaceVariantCache,
-    numberOfAnimationSteps: Int? = null,
-) {
+class TextInterpolator(layout: Layout, var typefaceCache: TypefaceVariantCache) {
     /**
      * Returns base paint used for interpolation.
      *
@@ -66,7 +62,7 @@
         val start: Int, // inclusive
         val end: Int, // exclusive
         var baseFont: Font,
-        var targetFont: Font
+        var targetFont: Font,
     ) {
         val length: Int
             get() = end - start
@@ -79,14 +75,14 @@
         val baseY: FloatArray, // same length as glyphIds
         val targetX: FloatArray, // same length as glyphIds
         val targetY: FloatArray, // same length as glyphIds
-        val fontRuns: List<FontRun>
+        val fontRuns: List<FontRun>,
     )
 
     /** A class represents text layout of a single line. */
     private class Line(val runs: List<Run>)
 
     private var lines = listOf<Line>()
-    private val fontInterpolator = FontInterpolator(numberOfAnimationSteps)
+    private val fontInterpolator = FontInterpolator(typefaceCache.fontCache)
 
     // Recycling object for glyph drawing and tweaking.
     private val tmpPaint = TextPaint()
@@ -343,12 +339,16 @@
     private class MutablePositionedGlyph : TextAnimator.PositionedGlyph() {
         override var runStart: Int = 0
             public set
+
         override var runLength: Int = 0
             public set
+
         override var glyphIndex: Int = 0
             public set
+
         override lateinit var font: Font
             public set
+
         override var glyphId: Int = 0
             public set
     }
@@ -401,7 +401,7 @@
                     0,
                     i - prevStart,
                     font,
-                    tmpPaintForGlyph
+                    tmpPaintForGlyph,
                 )
                 prevStart = i
                 arrayIndex = 0
@@ -418,13 +418,13 @@
             0,
             run.end - prevStart,
             font,
-            tmpPaintForGlyph
+            tmpPaintForGlyph,
         )
     }
 
     private fun updatePositionsAndFonts(
         layoutResult: List<List<PositionedGlyphs>>,
-        updateBase: Boolean
+        updateBase: Boolean,
     ) {
         // Update target positions with newly calculated text layout.
         check(layoutResult.size == lines.size) { "The new layout result has different line count." }
@@ -507,7 +507,7 @@
                 lineStart,
                 count,
                 layout.textDirectionHeuristic,
-                paint
+                paint,
             ) { _, _, glyphs, _ ->
                 runs.add(glyphs)
             }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
index de4bdbc..e2bc409 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
@@ -114,16 +114,16 @@
             )
         }
 
-        internal fun assertReturnAnimations() {
+        fun assertReturnAnimations() {
             check(returnAnimationsEnabled()) {
                 "isLaunching cannot be false when the returnAnimationFrameworkLibrary flag " +
                     "is disabled"
             }
         }
 
-        internal fun returnAnimationsEnabled() = returnAnimationFrameworkLibrary()
+        fun returnAnimationsEnabled() = returnAnimationFrameworkLibrary()
 
-        internal fun assertLongLivedReturnAnimations() {
+        fun assertLongLivedReturnAnimations() {
             check(longLivedReturnAnimationsEnabled()) {
                 "Long-lived registrations cannot be used when the " +
                     "returnAnimationFrameworkLibrary or the " +
@@ -131,7 +131,7 @@
             }
         }
 
-        internal fun longLivedReturnAnimationsEnabled() =
+        fun longLivedReturnAnimationsEnabled() =
             returnAnimationFrameworkLibrary() && returnAnimationFrameworkLongLived()
 
         internal fun WindowAnimationState.toTransitionState() =
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt
index 6c982a0..9e872fc 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt
@@ -58,7 +58,12 @@
         val maxTranslationY = maxTranslationYByScale - maxMarginYPx
         val minScaleReversed = 1f - minScale
 
-        val direction = if (backEvent.swipeEdge == BackEvent.EDGE_LEFT) 1 else -1
+        val direction =
+            when (backEvent.swipeEdge) {
+                BackEvent.EDGE_LEFT -> 1
+                BackEvent.EDGE_RIGHT -> -1
+                else -> 0
+            }
         val progressX = backEvent.progress
 
         val ratioTranslateX = translateXEasing.getInterpolation(progressX)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 87e9c42..4705d8d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -44,6 +44,7 @@
 import com.android.compose.animation.scene.Swipe
 import com.android.compose.animation.scene.observableTransitionState
 import com.android.compose.animation.scene.transitions
+import com.android.systemui.Flags.communalHubOnMobile
 import com.android.systemui.communal.shared.model.CommunalBackgroundType
 import com.android.systemui.communal.shared.model.CommunalScenes
 import com.android.systemui.communal.shared.model.CommunalTransitionKeys
@@ -186,15 +187,19 @@
     ) {
         scene(
             CommunalScenes.Blank,
-            userActions = mapOf(Swipe.Start(fromSource = Edge.End) to CommunalScenes.Communal),
+            userActions =
+                if (communalHubOnMobile()) emptyMap()
+                else mapOf(Swipe.Start(fromSource = Edge.End) to CommunalScenes.Communal),
         ) {
             // This scene shows nothing only allowing for transitions to the communal scene.
             Box(modifier = Modifier.fillMaxSize())
         }
 
-        val userActions = mapOf(Swipe.End to CommunalScenes.Blank)
-
-        scene(CommunalScenes.Communal, userActions = userActions) {
+        scene(
+            CommunalScenes.Communal,
+            userActions =
+                if (communalHubOnMobile()) emptyMap() else mapOf(Swipe.End to CommunalScenes.Blank),
+        ) {
             CommunalScene(
                 backgroundType = backgroundType,
                 colors = colors,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index 5b1203f..787edfb 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -141,6 +141,7 @@
 import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.customActions
+import androidx.compose.ui.semantics.heading
 import androidx.compose.ui.semantics.onClick
 import androidx.compose.ui.semantics.paneTitle
 import androidx.compose.ui.semantics.semantics
@@ -902,11 +903,17 @@
                 Arrangement.spacedBy(Dimensions.Spacing, Alignment.CenterVertically),
             horizontalAlignment = Alignment.CenterHorizontally,
         ) {
+            val titleForEmptyStateCTA = stringResource(R.string.title_for_empty_state_cta)
             Text(
-                text = stringResource(R.string.title_for_empty_state_cta),
+                text = titleForEmptyStateCTA,
                 style = MaterialTheme.typography.displaySmall,
                 textAlign = TextAlign.Center,
                 color = colors.secondary,
+                modifier =
+                    Modifier.focusable().semantics(mergeDescendants = true) {
+                        contentDescription = titleForEmptyStateCTA
+                        heading()
+                    },
             )
             Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
                 Button(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalTouchableSurface.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalTouchableSurface.kt
index 3707a87..f2edec6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalTouchableSurface.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalTouchableSurface.kt
@@ -27,6 +27,8 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.key.onPreviewKeyEvent
 import androidx.compose.ui.input.pointer.motionEventSpy
+import androidx.compose.ui.semantics.hideFromAccessibility
+import androidx.compose.ui.semantics.semantics
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
 
 @OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
@@ -42,6 +44,9 @@
     Box(
         modifier =
             modifier
+                // The touchable surface is hidden for accessibility because these actions are
+                // already provided through custom accessibility actions.
+                .semantics { hideFromAccessibility() }
                 .combinedClickable(
                     onLongClick = viewModel::onLongClick,
                     onClick = viewModel::onClick,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
index ef5e90b..7a50080 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
@@ -94,7 +94,7 @@
     private val scope: CoroutineScope,
     private val updateDragPositionForRemove: (draggingBoundingBox: IntRect) -> Boolean,
 ) {
-    var draggingItemKey by mutableStateOf<Any?>(null)
+    var draggingItemKey by mutableStateOf<String?>(null)
         private set
 
     var isDraggingToRemove by mutableStateOf(false)
@@ -138,7 +138,7 @@
             // before content padding from the initial pointer position
             .firstItemAtOffset(normalizedOffset - contentOffset)
             ?.apply {
-                draggingItemKey = key
+                draggingItemKey = key as String
                 draggingItemInitialOffset = this.offset.toOffset()
                 return true
             }
@@ -284,7 +284,9 @@
                             contentOffset,
                         )
                     ) {
-                        viewModel.onReorderWidgetStart()
+                        // draggingItemKey is guaranteed to be non-null here because it is set in
+                        // onDragStart()
+                        viewModel.onReorderWidgetStart(dragDropState.draggingItemKey!!)
                     }
                 },
                 onDragEnd = {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
index 2a2c2fc..105e8da 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
@@ -21,7 +21,6 @@
 import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
@@ -70,10 +69,7 @@
     override val id: String = "default"
 
     @Composable
-    override fun SceneScope.Content(
-        viewModel: LockscreenContentViewModel,
-        modifier: Modifier,
-    ) {
+    override fun SceneScope.Content(viewModel: LockscreenContentViewModel, modifier: Modifier) {
         val isUdfpsVisible = viewModel.isUdfpsVisible
         val isShadeLayoutWide by viewModel.isShadeLayoutWide.collectAsStateWithLifecycle()
         val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle()
@@ -85,22 +81,18 @@
             with(notificationSection) { HeadsUpNotifications() }
         }
 
-        LockscreenLongPress(
-            viewModel = viewModel.touchHandling,
-            modifier = modifier,
-        ) { onSettingsMenuPlaced ->
+        LockscreenLongPress(viewModel = viewModel.touchHandling, modifier = modifier) {
+            onSettingsMenuPlaced ->
             Layout(
                 content = {
                     // Constrained to above the lock icon.
-                    Column(
-                        modifier = Modifier.fillMaxSize(),
-                    ) {
+                    Column(modifier = Modifier.fillMaxSize()) {
                         with(statusBarSection) {
                             StatusBar(
                                 modifier =
                                     Modifier.fillMaxWidth()
                                         .padding(
-                                            horizontal = { unfoldTranslations.start.roundToInt() },
+                                            horizontal = { unfoldTranslations.start.roundToInt() }
                                         )
                             )
                         }
@@ -109,13 +101,14 @@
                             with(topAreaSection) {
                                 DefaultClockLayout(
                                     smartSpacePaddingTop = viewModel::getSmartSpacePaddingTop,
+                                    isShadeLayoutWide = isShadeLayoutWide,
                                     modifier =
                                         Modifier.thenIf(isShadeLayoutWide) {
                                                 Modifier.fillMaxWidth(0.5f)
                                             }
                                             .graphicsLayer {
                                                 translationX = unfoldTranslations.start
-                                            }
+                                            },
                                 )
                             }
                             if (isShadeLayoutWide && !isBypassEnabled) {
@@ -127,7 +120,7 @@
                                         modifier =
                                             Modifier.fillMaxWidth(0.5f)
                                                 .fillMaxHeight()
-                                                .align(alignment = Alignment.TopEnd)
+                                                .align(alignment = Alignment.TopEnd),
                                     )
                                 }
                             }
@@ -142,7 +135,7 @@
                                     AodNotificationIcons(
                                         modifier =
                                             Modifier.align(alignment = Alignment.TopStart)
-                                                .padding(start = aodIconPadding),
+                                                .padding(start = aodIconPadding)
                                     )
                                     Notifications(
                                         areNotificationsVisible = areNotificationsVisible,
@@ -152,7 +145,7 @@
                                 }
                             } else {
                                 AodNotificationIcons(
-                                    modifier = Modifier.padding(start = aodIconPadding),
+                                    modifier = Modifier.padding(start = aodIconPadding)
                                 )
                             }
                         }
@@ -205,11 +198,7 @@
                 val endShortcutMeasurable = measurables[4]
                 val settingsMenuMeasurable = measurables[5]
 
-                val noMinConstraints =
-                    constraints.copy(
-                        minWidth = 0,
-                        minHeight = 0,
-                    )
+                val noMinConstraints = constraints.copy(minWidth = 0, minHeight = 0)
                 val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints)
                 val lockIconBounds =
                     IntRect(
@@ -235,14 +224,8 @@
                 val settingsMenuPlaceable = settingsMenuMeasurable.measure(noMinConstraints)
 
                 layout(constraints.maxWidth, constraints.maxHeight) {
-                    aboveLockIconPlaceable.place(
-                        x = 0,
-                        y = 0,
-                    )
-                    lockIconPlaceable.place(
-                        x = lockIconBounds.left,
-                        y = lockIconBounds.top,
-                    )
+                    aboveLockIconPlaceable.place(x = 0, y = 0)
+                    lockIconPlaceable.place(x = lockIconBounds.left, y = lockIconBounds.top)
                     belowLockIconPlaceable.place(
                         x = 0,
                         y = constraints.maxHeight - belowLockIconPlaceable.height,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt
index 3ca2b9c..4a9f44b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt
@@ -17,9 +17,11 @@
 package com.android.systemui.keyguard.ui.composable.section
 
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.dimensionResource
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.animation.scene.SceneScope
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardMediaViewModel
@@ -27,6 +29,7 @@
 import com.android.systemui.media.controls.ui.controller.MediaCarouselController
 import com.android.systemui.media.controls.ui.view.MediaHost
 import com.android.systemui.media.dagger.MediaModule
+import com.android.systemui.res.R
 import javax.inject.Inject
 import javax.inject.Named
 
@@ -39,13 +42,22 @@
 ) {
 
     @Composable
-    fun SceneScope.KeyguardMediaCarousel() {
+    fun SceneScope.KeyguardMediaCarousel(
+        isShadeLayoutWide: Boolean,
+        modifier: Modifier = Modifier,
+    ) {
         val isMediaVisible by keyguardMediaViewModel.isMediaVisible.collectAsStateWithLifecycle()
-
+        val horizontalPadding =
+            if (isShadeLayoutWide) {
+                dimensionResource(id = R.dimen.notification_side_paddings)
+            } else {
+                dimensionResource(id = R.dimen.notification_side_paddings) +
+                    dimensionResource(id = R.dimen.notification_panel_margin_horizontal)
+            }
         MediaCarousel(
             isVisible = isMediaVisible,
             mediaHost = mediaHost,
-            modifier = Modifier.fillMaxWidth(),
+            modifier = modifier.fillMaxWidth().padding(horizontal = horizontalPadding),
             carouselController = mediaCarouselController,
         )
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
index afa92f2..db33e7c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
@@ -63,6 +63,7 @@
     @Composable
     fun SceneScope.DefaultClockLayout(
         smartSpacePaddingTop: (Resources) -> Int,
+        isShadeLayoutWide: Boolean,
         modifier: Modifier = Modifier,
     ) {
         val currentClockLayout by clockViewModel.currentClockLayout.collectAsStateWithLifecycle()
@@ -128,7 +129,7 @@
                     )
                 }
             }
-            with(mediaCarouselSection) { KeyguardMediaCarousel() }
+            with(mediaCarouselSection) { KeyguardMediaCarousel(isShadeLayoutWide) }
         }
     }
 
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
index e725ce5..58336c2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
@@ -79,8 +79,8 @@
         val MediaLandscapeTopOffset = ValueKey("MediaLandscapeTopOffset")
 
         object MediaOffset {
-            // Brightness + padding
-            val InQS = 92.dp
+            // Brightness
+            val InQS = 60.dp
             val Default = 0.dp
 
             @Composable
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 0e7165c..52adaf2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -74,6 +74,7 @@
 import com.android.compose.animation.scene.animateSceneDpAsState
 import com.android.compose.animation.scene.animateSceneFloatAsState
 import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.modifiers.padding
 import com.android.compose.modifiers.thenIf
 import com.android.compose.windowsizeclass.LocalWindowSizeClass
 import com.android.systemui.battery.BatteryMeterViewController
@@ -379,7 +380,11 @@
                             mediaHost = mediaHost,
                             modifier =
                                 Modifier.fillMaxWidth()
-                                    .layoutId(QSMediaMeasurePolicy.LayoutId.Media),
+                                    .layoutId(QSMediaMeasurePolicy.LayoutId.Media)
+                                    .padding(
+                                        horizontal =
+                                            dimensionResource(id = R.dimen.qs_horizontal_margin)
+                                    ),
                             carouselController = mediaCarouselController,
                         )
                     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
index 26c827a..3fce890 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
@@ -44,8 +44,11 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.rememberViewModel
 import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace
+import com.android.systemui.plugins.qs.TileDetailsViewModel
 import com.android.systemui.qs.composefragment.ui.GridAnchor
+import com.android.systemui.qs.flags.QsDetailedView
 import com.android.systemui.qs.panels.ui.compose.EditMode
+import com.android.systemui.qs.panels.ui.compose.TileDetails
 import com.android.systemui.qs.panels.ui.compose.TileGrid
 import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
 import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeOverlayActionsViewModel
@@ -116,24 +119,50 @@
     }
 }
 
+// A sealed interface to represent the possible states of the `ShadeBody`
+sealed interface ShadeBodyState {
+    data object Editing : ShadeBodyState
+    data object TileDetails : ShadeBodyState
+    data object Default : ShadeBodyState
+}
+
+// Function to map the current state of the `ShadeBody`
+fun checkQsState(isEditing: Boolean, tileDetails: TileDetailsViewModel?): ShadeBodyState {
+    if (isEditing) {
+        return ShadeBodyState.Editing
+    } else if (tileDetails != null && QsDetailedView.isEnabled) {
+        return ShadeBodyState.TileDetails
+    }
+    return ShadeBodyState.Default
+}
+
 @Composable
 fun SceneScope.ShadeBody(viewModel: QuickSettingsContainerViewModel) {
     val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle()
+    val tileDetails = viewModel.detailsViewModel.activeTileDetails
 
     AnimatedContent(
-        targetState = isEditing,
+        targetState = checkQsState(isEditing, tileDetails),
         transitionSpec = { fadeIn(tween(500)) togetherWith fadeOut(tween(500)) },
-    ) { editing ->
-        if (editing) {
-            EditMode(
-                viewModel = viewModel.editModeViewModel,
-                modifier = Modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding),
-            )
-        } else {
-            QuickSettingsLayout(
-                viewModel = viewModel,
-                modifier = Modifier.sysuiResTag("quick_settings_panel"),
-            )
+    ) { state ->
+        when (state) {
+            ShadeBodyState.Editing -> {
+                EditMode(
+                    viewModel = viewModel.editModeViewModel,
+                    modifier = Modifier
+                        .fillMaxWidth()
+                        .padding(QuickSettingsShade.Dimensions.Padding),
+                )
+            }
+            ShadeBodyState.TileDetails -> {
+                TileDetails(viewModel.detailsViewModel)
+            }
+            else -> {
+                QuickSettingsLayout(
+                    viewModel = viewModel,
+                    modifier = Modifier.sysuiResTag("quick_settings_panel"),
+                )
+            }
         }
     }
 }
@@ -168,7 +197,6 @@
                 modifier =
                     Modifier.fillMaxWidth()
                         .heightIn(max = QuickSettingsShade.Dimensions.GridMaxHeight),
-                viewModel.editModeViewModel::startEditing,
             )
         }
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index ae5dd8a..5fb9416 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -19,12 +19,17 @@
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import com.android.compose.animation.scene.SceneScope
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.compose.animation.scene.animateContentDpAsState
 import com.android.compose.animation.scene.animateContentFloatAsState
+import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.rememberViewModel
@@ -63,9 +68,25 @@
     }
 
     @Composable
-    override fun SceneScope.Content(
-        modifier: Modifier,
-    ) {
+    override fun SceneScope.Content(modifier: Modifier) {
+
+        val isIdle by remember {
+            derivedStateOf { layoutState.transitionState is TransitionState.Idle }
+        }
+
+        LaunchedEffect(isIdle) {
+            // Wait for being Idle on this Scene, otherwise LaunchedEffect would fire too soon,
+            // and another transition could override the NSSL stack bounds.
+            if (isIdle) {
+                // Reset the stack bounds to avoid caching these values from the previous Scenes,
+                // and not to confuse the StackScrollAlgorithm when it displays a HUN over GONE.
+                notificationStackScrolLView.get().apply {
+                    setStackTop(0f)
+                    setStackCutoff(0f)
+                }
+            }
+        }
+
         animateContentFloatAsState(
             value = QuickSettings.SharedValues.SquishinessValues.GoneSceneStarting,
             key = QuickSettings.SharedValues.TilesSquishiness,
@@ -75,9 +96,7 @@
         SnoozeableHeadsUpNotificationSpace(
             stackScrollView = notificationStackScrolLView.get(),
             viewModel =
-                rememberViewModel("GoneScene") {
-                    notificationsPlaceholderViewModelFactory.create()
-                },
+                rememberViewModel("GoneScene") { notificationsPlaceholderViewModelFactory.create() },
         )
     }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 2d58c8c..a266e7e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -49,7 +49,6 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
 import javax.inject.Provider
-import kotlinx.coroutines.flow.collectLatest
 
 /**
  * Renders a container of a collection of "scenes" that the user can switch between using certain
@@ -117,7 +116,7 @@
                 ) {
                     "invalid ContentKey: $actionableContentKey"
                 }
-            actionableContent.userActions.collectLatest { userActions ->
+            viewModel.filteredUserActions(actionableContent.userActions).collect { userActions ->
                 userActionsByContentKey[actionableContentKey] =
                     viewModel.resolveSceneFamilies(userActions)
             }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
index 05a0119..bfcde7d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
@@ -130,10 +130,6 @@
     modifier: Modifier = Modifier,
 ) {
     val viewModel = rememberViewModel("CollapsedShadeHeader") { viewModelFactory.create() }
-    val isDisabled by viewModel.isDisabled.collectAsStateWithLifecycle()
-    if (isDisabled) {
-        return
-    }
 
     val cutoutWidth = LocalDisplayCutout.current.width()
     val cutoutHeight = LocalDisplayCutout.current.height()
@@ -196,7 +192,7 @@
                             horizontalArrangement = Arrangement.End,
                             modifier =
                                 Modifier.element(ShadeHeader.Elements.CollapsedContentEnd)
-                                    .padding(horizontal = horizontalPadding)
+                                    .padding(horizontal = horizontalPadding),
                         ) {
                             if (isLargeScreenLayout) {
                                 ShadeCarrierGroup(
@@ -207,7 +203,7 @@
                             SystemIconContainer(
                                 viewModel = viewModel,
                                 isClickable = isLargeScreenLayout,
-                                modifier = Modifier.align(Alignment.CenterVertically)
+                                modifier = Modifier.align(Alignment.CenterVertically),
                             ) {
                                 StatusIcons(
                                     viewModel = viewModel,
@@ -217,7 +213,7 @@
                                     modifier =
                                         Modifier.align(Alignment.CenterVertically)
                                             .padding(end = 6.dp)
-                                            .weight(1f, fill = false)
+                                            .weight(1f, fill = false),
                                 )
                                 BatteryIcon(
                                     createBatteryMeterViewController =
@@ -252,27 +248,15 @@
                 CutoutLocation.NONE,
                 CutoutLocation.RIGHT -> {
                     startPlaceable.placeRelative(x = 0, y = 0)
-                    endPlaceable.placeRelative(
-                        x = startPlaceable.width,
-                        y = 0,
-                    )
+                    endPlaceable.placeRelative(x = startPlaceable.width, y = 0)
                 }
                 CutoutLocation.CENTER -> {
                     startPlaceable.placeRelative(x = 0, y = 0)
-                    endPlaceable.placeRelative(
-                        x = startPlaceable.width + cutoutWidthPx,
-                        y = 0,
-                    )
+                    endPlaceable.placeRelative(x = startPlaceable.width + cutoutWidthPx, y = 0)
                 }
                 CutoutLocation.LEFT -> {
-                    startPlaceable.placeRelative(
-                        x = cutoutWidthPx,
-                        y = 0,
-                    )
-                    endPlaceable.placeRelative(
-                        x = startPlaceable.width + cutoutWidthPx,
-                        y = 0,
-                    )
+                    startPlaceable.placeRelative(x = cutoutWidthPx, y = 0)
+                    endPlaceable.placeRelative(x = startPlaceable.width + cutoutWidthPx, y = 0)
                 }
             }
         }
@@ -288,10 +272,6 @@
     modifier: Modifier = Modifier,
 ) {
     val viewModel = rememberViewModel("ExpandedShadeHeader") { viewModelFactory.create() }
-    val isDisabled by viewModel.isDisabled.collectAsStateWithLifecycle()
-    if (isDisabled) {
-        return
-    }
 
     val useExpandedFormat by remember {
         derivedStateOf { shouldUseExpandedFormat(layoutState.transitionState) }
@@ -302,17 +282,14 @@
     Box(modifier = modifier.sysuiResTag(ShadeHeader.TestTags.Root)) {
         if (isPrivacyChipVisible) {
             Box(modifier = Modifier.height(CollapsedHeight).fillMaxWidth()) {
-                PrivacyChip(
-                    viewModel = viewModel,
-                    modifier = Modifier.align(Alignment.CenterEnd),
-                )
+                PrivacyChip(viewModel = viewModel, modifier = Modifier.align(Alignment.CenterEnd))
             }
         }
         Column(
             verticalArrangement = Arrangement.Bottom,
             modifier =
                 Modifier.fillMaxWidth()
-                    .defaultMinSize(minHeight = ShadeHeader.Dimensions.ExpandedHeight)
+                    .defaultMinSize(minHeight = ShadeHeader.Dimensions.ExpandedHeight),
         ) {
             Box(modifier = Modifier.fillMaxWidth()) {
                 Box {
@@ -362,11 +339,7 @@
 }
 
 @Composable
-private fun SceneScope.Clock(
-    scale: Float,
-    viewModel: ShadeHeaderViewModel,
-    modifier: Modifier,
-) {
+private fun SceneScope.Clock(scale: Float, viewModel: ShadeHeaderViewModel, modifier: Modifier) {
     val layoutDirection = LocalLayoutDirection.current
 
     Element(key = ShadeHeader.Elements.Clock, modifier = modifier) {
@@ -391,10 +364,10 @@
                                     LayoutDirection.Ltr -> 0f
                                     LayoutDirection.Rtl -> 1f
                                 },
-                                0.5f
+                                0.5f,
                             )
                     }
-                    .clickable { viewModel.onClockClicked() }
+                    .clickable { viewModel.onClockClicked() },
         )
     }
 }
@@ -447,10 +420,7 @@
 }
 
 @Composable
-private fun ShadeCarrierGroup(
-    viewModel: ShadeHeaderViewModel,
-    modifier: Modifier = Modifier,
-) {
+private fun ShadeCarrierGroup(viewModel: ShadeHeaderViewModel, modifier: Modifier = Modifier) {
     Row(modifier = modifier) {
         val subIds by viewModel.mobileSubIds.collectAsStateWithLifecycle()
 
@@ -465,11 +435,11 @@
                             viewModel =
                                 (viewModel.mobileIconsViewModel.viewModelForSub(
                                     subId,
-                                    StatusBarLocation.SHADE_CARRIER_GROUP
+                                    StatusBarLocation.SHADE_CARRIER_GROUP,
                                 ) as ShadeCarrierGroupMobileIconViewModel),
                         )
                         .also { it.setOnClickListener { viewModel.onShadeCarrierGroupClicked() } }
-                },
+                }
             )
         }
     }
@@ -506,7 +476,7 @@
                 Utils.getColorAttrDefaultColor(themedContext, android.R.attr.textColorPrimary),
                 Utils.getColorAttrDefaultColor(
                     themedContext,
-                    android.R.attr.textColorPrimaryInverse
+                    android.R.attr.textColorPrimaryInverse,
                 ),
             )
             statusBarIconController.addIconGroup(iconManager)
@@ -551,7 +521,7 @@
     viewModel: ShadeHeaderViewModel,
     isClickable: Boolean,
     modifier: Modifier = Modifier,
-    content: @Composable RowScope.() -> Unit
+    content: @Composable RowScope.() -> Unit,
 ) {
     val interactionSource = remember { MutableInteractionSource() }
     val isHovered by interactionSource.collectIsHoveredAsState()
@@ -578,10 +548,7 @@
 }
 
 @Composable
-private fun SceneScope.PrivacyChip(
-    viewModel: ShadeHeaderViewModel,
-    modifier: Modifier = Modifier,
-) {
+private fun SceneScope.PrivacyChip(viewModel: ShadeHeaderViewModel, modifier: Modifier = Modifier) {
     val privacyList by viewModel.privacyItems.collectAsStateWithLifecycle()
 
     AndroidView(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index bba3d69..22b6dbc 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -270,6 +270,7 @@
         )
     val isEmptySpaceClickable by viewModel.isEmptySpaceClickable.collectAsStateWithLifecycle()
     val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle()
+    val isQsEnabled by viewModel.isQsEnabled.collectAsStateWithLifecycle()
 
     val shouldPunchHoleBehindScrim =
         layoutState.isTransitioningBetween(Scenes.Gone, Scenes.Shade) ||
@@ -353,14 +354,26 @@
                     )
                 }
 
+                val qqsLayoutPaddingBottom =
+                    dimensionResource(id = R.dimen.qqs_layout_padding_bottom)
                 ShadeMediaCarousel(
                     isVisible = isMediaVisible,
                     isInRow = mediaInRow,
                     mediaHost = mediaHost,
                     mediaOffsetProvider = mediaOffsetProvider,
                     carouselController = mediaCarouselController,
-                    modifier = Modifier.layoutId(SingleShadeMeasurePolicy.LayoutId.Media),
+                    modifier =
+                        Modifier.layoutId(SingleShadeMeasurePolicy.LayoutId.Media)
+                            .padding(
+                                horizontal =
+                                    shadeHorizontalPadding +
+                                        dimensionResource(id = R.dimen.qs_horizontal_margin)
+                            )
+                            .thenIf(!mediaInRow) {
+                                Modifier.padding(bottom = qqsLayoutPaddingBottom)
+                            },
                     usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia,
+                    isQsEnabled = isQsEnabled,
                     isInSplitShade = false,
                 )
 
@@ -416,6 +429,7 @@
     val screenCornerRadius = LocalScreenCornerRadius.current
 
     val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsStateWithLifecycle()
+    val isQsEnabled by viewModel.isQsEnabled.collectAsStateWithLifecycle()
     val isCustomizerShowing by
         viewModel.qsSceneAdapter.isCustomizerShowing.collectAsStateWithLifecycle()
     val customizingAnimationDuration by
@@ -562,11 +576,16 @@
                                 mediaOffsetProvider = mediaOffsetProvider,
                                 modifier =
                                     Modifier.thenIf(
-                                        MediaContentPicker.shouldElevateMedia(layoutState)
-                                    ) {
-                                        Modifier.zIndex(1f)
-                                    },
+                                            MediaContentPicker.shouldElevateMedia(layoutState)
+                                        ) {
+                                            Modifier.zIndex(1f)
+                                        }
+                                        .padding(
+                                            horizontal =
+                                                dimensionResource(id = R.dimen.qs_horizontal_margin)
+                                        ),
                                 carouselController = mediaCarouselController,
+                                isQsEnabled = isQsEnabled,
                                 isInSplitShade = true,
                             )
                         }
@@ -620,10 +639,14 @@
     mediaHost: MediaHost,
     carouselController: MediaCarouselController,
     mediaOffsetProvider: ShadeMediaOffsetProvider,
+    isInSplitShade: Boolean,
+    isQsEnabled: Boolean,
     modifier: Modifier = Modifier,
     usingCollapsedLandscapeMedia: Boolean = false,
-    isInSplitShade: Boolean,
 ) {
+    if (!isQsEnabled) {
+        return
+    }
     MediaCarousel(
         modifier = modifier.fillMaxWidth(),
         isVisible = isVisible,
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 04c5271..cf0ba51 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
@@ -30,8 +30,7 @@
 import com.android.compose.nestedscroll.PriorityNestedScrollConnection
 import com.android.compose.nestedscroll.ScrollController
 import kotlin.math.absoluteValue
-
-internal typealias SuspendedValue<T> = suspend () -> T
+import kotlinx.coroutines.launch
 
 internal interface DraggableHandler {
     /**
@@ -50,6 +49,7 @@
     /**
      * Drag the current scene by [delta] pixels.
      *
+     * @param delta The distance to drag the scene in pixels.
      * @return the consumed [delta]
      */
     fun onDrag(delta: Float): Float
@@ -57,9 +57,18 @@
     /**
      * Stop the current drag with the given [velocity].
      *
+     * @param velocity The velocity of the drag when it stopped.
+     * @param canChangeContent Whether the content can be changed as a result of this drag.
      * @return the consumed [velocity] when the animation complete
      */
-    fun onStop(velocity: Float, canChangeContent: Boolean): SuspendedValue<Float>
+    suspend fun onStop(velocity: Float, canChangeContent: Boolean): Float
+
+    /**
+     * Cancels the current drag.
+     *
+     * @param canChangeContent Whether the content can be changed as a result of this drag.
+     */
+    fun onCancel(canChangeContent: Boolean)
 }
 
 internal class DraggableHandlerImpl(
@@ -350,7 +359,7 @@
         val result = swipes.findUserActionResult(directionOffset = newOffset)
 
         if (result == null) {
-            onStop(velocity = delta, canChangeContent = true)
+            onCancel(canChangeContent = true)
             return 0f
         }
 
@@ -379,11 +388,11 @@
         return consumedDelta
     }
 
-    override fun onStop(velocity: Float, canChangeContent: Boolean): SuspendedValue<Float> {
+    override suspend fun onStop(velocity: Float, canChangeContent: Boolean): Float {
         return onStop(velocity, canChangeContent, swipeAnimation)
     }
 
-    private fun <T : ContentKey> onStop(
+    private suspend fun <T : ContentKey> onStop(
         velocity: Float,
         canChangeContent: Boolean,
 
@@ -392,24 +401,23 @@
         // callbacks (like onAnimationCompleted()) might incorrectly finish a new transition that
         // replaced this one.
         swipeAnimation: SwipeAnimation<T>,
-    ): SuspendedValue<Float> {
+    ): Float {
         // The state was changed since the drag started; don't do anything.
         if (!isDrivingTransition || swipeAnimation.isAnimatingOffset()) {
-            return { 0f }
+            return 0f
         }
 
         val fromContent = swipeAnimation.fromContent
-        val consumedVelocity: SuspendedValue<Float>
-        if (canChangeContent) {
-            // If we are halfway between two contents, we check what the target will be based on the
-            // velocity and offset of the transition, then we launch the animation.
+        val targetContent =
+            if (canChangeContent) {
+                // If we are halfway between two contents, we check what the target will be based on
+                // the velocity and offset of the transition, then we launch the animation.
 
-            val toContent = swipeAnimation.toContent
+                val toContent = swipeAnimation.toContent
 
-            // Compute the destination content (and therefore offset) to settle in.
-            val offset = swipeAnimation.dragOffset
-            val distance = swipeAnimation.distance()
-            val targetContent =
+                // Compute the destination content (and therefore offset) to settle in.
+                val offset = swipeAnimation.dragOffset
+                val distance = swipeAnimation.distance()
                 if (
                     distance != DistanceUnspecified &&
                         shouldCommitSwipe(
@@ -424,16 +432,15 @@
                 } else {
                     fromContent
                 }
-            consumedVelocity = swipeAnimation.animateOffset(velocity, targetContent = targetContent)
-        } else {
-            // We are doing an overscroll preview animation between scenes.
-            check(fromContent == swipeAnimation.currentContent) {
-                "canChangeContent is false but currentContent != fromContent"
+            } else {
+                // We are doing an overscroll preview animation between scenes.
+                check(fromContent == swipeAnimation.currentContent) {
+                    "canChangeContent is false but currentContent != fromContent"
+                }
+                fromContent
             }
-            consumedVelocity = swipeAnimation.animateOffset(velocity, targetContent = fromContent)
-        }
 
-        return consumedVelocity
+        return swipeAnimation.animateOffset(velocity, targetContent)
     }
 
     /**
@@ -478,6 +485,12 @@
                 isCloserToTarget()
         }
     }
+
+    override fun onCancel(canChangeContent: Boolean) {
+        swipeAnimation.contentTransition.coroutineScope.launch {
+            onStop(velocity = 0f, canChangeContent = canChangeContent)
+        }
+    }
 }
 
 /** The [Swipe] associated to a given fromScene, startedPosition and pointersDown. */
@@ -701,13 +714,14 @@
         }
 
         override suspend fun OnStopScope.onStop(initialVelocity: Float): Float {
-            return dragController
-                .onStop(velocity = initialVelocity, canChangeContent = canChangeScene)
-                .invoke()
+            return dragController.onStop(
+                velocity = initialVelocity,
+                canChangeContent = canChangeScene,
+            )
         }
 
         override fun onCancel() {
-            dragController.onStop(velocity = 0f, canChangeContent = canChangeScene)
+            dragController.onCancel(canChangeScene)
         }
 
         /**
@@ -731,5 +745,9 @@
 private object NoOpDragController : DragController {
     override fun onDrag(delta: Float) = 0f
 
-    override fun onStop(velocity: Float, canChangeContent: Boolean) = suspend { 0f }
+    override suspend fun onStop(velocity: Float, canChangeContent: Boolean) = 0f
+
+    override fun onCancel(canChangeContent: Boolean) {
+        /* do nothing */
+    }
 }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
index 0db545f..59ac68b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
@@ -318,17 +318,13 @@
                                             velocityTracker.calculateVelocity(maxVelocity)
                                         }
                                         .toFloat(),
-                                onFling = {
-                                    controller.onStop(it, canChangeContent = true).invoke()
-                                },
+                                onFling = { controller.onStop(it, canChangeContent = true) },
                             )
                         },
                         onDragCancel = { controller ->
                             startFlingGesture(
                                 initialVelocity = 0f,
-                                onFling = {
-                                    controller.onStop(it, canChangeContent = true).invoke()
-                                },
+                                onFling = { controller.onStop(it, canChangeContent = true) },
                             )
                         },
                         swipeDetector = swipeDetector,
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 dbfeb5c..ae235e5 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
@@ -28,6 +28,7 @@
 import com.android.compose.animation.scene.content.state.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified
 import kotlin.math.absoluteValue
 import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.launch
 
 internal fun createSwipeAnimation(
     layoutState: MutableSceneTransitionLayoutStateImpl,
@@ -317,11 +318,11 @@
      *
      * @return the velocity consumed
      */
-    fun animateOffset(
+    suspend fun animateOffset(
         initialVelocity: Float,
         targetContent: T,
         spec: AnimationSpec<Float>? = null,
-    ): SuspendedValue<Float> {
+    ): Float {
         check(!isAnimatingOffset()) { "SwipeAnimation.animateOffset() can only be called once" }
 
         val initialProgress = progress
@@ -379,7 +380,7 @@
         if (skipAnimation) {
             // Unblock the job.
             offsetAnimationRunnable.complete(null)
-            return { 0f }
+            return 0f
         }
 
         val isTargetGreater = targetOffset > animatable.value
@@ -440,7 +441,7 @@
             }
         }
 
-        return { velocityConsumed.await() }
+        return velocityConsumed.await()
     }
 
     /** An exception thrown during the animation to stop it immediately. */
@@ -469,7 +470,9 @@
     fun freezeAndAnimateToCurrentState() {
         if (isAnimatingOffset()) return
 
-        animateOffset(initialVelocity = 0f, targetContent = currentContent)
+        contentTransition.coroutineScope.launch {
+            animateOffset(initialVelocity = 0f, targetContent = currentContent)
+        }
     }
 }
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt
index 2b33224..c6912d5 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt
@@ -145,7 +145,7 @@
     cancelSpec: AnimationSpec<Float>?,
     animationScope: CoroutineScope? = null,
 ) {
-    fun animateOffset(targetContent: T, spec: AnimationSpec<Float>?) {
+    suspend fun animateOffset(targetContent: T, spec: AnimationSpec<Float>?) {
         if (state.transitionState != animation.contentTransition || animation.isAnimatingOffset()) {
             return
         }
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 10057b2..a1077cf 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
@@ -45,6 +45,8 @@
 import com.android.compose.test.transition
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.async
 import kotlinx.coroutines.launch
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -266,7 +268,7 @@
         ) {
             val velocityConsumed = onDragStoppedAnimateLater(velocity, canChangeScene)
             onAnimationStart()
-            onAnimationEnd(velocityConsumed.invoke())
+            onAnimationEnd(velocityConsumed.await())
         }
 
         suspend fun DragController.onDragStoppedAnimateNow(
@@ -285,8 +287,10 @@
         fun DragController.onDragStoppedAnimateLater(
             velocity: Float,
             canChangeScene: Boolean = true,
-        ): SuspendedValue<Float> {
-            return onStop(velocity, canChangeScene)
+        ): Deferred<Float> {
+            val velocityConsumed = testScope.async { onStop(velocity, canChangeScene) }
+            testScope.testScheduler.runCurrent()
+            return velocityConsumed
         }
 
         fun NestedScrollConnection.scroll(
@@ -1112,6 +1116,7 @@
         // Freeze the transition.
         val transition = transitionState as Transition
         transition.freezeAndAnimateToCurrentState()
+        runCurrent()
         assertTransition(isUserInputOngoing = false)
         advanceUntilIdle()
         assertIdle(SceneC)
@@ -1279,14 +1284,13 @@
         // Release the finger.
         dragController.onDragStoppedAnimateNow(
             velocity = -velocityThreshold,
-            onAnimationStart = { assertTransition(fromScene = SceneA, toScene = SceneB) },
+            onAnimationStart = {
+                // Given that we are at progress >= 100% and that the overscroll on scene B is doing
+                // nothing, we are already idle.
+                assertIdle(SceneB)
+            },
             expectedConsumedVelocity = 0f,
         )
-
-        // Exhaust all coroutines *without advancing the clock*. Given that we are at progress >=
-        // 100% and that the overscroll on scene B is doing nothing, we are already idle.
-        runCurrent()
-        assertIdle(SceneB)
     }
 
     @Test
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 85d8b60..cb3e433 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
@@ -72,9 +72,13 @@
             return delta
         }
 
-        override fun onStop(velocity: Float, canChangeContent: Boolean): SuspendedValue<Float> {
+        override suspend fun onStop(velocity: Float, canChangeContent: Boolean): Float {
             onStop.invoke(velocity)
-            return { velocity }
+            return velocity
+        }
+
+        override fun onCancel(canChangeContent: Boolean) {
+            error("MultiPointerDraggable never calls onCancel()")
         }
     }
 
diff --git a/packages/SystemUI/customization/res/values/dimens.xml b/packages/SystemUI/customization/res/values/dimens.xml
index 21b4c71..2bb5541 100644
--- a/packages/SystemUI/customization/res/values/dimens.xml
+++ b/packages/SystemUI/customization/res/values/dimens.xml
@@ -33,6 +33,7 @@
     <dimen name="small_clock_height">114dp</dimen>
     <dimen name="small_clock_padding_top">28dp</dimen>
     <dimen name="clock_padding_start">28dp</dimen>
+    <dimen name="weather_date_icon_padding">28dp</dimen>
 
     <!-- When large clock is showing, offset the smartspace by this amount -->
     <dimen name="keyguard_smartspace_top_offset">12dp</dimen>
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
index 9877406..801a2d6 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
@@ -34,6 +34,7 @@
 import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.animation.GlyphCallback
 import com.android.systemui.animation.TextAnimator
+import com.android.systemui.animation.TypefaceVariantCacheImpl
 import com.android.systemui.customization.R
 import com.android.systemui.log.core.LogLevel
 import com.android.systemui.log.core.LogcatOnlyMessageBuffer
@@ -98,7 +99,8 @@
 
     @VisibleForTesting
     var textAnimatorFactory: (Layout, () -> Unit) -> TextAnimator = { layout, invalidateCb ->
-        TextAnimator(layout, NUM_CLOCK_FONT_ANIMATION_STEPS, invalidateCb)
+        val cache = TypefaceVariantCacheImpl(layout.paint.typeface, NUM_CLOCK_FONT_ANIMATION_STEPS)
+        TextAnimator(layout, cache, invalidateCb)
     }
 
     // Used by screenshot tests to provide stability
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 9bb92bc..e898725 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
@@ -67,7 +67,10 @@
             val buffers = messageBuffers ?: ClockMessageBuffers(LogUtil.DEFAULT_MESSAGE_BUFFER)
             val fontAxes = ClockFontAxis.merge(FlexClockController.FONT_AXES, settings.axes)
             val clockSettings = settings.copy(axes = fontAxes.map { it.toSetting() })
-            val typefaceCache = TypefaceCache(buffers.infraMessageBuffer) { FLEX_TYPEFACE }
+            val typefaceCache =
+                TypefaceCache(buffers.infraMessageBuffer, NUM_CLOCK_FONT_ANIMATION_STEPS) {
+                    FLEX_TYPEFACE
+                }
             FlexClockController(
                 ClockContext(
                     ctx,
@@ -110,6 +113,8 @@
     }
 
     companion object {
+        const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+
         // TODO(b/364681643): Variations for retargetted DIGITAL_CLOCK_FLEX
         val LEGACY_FLEX_LS_VARIATION =
             listOf(
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TypefaceCache.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TypefaceCache.kt
index f5a9375..9e3f6d9 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TypefaceCache.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TypefaceCache.kt
@@ -17,13 +17,18 @@
 package com.android.systemui.shared.clocks
 
 import android.graphics.Typeface
+import com.android.systemui.animation.FontCacheImpl
 import com.android.systemui.animation.TypefaceVariantCache
 import com.android.systemui.log.core.Logger
 import com.android.systemui.log.core.MessageBuffer
 import java.lang.ref.ReferenceQueue
 import java.lang.ref.WeakReference
 
-class TypefaceCache(messageBuffer: MessageBuffer, val typefaceFactory: (String) -> Typeface) {
+class TypefaceCache(
+    messageBuffer: MessageBuffer,
+    val animationFrameCount: Int,
+    val typefaceFactory: (String) -> Typeface,
+) {
     private val logger = Logger(messageBuffer, this::class.simpleName!!)
 
     private data class CacheKey(val res: String, val fvar: String?)
@@ -44,6 +49,7 @@
     // result, once a typeface is no longer being used, it is unlikely to be recreated immediately.
     private val cache = mutableMapOf<CacheKey, WeakTypefaceRef>()
     private val queue = ReferenceQueue<Typeface>()
+    private val fontCache = FontCacheImpl(animationFrameCount)
 
     fun getTypeface(res: String): Typeface {
         checkQueue()
@@ -62,6 +68,9 @@
     fun getVariantCache(res: String): TypefaceVariantCache {
         val baseTypeface = getTypeface(res)
         return object : TypefaceVariantCache {
+            override val fontCache = this@TypefaceCache.fontCache
+            override val animationFrameCount = this@TypefaceCache.animationFrameCount
+
             override fun getTypefaceForVariant(fvar: String?): Typeface? {
                 checkQueue()
                 val key = CacheKey(res, fvar)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
index 48761c0..cef24e9 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
@@ -39,7 +39,6 @@
 import com.android.systemui.customization.R
 import com.android.systemui.log.core.Logger
 import com.android.systemui.plugins.clocks.ClockFontAxisSetting
-import com.android.systemui.shared.clocks.ClockAnimation
 import com.android.systemui.shared.clocks.ClockContext
 import com.android.systemui.shared.clocks.DigitTranslateAnimator
 import com.android.systemui.shared.clocks.DimensionParser
@@ -96,9 +95,7 @@
 
     @VisibleForTesting
     var textAnimatorFactory: (Layout, () -> Unit) -> TextAnimator = { layout, invalidateCb ->
-        TextAnimator(layout, ClockAnimation.NUM_CLOCK_FONT_ANIMATION_STEPS, invalidateCb).also {
-            it.typefaceCache = typefaceCache
-        }
+        TextAnimator(layout, typefaceCache, invalidateCb)
     }
 
     override var verticalAlignment: VerticalAlignment = VerticalAlignment.BASELINE
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index 1ceac78..aa95abb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -168,8 +168,7 @@
     public void showFullscreenModeButton_addViewAndSetImageResource() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
 
-        verify(mSpyImageView).setImageResource(
-                getIconResId(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN));
+        verify(mSpyImageView).setImageResource(getIconResId());
         assertEquals(mSpyImageView, mWindowManager.getAttachedView());
         assertShowFadingAnimation(FADE_IN_ALPHA);
         assertShowFadingAnimation(FADE_OUT_ALPHA);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java
index 944066fa..d47ec8c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java
@@ -25,15 +25,12 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper;
 import android.util.Size;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.FakeSharedPreferences;
 
@@ -59,18 +56,6 @@
         mWindowMagnificationFrameSizePrefs = new WindowMagnificationFrameSizePrefs(mContext);
     }
 
-    @DisableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
-    @Test
-    public void saveSizeForCurrentDensity_getExpectedSize() {
-        Size testSize = new Size(500, 500);
-        mWindowMagnificationFrameSizePrefs
-                .saveIndexAndSizeForCurrentDensity(MagnificationSize.CUSTOM, testSize);
-
-        assertThat(mWindowMagnificationFrameSizePrefs.getSizeForCurrentDensity())
-                .isEqualTo(testSize);
-    }
-
-    @EnableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
     @Test
     public void saveSizeForCurrentDensity_validPreference_getExpectedSize() {
         int testIndex = MagnificationSize.MEDIUM;
@@ -81,7 +66,6 @@
                 .isEqualTo(testSize);
     }
 
-    @EnableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
     @Test
     public void saveSizeForCurrentDensity_validPreference_getExpectedIndex() {
         int testIndex = MagnificationSize.MEDIUM;
@@ -92,7 +76,6 @@
                 .isEqualTo(testIndex);
     }
 
-    @EnableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
     @Test
     public void saveSizeForCurrentDensity_invalidPreference_getDefaultIndex() {
         mSharedPreferences
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt
index b7b98d4..9f9245c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.systemui.accessibility.extradim
 
+import android.os.Handler
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -25,8 +26,10 @@
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.eq
+import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
@@ -43,21 +46,30 @@
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var dialogProvider: Provider<ExtraDimDialogDelegate>
     @Mock private lateinit var dialogTransitionAnimator: DialogTransitionAnimator
+    @Mock private lateinit var mainHandler: Handler
+    @Captor private lateinit var runnableCaptor: ArgumentCaptor<Runnable>
 
     @Before
     fun setUp() {
         extraDimDialogManager =
-            ExtraDimDialogManager(dialogProvider, activityStarter, dialogTransitionAnimator)
+            ExtraDimDialogManager(
+                dialogProvider,
+                activityStarter,
+                dialogTransitionAnimator,
+                mainHandler,
+            )
     }
 
     @Test
     fun dismissKeyguardIfNeededAndShowDialog_executeRunnableDismissingKeyguard() {
         extraDimDialogManager.dismissKeyguardIfNeededAndShowDialog()
+        verify(mainHandler).post(runnableCaptor.capture())
+        runnableCaptor.value.run()
         verify(activityStarter)
             .executeRunnableDismissingKeyguard(
                 any(),
                 /* cancelAction= */ eq(null),
-                /* dismissShade= */ eq(false),
+                /* dismissShade= */ eq(true),
                 /* afterKeyguardGone= */ eq(true),
                 /* deferred= */ eq(false),
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/activity/data/repository/ActivityManagerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/activity/data/repository/ActivityManagerRepositoryTest.kt
new file mode 100644
index 0000000..d6ba98d
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/activity/data/repository/ActivityManagerRepositoryTest.kt
@@ -0,0 +1,143 @@
+/*
+ * 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.activity.data.repository
+
+import android.app.ActivityManager
+import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
+import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE
+import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_TOP_SLEEPING
+import android.app.activityManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.log.core.Logger
+import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ActivityManagerRepositoryTest : SysuiTestCase() {
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+    private val logger = Logger(logcatLogBuffer("ActivityManagerRepositoryTest"), "tag")
+
+    private val Kosmos.underTest by Kosmos.Fixture { realActivityManagerRepository }
+
+    @Test
+    fun createIsAppVisibleFlow_fetchesInitialValue_true() =
+        kosmos.runTest {
+            whenever(activityManager.getUidImportance(THIS_UID)).thenReturn(IMPORTANCE_FOREGROUND)
+
+            val latest by
+                collectLastValue(underTest.createIsAppVisibleFlow(THIS_UID, logger, LOG_TAG))
+
+            assertThat(latest).isTrue()
+        }
+
+    @Test
+    fun createIsAppVisibleFlow_fetchesInitialValue_false() =
+        kosmos.runTest {
+            whenever(activityManager.getUidImportance(THIS_UID)).thenReturn(IMPORTANCE_GONE)
+
+            val latest by
+                collectLastValue(underTest.createIsAppVisibleFlow(THIS_UID, logger, LOG_TAG))
+
+            assertThat(latest).isFalse()
+        }
+
+    @Test
+    fun createIsAppVisibleFlow_getsImportanceUpdates() =
+        kosmos.runTest {
+            val latest by
+                collectLastValue(underTest.createIsAppVisibleFlow(THIS_UID, logger, LOG_TAG))
+
+            val listenerCaptor = argumentCaptor<ActivityManager.OnUidImportanceListener>()
+            verify(activityManager).addOnUidImportanceListener(listenerCaptor.capture(), any())
+            val listener = listenerCaptor.firstValue
+
+            listener.onUidImportance(THIS_UID, IMPORTANCE_GONE)
+            assertThat(latest).isFalse()
+
+            listener.onUidImportance(THIS_UID, IMPORTANCE_FOREGROUND)
+            assertThat(latest).isTrue()
+
+            listener.onUidImportance(THIS_UID, IMPORTANCE_TOP_SLEEPING)
+            assertThat(latest).isFalse()
+        }
+
+    @Test
+    fun createIsAppVisibleFlow_ignoresUpdatesForOtherUids() =
+        kosmos.runTest {
+            val latest by
+                collectLastValue(underTest.createIsAppVisibleFlow(THIS_UID, logger, LOG_TAG))
+
+            val listenerCaptor = argumentCaptor<ActivityManager.OnUidImportanceListener>()
+            verify(activityManager).addOnUidImportanceListener(listenerCaptor.capture(), any())
+            val listener = listenerCaptor.firstValue
+
+            listener.onUidImportance(THIS_UID, IMPORTANCE_GONE)
+            assertThat(latest).isFalse()
+
+            // WHEN another UID becomes foreground
+            listener.onUidImportance(THIS_UID + 2, IMPORTANCE_FOREGROUND)
+
+            // THEN this UID still stays not visible
+            assertThat(latest).isFalse()
+        }
+
+    @Test
+    fun createIsAppVisibleFlow_securityExceptionOnUidRegistration_ok() =
+        kosmos.runTest {
+            whenever(activityManager.getUidImportance(THIS_UID)).thenReturn(IMPORTANCE_GONE)
+            whenever(activityManager.addOnUidImportanceListener(any(), any()))
+                .thenThrow(SecurityException())
+
+            val latest by
+                collectLastValue(underTest.createIsAppVisibleFlow(THIS_UID, logger, LOG_TAG))
+
+            // Verify no crash, and we get a value emitted
+            assertThat(latest).isFalse()
+        }
+
+    /** Regression test for b/216248574. */
+    @Test
+    fun createIsAppVisibleFlow_getUidImportanceThrowsException_ok() =
+        kosmos.runTest {
+            whenever(activityManager.getUidImportance(any())).thenThrow(SecurityException())
+
+            val latest by
+                collectLastValue(underTest.createIsAppVisibleFlow(THIS_UID, logger, LOG_TAG))
+
+            // Verify no crash, and we get a value emitted
+            assertThat(latest).isFalse()
+        }
+
+    companion object {
+        private const val THIS_UID = 558
+        private const val LOG_TAG = "LogTag"
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt
index 4809d0e..d6db349 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt
@@ -48,6 +48,11 @@
         )
         assertBackTransformation(
             backAnimationSpec = backAnimationSpec,
+            backInput = BackInput(progressX = 1f, progressY = 0f, edge = BackEvent.EDGE_NONE),
+            expected = BackTransformation(translateX = 0f, translateY = 0f, scale = minScale),
+        )
+        assertBackTransformation(
+            backAnimationSpec = backAnimationSpec,
             backInput = BackInput(progressX = 1f, progressY = 1f, edge = BackEvent.EDGE_LEFT),
             expected = BackTransformation(translateX = -maxX, translateY = -maxY, scale = minScale),
         )
@@ -77,7 +82,7 @@
                     translateX = Float.NaN,
                     translateY = Float.NaN,
                     scale = 1f,
-                    scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER
+                    scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
                 ),
         )
         assertBackTransformation(
@@ -88,7 +93,7 @@
                     translateX = Float.NaN,
                     translateY = Float.NaN,
                     scale = minScale,
-                    scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER
+                    scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
                 ),
         )
         assertBackTransformation(
@@ -99,7 +104,7 @@
                     translateX = Float.NaN,
                     translateY = Float.NaN,
                     scale = minScale,
-                    scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER
+                    scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
                 ),
         )
         assertBackTransformation(
@@ -110,7 +115,18 @@
                     translateX = Float.NaN,
                     translateY = Float.NaN,
                     scale = minScale,
-                    scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER
+                    scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
+                ),
+        )
+        assertBackTransformation(
+            backAnimationSpec = backAnimationSpec,
+            backInput = BackInput(progressX = 1f, progressY = 1f, edge = BackEvent.EDGE_NONE),
+            expected =
+                BackTransformation(
+                    translateX = Float.NaN,
+                    translateY = Float.NaN,
+                    scale = minScale,
+                    scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
                 ),
         )
     }
@@ -131,7 +147,7 @@
                 /* swipeEdge = */ backInput.edge,
             ),
         progressY = backInput.progressY,
-        result = actual
+        result = actual,
     )
 
     val tolerance = 0f
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
index cdda9cc..41cc6ee 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
@@ -48,8 +48,8 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt
index 25f9565..a11dace 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.bluetooth.qsdialog
 
 import android.bluetooth.BluetoothLeBroadcast
+import android.bluetooth.BluetoothLeBroadcastMetadata
 import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -50,6 +51,7 @@
     @get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
     private val kosmos = testKosmos()
     @Mock private lateinit var localBluetoothLeBroadcast: LocalBluetoothLeBroadcast
+    @Mock private lateinit var bluetoothLeBroadcastMetadata: BluetoothLeBroadcastMetadata
     @Captor private lateinit var callbackCaptor: ArgumentCaptor<BluetoothLeBroadcast.Callback>
     private lateinit var underTest: AudioSharingInteractor
 
@@ -202,7 +204,7 @@
                 verify(localBluetoothLeBroadcast)
                     .registerServiceCallBack(any(), callbackCaptor.capture())
                 runCurrent()
-                callbackCaptor.value.onPlaybackStarted(0, 0)
+                callbackCaptor.value.onBroadcastMetadataChanged(0, bluetoothLeBroadcastMetadata)
                 runCurrent()
 
                 assertThat(bluetoothTileDialogAudioSharingRepository.sourceAdded).isTrue()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
similarity index 98%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
index 97f2e56..af8c357 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
@@ -59,6 +59,7 @@
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.rememberViewModel
 import com.android.systemui.motion.createSysUiComposeMotionTestRule
+import com.android.systemui.qs.ui.viewmodel.fakeQsSceneAdapter
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.startable.sceneContainerStartable
 import com.android.systemui.scene.sceneContainerViewModelFactory
@@ -183,6 +184,7 @@
                                 initialSceneKey = Scenes.Bouncer,
                                 overlayByKey = emptyMap(),
                                 dataSourceDelegator = kosmos.sceneDataSourceDelegator,
+                                qsSceneAdapter = { kosmos.fakeQsSceneAdapter },
                             )
                         }
                     },
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
index 0f148f8..2d093bf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.brightness.domain.interactor.screenBrightnessInteractor
 import com.android.systemui.brightness.shared.model.GammaBrightness
 import com.android.systemui.brightness.shared.model.LinearBrightness
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.Text
@@ -61,6 +62,7 @@
                 brightnessPolicyEnforcementInteractor,
                 sliderHapticsViewModelFactory,
                 brightnessMirrorShowingInteractor,
+                falsingInteractor,
                 supportsMirroring = true,
                 brightnessWarningToast,
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
index 1e86516..e5f0d7c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
@@ -19,13 +19,13 @@
 import android.os.UserHandle
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
 import android.provider.Settings
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.internal.logging.uiEventLogger
 import com.android.internal.logging.uiEventLoggerFake
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.Flags.FLAG_COMMUNAL_SCENE_KTF_REFACTOR
+import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.communal.domain.interactor.communalInteractor
 import com.android.systemui.communal.domain.interactor.communalSceneInteractor
@@ -38,6 +38,7 @@
 import com.android.systemui.dock.dockManager
 import com.android.systemui.dock.fakeDockManager
 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.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -47,6 +48,8 @@
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.notificationShadeWindowController
 import com.android.systemui.statusbar.phone.centralSurfaces
 import com.android.systemui.statusbar.phone.centralSurfacesOptional
@@ -65,12 +68,29 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @EnableFlags(FLAG_COMMUNAL_HUB)
-class CommunalSceneStartableTest : SysuiTestCase() {
+class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+    companion object {
+        private const val SCREEN_TIMEOUT = 1000
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return FlagsParameterization.allCombinationsOf().andSceneContainer()
+        }
+    }
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
+
     private val kosmos = testKosmos()
 
     private lateinit var underTest: CommunalSceneStartable
@@ -95,7 +115,6 @@
                         keyguardInteractor = keyguardInteractor,
                         systemSettings = fakeSettings,
                         notificationShadeWindowController = notificationShadeWindowController,
-                        featureFlagsClassic = kosmos.fakeFeatureFlagsClassic,
                         applicationScope = applicationCoroutineScope,
                         bgScope = applicationCoroutineScope,
                         mainDispatcher = testDispatcher,
@@ -114,7 +133,7 @@
     }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun keyguardGoesAway_whenLaunchingEditMode_doNotForceBlankScene() =
         with(kosmos) {
             testScope.runTest {
@@ -135,7 +154,7 @@
         }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun keyguardGoesAway_whenLaunchingWidget_doNotForceBlankScene() =
         with(kosmos) {
             testScope.runTest {
@@ -156,7 +175,7 @@
         }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun keyguardGoesAway_whenNotLaunchingWidget_forceBlankScene() =
         with(kosmos) {
             testScope.runTest {
@@ -177,7 +196,7 @@
         }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun keyguardGoesAway_whenInEditMode_doesNotChangeScene() =
         with(kosmos) {
             testScope.runTest {
@@ -198,6 +217,7 @@
 
     @Ignore("Ignored until custom animations are implemented in b/322787129")
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun deviceDocked_forceCommunalScene() =
         with(kosmos) {
             testScope.runTest {
@@ -215,7 +235,7 @@
         }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun occluded_forceBlankScene() =
         with(kosmos) {
             testScope.runTest {
@@ -235,7 +255,7 @@
         }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun occluded_doesNotForceBlankSceneIfLaunchingActivityOverLockscreen() =
         with(kosmos) {
             testScope.runTest {
@@ -255,7 +275,7 @@
         }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun deviceDocked_doesNotForceCommunalIfTransitioningFromCommunal() =
         with(kosmos) {
             testScope.runTest {
@@ -273,7 +293,7 @@
         }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun deviceAsleep_forceBlankSceneAfterTimeout() =
         with(kosmos) {
             testScope.runTest {
@@ -295,7 +315,7 @@
         }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun deviceAsleep_wakesUpBeforeTimeout_noChangeInScene() =
         with(kosmos) {
             testScope.runTest {
@@ -325,6 +345,7 @@
 
     @Ignore("Ignored until custom animations are implemented in b/322787129")
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun dockingOnLockscreen_forcesCommunal() =
         with(kosmos) {
             testScope.runTest {
@@ -347,6 +368,7 @@
 
     @Ignore("Ignored until custom animations are implemented in b/322787129")
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun dockingOnLockscreen_doesNotForceCommunalIfDreamStarts() =
         with(kosmos) {
             testScope.runTest {
@@ -377,6 +399,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun hubTimeout_whenDreaming_goesToBlank() =
         with(kosmos) {
             testScope.runTest {
@@ -394,6 +417,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun hubTimeout_notDreaming_staysOnCommunal() =
         with(kosmos) {
             testScope.runTest {
@@ -409,6 +433,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun hubTimeout_dreamStopped_staysOnCommunal() =
         with(kosmos) {
             testScope.runTest {
@@ -432,6 +457,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun hubTimeout_dreamStartedHalfway_goesToCommunal() =
         with(kosmos) {
             testScope.runTest {
@@ -454,6 +480,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun hubTimeout_dreamAfterInitialTimeout_goesToBlank() =
         with(kosmos) {
             testScope.runTest {
@@ -474,6 +501,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun hubTimeout_userActivityTriggered_resetsTimeout() =
         with(kosmos) {
             testScope.runTest {
@@ -501,6 +529,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_SCENE_CONTAINER)
     fun hubTimeout_screenTimeoutChanged() =
         with(kosmos) {
             testScope.runTest {
@@ -526,7 +555,163 @@
         }
 
     @Test
-    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    fun hubTimeout_withSceneContainer_whenDreaming_goesToBlank() =
+        with(kosmos) {
+            testScope.runTest {
+                // Device is dreaming and on communal.
+                updateDreaming(true)
+                sceneInteractor.changeScene(Scenes.Communal, "test")
+
+                val scene by collectLastValue(sceneInteractor.currentScene)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                // Scene times out back to blank after the screen timeout.
+                advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
+                assertThat(scene).isEqualTo(Scenes.Dream)
+            }
+        }
+
+    @Test
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    fun hubTimeout_withSceneContainer_notDreaming_staysOnCommunal() =
+        with(kosmos) {
+            testScope.runTest {
+                // Device is not dreaming and on communal.
+                updateDreaming(false)
+                sceneInteractor.changeScene(Scenes.Communal, "test")
+
+                // Scene stays as Communal
+                advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
+                val scene by collectLastValue(sceneInteractor.currentScene)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+            }
+        }
+
+    @Test
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    fun hubTimeout_withSceneContainer_dreamStopped_staysOnCommunal() =
+        with(kosmos) {
+            testScope.runTest {
+                // Device is dreaming and on communal.
+                updateDreaming(true)
+                sceneInteractor.changeScene(Scenes.Communal, "test")
+
+                val scene by collectLastValue(sceneInteractor.currentScene)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                // Wait a bit, but not long enough to timeout.
+                advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                // Dream stops, timeout is cancelled and device stays on hub, because the regular
+                // screen timeout will take effect at this point.
+                updateDreaming(false)
+                advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+            }
+        }
+
+    @Test
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    fun hubTimeout_withSceneContainer_dreamStartedHalfway_goesToCommunal() =
+        with(kosmos) {
+            testScope.runTest {
+                // Device is on communal, but not dreaming.
+                updateDreaming(false)
+                sceneInteractor.changeScene(Scenes.Communal, "test")
+
+                val scene by collectLastValue(sceneInteractor.currentScene)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                // Wait a bit, but not long enough to timeout, then start dreaming.
+                advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+                updateDreaming(true)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                // Device times out after one screen timeout interval, dream doesn't reset timeout.
+                advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+                assertThat(scene).isEqualTo(Scenes.Dream)
+            }
+        }
+
+    @Test
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    fun hubTimeout_withSceneContainer_dreamAfterInitialTimeout_goesToBlank() =
+        with(kosmos) {
+            testScope.runTest {
+                // Device is on communal.
+                sceneInteractor.changeScene(Scenes.Communal, "test")
+
+                // Device stays on the hub after the timeout since we're not dreaming.
+                advanceTimeBy(SCREEN_TIMEOUT.milliseconds * 2)
+                val scene by collectLastValue(sceneInteractor.currentScene)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                // Start dreaming.
+                updateDreaming(true)
+
+                // Hub times out immediately.
+                assertThat(scene).isEqualTo(Scenes.Dream)
+            }
+        }
+
+    @Test
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    fun hubTimeout_withSceneContainer_userActivityTriggered_resetsTimeout() =
+        with(kosmos) {
+            testScope.runTest {
+                // Device is dreaming and on communal.
+                updateDreaming(true)
+                sceneInteractor.changeScene(Scenes.Communal, "test")
+
+                val scene by collectLastValue(sceneInteractor.currentScene)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                // Wait a bit, but not long enough to timeout.
+                advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+
+                // Send user interaction to reset timeout.
+                communalInteractor.signalUserInteraction()
+
+                // If user activity didn't reset timeout, we would have gone back to Blank by now.
+                advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                // Timeout happens one interval after the user interaction.
+                advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+                assertThat(scene).isEqualTo(Scenes.Dream)
+            }
+        }
+
+    @Test
+    @EnableFlags(FLAG_SCENE_CONTAINER)
+    fun hubTimeout_withSceneContainer_screenTimeoutChanged() =
+        with(kosmos) {
+            testScope.runTest {
+                fakeSettings.putInt(Settings.System.SCREEN_OFF_TIMEOUT, SCREEN_TIMEOUT * 2)
+
+                // Device is dreaming and on communal.
+                updateDreaming(true)
+                sceneInteractor.changeScene(Scenes.Communal, "test")
+
+                val scene by collectLastValue(sceneInteractor.currentScene)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                // Scene times out back to blank after the screen timeout.
+                advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
+                assertThat(scene).isEqualTo(Scenes.Communal)
+
+                advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
+                assertThat(scene).isEqualTo(Scenes.Dream)
+                assertThat(uiEventLoggerFake.logs.first().eventId)
+                    .isEqualTo(CommunalUiEvent.COMMUNAL_HUB_TIMEOUT.id)
+                assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+            }
+        }
+
+    @Test
+    @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
     fun transitionFromDozingToGlanceableHub_forcesCommunal() =
         with(kosmos) {
             testScope.runTest {
@@ -558,8 +743,4 @@
             fakeKeyguardRepository.setDreaming(dreaming)
             runCurrent()
         }
-
-    companion object {
-        private const val SCREEN_TIMEOUT = 1000
-    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
index 5bbd3ff..18cc8bf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
@@ -172,16 +172,16 @@
         }
 
     @Test
-    fun selectedKey_onReorderWidgets_isCleared() =
+    fun selectedKey_onReorderWidgets_isSet() =
         testScope.runTest {
             val selectedKey by collectLastValue(underTest.selectedKey)
 
-            val key = CommunalContentModel.KEY.widget(123)
-            underTest.setSelectedKey(key)
-            assertThat(selectedKey).isEqualTo(key)
-
-            underTest.onReorderWidgetStart()
+            underTest.setSelectedKey(null)
             assertThat(selectedKey).isNull()
+
+            val key = CommunalContentModel.KEY.widget(123)
+            underTest.onReorderWidgetStart(key)
+            assertThat(selectedKey).isEqualTo(key)
         }
 
     @Test
@@ -234,7 +234,7 @@
 
     @Test
     fun reorderWidget_uiEventLogging_start() {
-        underTest.onReorderWidgetStart()
+        underTest.onReorderWidgetStart(CommunalContentModel.KEY.widget(123))
         verify(uiEventLogger).log(CommunalUiEvent.COMMUNAL_HUB_REORDER_WIDGET_START)
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
index ed21474..3c90c93 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
@@ -67,7 +67,6 @@
         mFeatureFlags.set(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS, true);
         mStateController = new DreamOverlayStateController(
                 mExecutor,
-                /* overlayEnabled= */ true,
                 mFeatureFlags,
                 FakeLogBuffer.Factory.Companion.create(),
                 new FakeWeakReferenceFactory());
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index d90d58b..1bb5c9a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -43,7 +43,6 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.domain.interactor.sceneBackInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.startable.sceneContainerStartable
 import com.android.systemui.scene.shared.model.Scenes
@@ -72,7 +71,6 @@
     private val trustRepository by lazy { kosmos.fakeTrustRepository }
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
     private val authenticationInteractor by lazy { kosmos.authenticationInteractor }
-    private val sceneBackInteractor by lazy { kosmos.sceneBackInteractor }
     private val sceneContainerStartable by lazy { kosmos.sceneContainerStartable }
     private val sysuiStatusBarStateController by lazy { kosmos.sysuiStatusBarStateController }
     private lateinit var underTest: DeviceEntryInteractor
@@ -437,7 +435,9 @@
     fun isDeviceEntered_unlockedWhileOnShade_emitsTrue() =
         testScope.runTest {
             val isDeviceEntered by collectLastValue(underTest.isDeviceEntered)
+            val isDeviceEnteredDirectly by collectLastValue(underTest.isDeviceEnteredDirectly)
             assertThat(isDeviceEntered).isFalse()
+            assertThat(isDeviceEnteredDirectly).isFalse()
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
 
@@ -445,19 +445,20 @@
             switchToScene(Scenes.Shade)
             assertThat(currentScene).isEqualTo(Scenes.Shade)
             // Simulating a "leave it open when the keyguard is hidden" which means the bouncer will
-            // be
-            // shown and successful authentication should take the user back to where they are, the
-            // shade scene.
+            // be shown and successful authentication should take the user back to where they are,
+            // the shade scene.
             sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true)
             switchToScene(Scenes.Bouncer)
             assertThat(currentScene).isEqualTo(Scenes.Bouncer)
 
             assertThat(isDeviceEntered).isFalse()
+            assertThat(isDeviceEnteredDirectly).isFalse()
             // Authenticate with PIN to unlock and dismiss the lockscreen:
             authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
             runCurrent()
 
             assertThat(isDeviceEntered).isTrue()
+            assertThat(isDeviceEnteredDirectly).isFalse()
         }
 
     private fun TestScope.switchToScene(sceneKey: SceneKey) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorImplTest.kt
new file mode 100644
index 0000000..e1344ca
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorImplTest.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.display.domain.interactor
+
+import android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
+import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import android.view.layoutInflater
+import android.view.windowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.data.repository.fakeDisplayWindowPropertiesRepository
+import com.android.systemui.display.shared.model.DisplayWindowProperties
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class DisplayWindowPropertiesInteractorImplTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val repo = kosmos.fakeDisplayWindowPropertiesRepository
+
+    private val underTest = kosmos.displayWindowPropertiesInteractor
+
+    @Test
+    fun getForStatusBar_returnsPropertiesWithCorrectWindowType() {
+        val displayId = 123
+        val statusBarWindowProperties = createDisplayWindowProperties(displayId, TYPE_STATUS_BAR)
+        val navBarWindowProperties = createDisplayWindowProperties(displayId, TYPE_NAVIGATION_BAR)
+        repo.insert(statusBarWindowProperties)
+        repo.insert(navBarWindowProperties)
+
+        assertThat(underTest.getForStatusBar(displayId)).isEqualTo(statusBarWindowProperties)
+    }
+
+    private fun createDisplayWindowProperties(displayId: Int, windowType: Int) =
+        DisplayWindowProperties(
+            displayId,
+            windowType,
+            context,
+            kosmos.windowManager,
+            kosmos.layoutInflater,
+        )
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeScreenStateTest.java
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeScreenStateTest.java
index ba578a3..bbd78b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeScreenStateTest.java
@@ -35,7 +35,7 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Matchers.anyObject;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.verify;
@@ -315,6 +315,6 @@
     public void authCallbackRemovedOnDestroy() {
         mScreen.destroy();
 
-        verify(mAuthController).removeCallback(anyObject());
+        verify(mAuthController).removeCallback(any());
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt
new file mode 100644
index 0000000..790df03
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt
@@ -0,0 +1,165 @@
+/*
+ * 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.dreams
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.content.pm.ServiceInfo
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.service.dreams.IDreamManager
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.core.FakeLogBuffer
+import com.android.systemui.shared.condition.Monitor
+import com.android.systemui.util.mockito.withArgCaptor
+import kotlin.test.Test
+import org.junit.Before
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.kotlin.any
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidJUnit4::class)
+class DreamOverlayRegistrantTest : SysuiTestCase() {
+    private val context = mock<Context>()
+
+    private val packageManager = mock<PackageManager>()
+
+    private val dreamManager = mock<IDreamManager>()
+
+    private val componentName = mock<ComponentName>()
+
+    private val serviceInfo = mock<ServiceInfo>()
+
+    private val monitor = mock<Monitor>()
+
+    private val logBuffer = FakeLogBuffer.Factory.Companion.create()
+
+    private lateinit var underTest: DreamOverlayRegistrant
+
+    @Before
+    fun setup() {
+        underTest =
+            DreamOverlayRegistrant(
+                context,
+                componentName,
+                monitor,
+                packageManager,
+                dreamManager,
+                logBuffer,
+            )
+
+        whenever(packageManager.getComponentEnabledSetting(eq(componentName)))
+            .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)
+        whenever(
+                packageManager.getServiceInfo(
+                    eq(componentName),
+                    eq(PackageManager.GET_META_DATA or PackageManager.MATCH_DISABLED_COMPONENTS),
+                )
+            )
+            .thenReturn(serviceInfo)
+        whenever(
+                packageManager.setComponentEnabledSetting(
+                    eq(componentName),
+                    eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
+                    eq(PackageManager.DONT_KILL_APP),
+                )
+            )
+            .thenAnswer {
+                setComponentEnabledState(PackageManager.COMPONENT_ENABLED_STATE_ENABLED, true)
+            }
+
+        serviceInfo.enabled = false
+    }
+
+    private fun start() {
+        underTest.start()
+        val subscription = withArgCaptor { verify(monitor).addSubscription(capture()) }
+        subscription.callback.onConditionsChanged(true)
+    }
+
+    private fun setComponentEnabledState(enabledState: Int, triggerUpdate: Boolean) {
+        whenever(packageManager.getComponentEnabledSetting(eq(componentName)))
+            .thenReturn(enabledState)
+
+        if (triggerUpdate) {
+            withArgCaptor { verify(context).registerReceiver(capture(), any()) }
+                .onReceive(context, Intent())
+        }
+    }
+
+    /** Verify overlay registered when enabled in manifest. */
+    @Test
+    @DisableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+    fun testRegisteredWhenEnabledWithManifest() {
+        serviceInfo.enabled = true
+        start()
+
+        verify(dreamManager).registerDreamOverlayService(componentName)
+    }
+
+    /** Verify overlay registered for mobile hub with flag. */
+    @Test
+    @EnableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+    fun testRegisteredForMobileHub() {
+        start()
+
+        verify(dreamManager).registerDreamOverlayService(componentName)
+    }
+
+    /**
+     * Make sure dream overlay not registered when not in manifest and not hub mode on mobile is not
+     * enabled.
+     */
+    @Test
+    @DisableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+    fun testDisabledForMobileWithoutMobileHub() {
+        start()
+
+        verify(packageManager, never())
+            .setComponentEnabledSetting(
+                eq(componentName),
+                eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
+                eq(PackageManager.DONT_KILL_APP),
+            )
+        verify(dreamManager, never()).registerDreamOverlayService(componentName)
+    }
+
+    /** Ensure service unregistered when component is disabled at runtime. */
+    @Test
+    @EnableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+    fun testUnregisteredWhenComponentDisabled() {
+        start()
+        verify(dreamManager).registerDreamOverlayService(componentName)
+        clearInvocations(dreamManager)
+        setComponentEnabledState(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, true)
+        verify(dreamManager).registerDreamOverlayService(Mockito.isNull())
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index bbfc960..a804879 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -36,7 +36,6 @@
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.LifecycleRegistry
 import androidx.test.filters.SmallTest
-import com.android.app.viewcapture.ViewCapture
 import com.android.app.viewcapture.ViewCaptureAwareWindowManager
 import com.android.app.viewcapture.ViewCaptureFactory
 import com.android.compose.animation.scene.ObservableTransitionState
@@ -44,15 +43,15 @@
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB_ON_MOBILE
 import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.ambient.touch.TouchHandler
 import com.android.systemui.ambient.touch.TouchMonitor
 import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
 import com.android.systemui.ambient.touch.scrim.ScrimController
 import com.android.systemui.ambient.touch.scrim.ScrimManager
-import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
 import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
-import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
 import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.communal.domain.interactor.communalInteractor
@@ -64,6 +63,7 @@
 import com.android.systemui.complication.dagger.ComplicationComponent
 import com.android.systemui.dreams.complication.HideComplicationTouchHandler
 import com.android.systemui.dreams.dagger.DreamOverlayComponent
+import com.android.systemui.dreams.touch.CommunalTouchHandler
 import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.gesture.domain.gestureInteractor
@@ -87,21 +87,17 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
-import org.mockito.Captor
-import org.mockito.Mock
 import org.mockito.Mockito
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.isNull
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.any
 import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.firstValue
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.spy
-import org.mockito.kotlin.times
 import org.mockito.kotlin.verifyNoMoreInteractions
 import org.mockito.kotlin.whenever
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
@@ -117,68 +113,50 @@
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
-    @Mock lateinit var mLifecycleOwner: DreamOverlayLifecycleOwner
+    private val mLifecycleOwner = mock<DreamOverlayLifecycleOwner>()
+    private val mDreamOverlayCallback = mock<IDreamOverlayCallback>()
+    private val mWindowManager = mock<WindowManagerImpl>()
+    private val mComplicationComponentFactory = mock<ComplicationComponent.Factory>()
+    private val mComplicationHostViewController = mock<ComplicationHostViewController>()
+    private val mComplicationVisibilityController = mock<ComplicationLayoutEngine>()
+    private val mDreamComplicationComponentFactory =
+        mock<com.android.systemui.dreams.complication.dagger.ComplicationComponent.Factory>()
+    private val mHideComplicationTouchHandler = mock<HideComplicationTouchHandler>()
+    private val mDreamOverlayComponentFactory = mock<DreamOverlayComponent.Factory>()
+    private val mCommunalTouchHandler = mock<CommunalTouchHandler>()
+    private val mAmbientTouchComponentFactory = mock<AmbientTouchComponent.Factory>()
+    private val mDreamOverlayContainerView = mock<DreamOverlayContainerView>()
+    private val mDreamOverlayContainerViewController =
+        mock<DreamOverlayContainerViewController> {
+            on { containerView }.thenReturn(mDreamOverlayContainerView)
+        }
+    private val mKeyguardUpdateMonitor = mock<KeyguardUpdateMonitor>()
+    private val mTouchMonitor = mock<TouchMonitor>()
+    private val mStateController = mock<DreamOverlayStateController>()
+    private val mDreamOverlayContainerViewParent = mock<ViewGroup>()
+    private val mTouchInsetManager = mock<TouchInsetManager>()
+    private val mUiEventLogger = mock<UiEventLogger>()
+    private val mScrimController = mock<ScrimController>()
+    private val mScrimManager =
+        mock<ScrimManager> { on { currentController }.thenReturn(mScrimController) }
+    private val mSystemDialogsCloser = mock<SystemDialogsCloser>()
+    private val mDreamOverlayCallbackController = mock<DreamOverlayCallbackController>()
+    private val mLazyViewCapture = lazy { viewCaptureSpy }
 
-    private lateinit var lifecycleRegistry: FakeLifecycleRegistry
+    private val mViewCaptor = argumentCaptor<View>()
+    private val mTouchHandlersCaptor = argumentCaptor<Set<TouchHandler>>()
 
-    lateinit var mCommunalInteractor: CommunalInteractor
-
-    private lateinit var mWindowParams: WindowManager.LayoutParams
-
-    @Mock lateinit var mDreamOverlayCallback: IDreamOverlayCallback
-
-    @Mock lateinit var mWindowManager: WindowManagerImpl
-
-    @Mock lateinit var mComplicationComponentFactory: ComplicationComponent.Factory
-
-    @Mock lateinit var mComplicationHostViewController: ComplicationHostViewController
-
-    @Mock lateinit var mComplicationVisibilityController: ComplicationLayoutEngine
-
-    @Mock
-    lateinit var mDreamComplicationComponentFactory:
-        com.android.systemui.dreams.complication.dagger.ComplicationComponent.Factory
-
-    @Mock lateinit var mHideComplicationTouchHandler: HideComplicationTouchHandler
-
-    @Mock lateinit var mDreamOverlayComponentFactory: DreamOverlayComponent.Factory
-
-    @Mock lateinit var mAmbientTouchComponentFactory: AmbientTouchComponent.Factory
-
-    @Mock lateinit var mDreamOverlayContainerView: DreamOverlayContainerView
-
-    @Mock lateinit var mDreamOverlayContainerViewController: DreamOverlayContainerViewController
-
-    @Mock lateinit var mKeyguardUpdateMonitor: KeyguardUpdateMonitor
-
-    @Mock lateinit var mTouchMonitor: TouchMonitor
-
-    @Mock lateinit var mStateController: DreamOverlayStateController
-
-    @Mock lateinit var mDreamOverlayContainerViewParent: ViewGroup
-
-    @Mock lateinit var mTouchInsetManager: TouchInsetManager
-
-    @Mock lateinit var mUiEventLogger: UiEventLogger
-
-    @Mock lateinit var mScrimManager: ScrimManager
-
-    @Mock lateinit var mScrimController: ScrimController
-
-    @Mock lateinit var mSystemDialogsCloser: SystemDialogsCloser
-
-    @Mock lateinit var mDreamOverlayCallbackController: DreamOverlayCallbackController
-
-    @Mock lateinit var mLazyViewCapture: Lazy<ViewCapture>
-
-    private lateinit var mViewCaptureAwareWindowManager: ViewCaptureAwareWindowManager
-    private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
-    private lateinit var communalRepository: FakeCommunalSceneRepository
+    private val mWindowParams = WindowManager.LayoutParams()
+    private val lifecycleRegistry = FakeLifecycleRegistry(mLifecycleOwner)
+    private val bouncerRepository = kosmos.fakeKeyguardBouncerRepository
+    private val communalRepository = kosmos.fakeCommunalSceneRepository
     private var viewCaptureSpy = spy(ViewCaptureFactory.getInstance(context))
-    private lateinit var gestureInteractor: GestureInteractor
+    private val gestureInteractor = spy(kosmos.gestureInteractor)
+
+    private lateinit var mCommunalInteractor: CommunalInteractor
+    private lateinit var mViewCaptureAwareWindowManager: ViewCaptureAwareWindowManager
     private lateinit var environmentComponents: EnvironmentComponents
 
-    @Captor var mViewCaptor: ArgumentCaptor<View>? = null
     private lateinit var mService: DreamOverlayService
 
     private class EnvironmentComponents(
@@ -234,6 +212,7 @@
             mock<com.android.systemui.dreams.complication.dagger.ComplicationComponent>()
         whenever(dreamComplicationComponent.getHideComplicationTouchHandler())
             .thenReturn(mHideComplicationTouchHandler)
+        whenever(dreamOverlayComponent.communalTouchHandler).thenReturn(mCommunalTouchHandler)
         whenever(dreamComplicationComponentFactory.create(any(), any()))
             .thenReturn(dreamComplicationComponent)
 
@@ -259,13 +238,6 @@
 
     @Before
     fun setup() {
-        MockitoAnnotations.initMocks(this)
-
-        lifecycleRegistry = FakeLifecycleRegistry(mLifecycleOwner)
-        bouncerRepository = kosmos.fakeKeyguardBouncerRepository
-        communalRepository = kosmos.fakeCommunalSceneRepository
-        gestureInteractor = spy(kosmos.gestureInteractor)
-
         environmentComponents =
             setupComponentFactories(
                 mDreamComplicationComponentFactory,
@@ -273,12 +245,6 @@
                 mComplicationComponentFactory,
                 mAmbientTouchComponentFactory,
             )
-
-        whenever(mDreamOverlayContainerViewController.containerView)
-            .thenReturn(mDreamOverlayContainerView)
-        whenever(mScrimManager.getCurrentController()).thenReturn(mScrimController)
-        whenever(mLazyViewCapture.value).thenReturn(viewCaptureSpy)
-        mWindowParams = WindowManager.LayoutParams()
         mViewCaptureAwareWindowManager =
             ViewCaptureAwareWindowManager(
                 mWindowManager,
@@ -381,10 +347,10 @@
         verify(mStateController).setOverlayActive(false)
         verify(mStateController).setLowLightActive(false)
         verify(mStateController).setEntryAnimationsFinished(false)
-        verify(mStateController, Mockito.never()).setOverlayActive(true)
-        verify(mUiEventLogger, Mockito.never())
+        verify(mStateController, never()).setOverlayActive(true)
+        verify(mUiEventLogger, never())
             .log(DreamOverlayService.DreamOverlayEvent.DREAM_OVERLAY_COMPLETE_START)
-        verify(mDreamOverlayCallbackController, Mockito.never()).onStartDream()
+        verify(mDreamOverlayCallbackController, never()).onStartDream()
     }
 
     @Test
@@ -528,14 +494,14 @@
         mMainExecutor.runAllReady()
 
         // Verify view added.
-        verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
+        verify(mWindowManager).addView(mViewCaptor.capture(), any())
 
         // Service destroyed.
         mService.onEndDream()
         mMainExecutor.runAllReady()
 
         // Verify view removed.
-        verify(mWindowManager).removeView(mViewCaptor!!.value)
+        verify(mWindowManager).removeView(mViewCaptor.firstValue)
 
         // Verify state correctly set.
         verify(mStateController).setOverlayActive(false)
@@ -567,8 +533,8 @@
 
         // The overlay starts then finishes.
         val inOrder = Mockito.inOrder(mWindowManager)
-        inOrder.verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
-        inOrder.verify(mWindowManager).removeView(mViewCaptor!!.value)
+        inOrder.verify(mWindowManager).addView(mViewCaptor.capture(), any())
+        inOrder.verify(mWindowManager).removeView(mViewCaptor.firstValue)
     }
 
     @Test
@@ -596,8 +562,8 @@
 
         // The overlay starts then finishes.
         val inOrder = Mockito.inOrder(mWindowManager)
-        inOrder.verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
-        inOrder.verify(mWindowManager).removeView(mViewCaptor!!.value)
+        inOrder.verify(mWindowManager).addView(mViewCaptor.capture(), any())
+        inOrder.verify(mWindowManager).removeView(mViewCaptor.firstValue)
     }
 
     @Test
@@ -615,14 +581,14 @@
         mMainExecutor.runAllReady()
 
         // Verify view added.
-        verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
+        verify(mWindowManager).addView(mViewCaptor.capture(), any())
 
         // Service destroyed.
         mService.onDestroy()
         mMainExecutor.runAllReady()
 
         // Verify view removed.
-        verify(mWindowManager).removeView(mViewCaptor!!.value)
+        verify(mWindowManager).removeView(mViewCaptor.firstValue)
 
         // Verify state correctly set.
         verify(mKeyguardUpdateMonitor).removeCallback(any())
@@ -639,7 +605,7 @@
         mMainExecutor.runAllReady()
 
         // Verify no view is removed.
-        verify(mWindowManager, Mockito.never()).removeView(any())
+        verify(mWindowManager, never()).removeView(any())
 
         // Verify state still correctly set.
         verify(mKeyguardUpdateMonitor).removeCallback(any())
@@ -665,7 +631,7 @@
             false, /*shouldShowComplication*/
         )
         mMainExecutor.runAllReady()
-        verify(mWindowManager, Mockito.never()).addView(any(), any())
+        verify(mWindowManager, never()).addView(any(), any())
     }
 
     @Test
@@ -673,7 +639,7 @@
         // Service destroyed before dream started.
         mService.onDestroy()
         mMainExecutor.runAllReady()
-        verify(mWindowManager, Mockito.never()).removeView(any())
+        verify(mWindowManager, never()).removeView(any())
     }
 
     @Test
@@ -691,8 +657,8 @@
         mMainExecutor.runAllReady()
 
         // Verify that a new window is added.
-        verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
-        val windowDecorView = mViewCaptor!!.value
+        verify(mWindowManager).addView(mViewCaptor.capture(), any())
+        val windowDecorView = mViewCaptor.firstValue
 
         // Assert that the overlay is not showing complications.
         assertThat(mService.shouldShowComplications()).isFalse()
@@ -751,7 +717,7 @@
     @Test
     fun testWakeUpBeforeStartDoesNothing() {
         mService.onWakeUp()
-        verify(mDreamOverlayContainerViewController, Mockito.never()).onWakeUp()
+        verify(mDreamOverlayContainerViewController, never()).onWakeUp()
     }
 
     @Test
@@ -879,8 +845,8 @@
         )
         mMainExecutor.runAllReady()
 
-        whenever(mDreamOverlayContainerViewController.isBouncerShowing()).thenReturn(true)
-        mService!!.onComeToFront()
+        whenever(mDreamOverlayContainerViewController.isBouncerShowing).thenReturn(true)
+        mService.onComeToFront()
         verify(mScrimController).expand(any())
     }
 
@@ -900,7 +866,7 @@
         )
         mMainExecutor.runAllReady()
 
-        mService!!.onComeToFront()
+        mService.onComeToFront()
         assertThat(communalRepository.currentScene.value).isEqualTo(CommunalScenes.Blank)
     }
 
@@ -920,7 +886,7 @@
         )
         mMainExecutor.runAllReady()
 
-        mService!!.onComeToFront()
+        mService.onComeToFront()
         verify(mSystemDialogsCloser).closeSystemDialogs()
     }
 
@@ -1320,6 +1286,45 @@
         environmentComponents.verifyNoMoreInteractions()
     }
 
+    @DisableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+    @Test
+    fun testAmbientTouchHandlersRegistration_registerHideComplicationAndCommunal() {
+        val client = client
+
+        // Inform the overlay service of dream starting.
+        client.startDream(
+            mWindowParams,
+            mDreamOverlayCallback,
+            DREAM_COMPONENT,
+            false /*isPreview*/,
+            false, /*shouldShowComplication*/
+        )
+        mMainExecutor.runAllReady()
+
+        verify(mAmbientTouchComponentFactory).create(any(), mTouchHandlersCaptor.capture(), any())
+        assertThat(mTouchHandlersCaptor.firstValue)
+            .containsExactly(mHideComplicationTouchHandler, mCommunalTouchHandler)
+    }
+
+    @EnableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+    @Test
+    fun testAmbientTouchHandlersRegistration_v2_registerOnlyHideComplication() {
+        val client = client
+
+        // Inform the overlay service of dream starting.
+        client.startDream(
+            mWindowParams,
+            mDreamOverlayCallback,
+            DREAM_COMPONENT,
+            false /*isPreview*/,
+            false, /*shouldShowComplication*/
+        )
+        mMainExecutor.runAllReady()
+
+        verify(mAmbientTouchComponentFactory).create(any(), mTouchHandlersCaptor.capture(), any())
+        assertThat(mTouchHandlersCaptor.firstValue).containsExactly(mHideComplicationTouchHandler)
+    }
+
     internal class FakeLifecycleRegistry(provider: LifecycleOwner) : LifecycleRegistry(provider) {
         val mLifecycles: MutableList<State> = ArrayList()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index b46f2aa..5a1d8bb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -76,7 +76,7 @@
 
     @Test
     public void testStateChange_overlayActive() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
         stateController.addCallback(mCallback);
         stateController.setOverlayActive(true);
         mExecutor.runAllReady();
@@ -97,7 +97,7 @@
 
     @Test
     public void testCallback() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
         stateController.addCallback(mCallback);
 
         // Add complication and verify callback is notified.
@@ -122,7 +122,7 @@
 
     @Test
     public void testNotifyOnCallbackAdd() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
 
         stateController.addComplication(mComplication);
         mExecutor.runAllReady();
@@ -134,22 +134,8 @@
     }
 
     @Test
-    public void testNotifyOnCallbackAddOverlayDisabled() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(false);
-
-        stateController.addComplication(mComplication);
-        mExecutor.runAllReady();
-
-        // Verify callback occurs on add when an overlay is already present.
-        stateController.addCallback(mCallback);
-        mExecutor.runAllReady();
-        verify(mCallback, never()).onComplicationsChanged();
-    }
-
-
-    @Test
     public void testComplicationFilteringWhenShouldShowComplications() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
         stateController.setShouldShowComplications(true);
 
         final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
@@ -188,7 +174,7 @@
 
     @Test
     public void testComplicationFilteringWhenShouldHideComplications() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
         stateController.setShouldShowComplications(true);
 
         final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
@@ -234,7 +220,7 @@
     @Test
     public void testComplicationWithNoTypeNotFiltered() {
         final Complication complication = Mockito.mock(Complication.class);
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
         stateController.addComplication(complication);
         mExecutor.runAllReady();
         assertThat(stateController.getComplications(true).contains(complication))
@@ -244,7 +230,7 @@
     @Test
     public void testComplicationsNotShownForHomeControlPanelDream() {
         final Complication complication = Mockito.mock(Complication.class);
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
 
         // Add a complication and verify it's returned in getComplications.
         stateController.addComplication(complication);
@@ -261,7 +247,7 @@
     @Test
     public void testComplicationsNotShownForLowLight() {
         final Complication complication = Mockito.mock(Complication.class);
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
 
         // Add a complication and verify it's returned in getComplications.
         stateController.addComplication(complication);
@@ -277,7 +263,7 @@
 
     @Test
     public void testNotifyLowLightChanged() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
 
         stateController.addCallback(mCallback);
         mExecutor.runAllReady();
@@ -292,7 +278,7 @@
 
     @Test
     public void testNotifyLowLightExit() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
 
         stateController.addCallback(mCallback);
         mExecutor.runAllReady();
@@ -315,7 +301,7 @@
 
     @Test
     public void testNotifyEntryAnimationsFinishedChanged() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
 
         stateController.addCallback(mCallback);
         mExecutor.runAllReady();
@@ -330,7 +316,7 @@
 
     @Test
     public void testNotifyDreamOverlayStatusBarVisibleChanged() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
 
         stateController.addCallback(mCallback);
         mExecutor.runAllReady();
@@ -345,7 +331,7 @@
 
     @Test
     public void testNotifyHasAssistantAttentionChanged() {
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
 
         stateController.addCallback(mCallback);
         mExecutor.runAllReady();
@@ -362,7 +348,7 @@
     public void testShouldShowComplicationsSetToFalse_stillShowsHomeControls_featureEnabled() {
         when(mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)).thenReturn(true);
 
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
         stateController.setShouldShowComplications(true);
 
         final Complication homeControlsComplication = Mockito.mock(Complication.class);
@@ -404,7 +390,7 @@
     public void testHomeControlsDoNotShowIfNotAvailable_featureEnabled() {
         when(mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)).thenReturn(true);
 
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
         stateController.setShouldShowComplications(true);
 
         final Complication homeControlsComplication = Mockito.mock(Complication.class);
@@ -435,7 +421,7 @@
         final DreamOverlayStateController.Callback callback2 = Mockito.mock(
                 DreamOverlayStateController.Callback.class);
 
-        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        final DreamOverlayStateController stateController = getDreamOverlayStateController();
         stateController.addCallback(callback1);
         stateController.addCallback(callback2);
         mExecutor.runAllReady();
@@ -451,10 +437,9 @@
         assertThat(stateController.isOverlayActive()).isTrue();
     }
 
-    private DreamOverlayStateController getDreamOverlayStateController(boolean overlayEnabled) {
+    private DreamOverlayStateController getDreamOverlayStateController() {
         return new DreamOverlayStateController(
                 mExecutor,
-                overlayEnabled,
                 mFeatureFlags,
                 mLogBuffer,
                 mWeakReferenceFactory
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
index aacfaed..55b87db 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
@@ -27,6 +27,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.communal.domain.interactor.setCommunalAvailable
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.flags.EnableSceneContainer
@@ -39,7 +40,6 @@
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.shared.model.Overlays
-import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
 import com.android.systemui.shade.data.repository.fakeShadeRepository
@@ -73,8 +73,10 @@
 
     @Test
     @DisableFlags(DualShade.FLAG_NAME)
-    fun actions_singleShade() =
+    fun actions_communalNotAvailable_singleShade() =
         testScope.runTest {
+            kosmos.setCommunalAvailable(false)
+
             val actions by collectLastValue(underTest.actions)
 
             setUpState(
@@ -83,10 +85,11 @@
                 shadeMode = ShadeMode.Single,
             )
             assertThat(actions).isNotEmpty()
-            assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
             assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
             assertThat(actions?.get(Swipe.Down))
                 .isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
+            assertThat(actions?.get(Swipe.Start)).isNull()
+            assertThat(actions?.get(Swipe.End)).isNull()
 
             setUpState(
                 isShadeTouchable = false,
@@ -101,16 +104,19 @@
                 shadeMode = ShadeMode.Single,
             )
             assertThat(actions).isNotEmpty()
-            assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
             assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
             assertThat(actions?.get(Swipe.Down))
                 .isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
+            assertThat(actions?.get(Swipe.Start)).isNull()
+            assertThat(actions?.get(Swipe.End)).isNull()
         }
 
     @Test
     @DisableFlags(DualShade.FLAG_NAME)
-    fun actions_splitShade() =
+    fun actions_communalNotAvailable_splitShade() =
         testScope.runTest {
+            kosmos.setCommunalAvailable(false)
+
             val actions by collectLastValue(underTest.actions)
 
             setUpState(
@@ -119,10 +125,11 @@
                 shadeMode = ShadeMode.Split,
             )
             assertThat(actions).isNotEmpty()
-            assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
             assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
             assertThat(actions?.get(Swipe.Down))
                 .isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
+            assertThat(actions?.get(Swipe.Start)).isNull()
+            assertThat(actions?.get(Swipe.End)).isNull()
 
             setUpState(
                 isShadeTouchable = false,
@@ -137,16 +144,19 @@
                 shadeMode = ShadeMode.Split,
             )
             assertThat(actions).isNotEmpty()
-            assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
             assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
             assertThat(actions?.get(Swipe.Down))
                 .isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
+            assertThat(actions?.get(Swipe.Start)).isNull()
+            assertThat(actions?.get(Swipe.End)).isNull()
         }
 
     @Test
     @EnableFlags(DualShade.FLAG_NAME)
-    fun actions_dualShade() =
+    fun actions_communalNotAvailable_dualShade() =
         testScope.runTest {
+            kosmos.setCommunalAvailable(false)
+
             val actions by collectLastValue(underTest.actions)
 
             setUpState(
@@ -155,12 +165,13 @@
                 shadeMode = ShadeMode.Dual,
             )
             assertThat(actions).isNotEmpty()
-            assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
             assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
             assertThat(actions?.get(Swipe.Down))
                 .isEqualTo(
                     UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true)
                 )
+            assertThat(actions?.get(Swipe.Start)).isNull()
+            assertThat(actions?.get(Swipe.End)).isNull()
 
             setUpState(
                 isShadeTouchable = false,
@@ -171,12 +182,133 @@
 
             setUpState(isShadeTouchable = true, isDeviceUnlocked = true, shadeMode = ShadeMode.Dual)
             assertThat(actions).isNotEmpty()
-            assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
             assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
             assertThat(actions?.get(Swipe.Down))
                 .isEqualTo(
                     UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true)
                 )
+            assertThat(actions?.get(Swipe.Start)).isNull()
+            assertThat(actions?.get(Swipe.End)).isNull()
+        }
+
+    @Test
+    @DisableFlags(DualShade.FLAG_NAME)
+    fun actions_communalAvailable_singleShade() =
+        testScope.runTest {
+            kosmos.setCommunalAvailable(true)
+
+            val actions by collectLastValue(underTest.actions)
+
+            setUpState(
+                isShadeTouchable = true,
+                isDeviceUnlocked = false,
+                shadeMode = ShadeMode.Single,
+            )
+            assertThat(actions).isNotEmpty()
+            assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+            assertThat(actions?.get(Swipe.Down))
+                .isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
+            assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+            assertThat(actions?.get(Swipe.End)).isNull()
+
+            setUpState(
+                isShadeTouchable = false,
+                isDeviceUnlocked = false,
+                shadeMode = ShadeMode.Single,
+            )
+            assertThat(actions).isEmpty()
+
+            setUpState(
+                isShadeTouchable = true,
+                isDeviceUnlocked = true,
+                shadeMode = ShadeMode.Single,
+            )
+            assertThat(actions).isNotEmpty()
+            assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
+            assertThat(actions?.get(Swipe.Down))
+                .isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
+            assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+            assertThat(actions?.get(Swipe.End)).isNull()
+        }
+
+    @Test
+    @DisableFlags(DualShade.FLAG_NAME)
+    fun actions_communalAvailable_splitShade() =
+        testScope.runTest {
+            kosmos.setCommunalAvailable(true)
+
+            val actions by collectLastValue(underTest.actions)
+
+            setUpState(
+                isShadeTouchable = true,
+                isDeviceUnlocked = false,
+                shadeMode = ShadeMode.Split,
+            )
+            assertThat(actions).isNotEmpty()
+            assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+            assertThat(actions?.get(Swipe.Down))
+                .isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
+            assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+            assertThat(actions?.get(Swipe.End)).isNull()
+
+            setUpState(
+                isShadeTouchable = false,
+                isDeviceUnlocked = false,
+                shadeMode = ShadeMode.Split,
+            )
+            assertThat(actions).isEmpty()
+
+            setUpState(
+                isShadeTouchable = true,
+                isDeviceUnlocked = true,
+                shadeMode = ShadeMode.Split,
+            )
+            assertThat(actions).isNotEmpty()
+            assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
+            assertThat(actions?.get(Swipe.Down))
+                .isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
+            assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+            assertThat(actions?.get(Swipe.End)).isNull()
+        }
+
+    @Test
+    @EnableFlags(DualShade.FLAG_NAME)
+    fun actions_communalAvailable_dualShade() =
+        testScope.runTest {
+            kosmos.setCommunalAvailable(true)
+
+            val actions by collectLastValue(underTest.actions)
+
+            setUpState(
+                isShadeTouchable = true,
+                isDeviceUnlocked = false,
+                shadeMode = ShadeMode.Dual,
+            )
+            assertThat(actions).isNotEmpty()
+            assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+            assertThat(actions?.get(Swipe.Down))
+                .isEqualTo(
+                    UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true)
+                )
+            assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+            assertThat(actions?.get(Swipe.End)).isNull()
+
+            setUpState(
+                isShadeTouchable = false,
+                isDeviceUnlocked = false,
+                shadeMode = ShadeMode.Dual,
+            )
+            assertThat(actions).isEmpty()
+
+            setUpState(isShadeTouchable = true, isDeviceUnlocked = true, shadeMode = ShadeMode.Dual)
+            assertThat(actions).isNotEmpty()
+            assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
+            assertThat(actions?.get(Swipe.Down))
+                .isEqualTo(
+                    UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true)
+                )
+            assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+            assertThat(actions?.get(Swipe.End)).isNull()
         }
 
     private fun TestScope.setUpState(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt
index dd83702..e288522 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.contextualeducation.GestureType
 import com.android.systemui.contextualeducation.GestureType.BACK
+import com.android.systemui.contextualeducation.GestureType.HOME
 import com.android.systemui.education.data.repository.fakeEduClock
 import com.android.systemui.education.domain.interactor.KeyboardTouchpadEduInteractor
 import com.android.systemui.education.domain.interactor.contextualEducationInteractor
@@ -52,6 +53,7 @@
 import org.mockito.Mock
 import org.mockito.junit.MockitoJUnit
 import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
@@ -66,6 +68,7 @@
     private val minDurationForNextEdu =
         KeyboardTouchpadEduInteractor.minIntervalBetweenEdu + 1.seconds
     private lateinit var underTest: ContextualEduUiCoordinator
+    private lateinit var previousDialog: Dialog
     @Mock private lateinit var dialog: Dialog
     @Mock private lateinit var notificationManager: NotificationManager
     @Mock private lateinit var accessibilityManagerWrapper: AccessibilityManagerWrapper
@@ -95,9 +98,11 @@
                 kosmos.applicationCoroutineScope,
                 viewModel,
                 kosmos.applicationContext,
-                notificationManager
+                notificationManager,
             ) { model ->
                 toastContent = model.message
+                previousDialog = dialog
+                dialog = mock<Dialog>()
                 dialog
             }
         underTest.start()
@@ -129,6 +134,14 @@
         }
 
     @Test
+    fun dismissPreviousDialogOnNewDialog() =
+        testScope.runTest {
+            triggerEducation(BACK)
+            triggerEducation(HOME)
+            verify(previousDialog).dismiss()
+        }
+
+    @Test
     fun verifyBackEduToastContent() =
         testScope.runTest {
             triggerEducation(BACK)
@@ -149,14 +162,14 @@
             verifyNotificationContent(
                 R.string.back_edu_notification_title,
                 R.string.back_edu_notification_content,
-                notificationCaptor.value
+                notificationCaptor.value,
             )
         }
 
     private fun verifyNotificationContent(
         titleResId: Int,
         contentResId: Int,
-        notification: Notification
+        notification: Notification,
     ) {
         val expectedContent = context.getString(contentResId)
         val expectedTitle = context.getString(titleResId)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
index 366b55d..329f90a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
@@ -398,6 +398,16 @@
             verify(controller).onTransitionAnimationCancelled(newOccludedState)
         }
 
+    @Test
+    fun onTileLongClick_whileIdle_performsLongClick() =
+        testWhileInState(QSLongPressEffect.State.IDLE) {
+            // WHEN a long-click is detected by the view
+            val longClicks = longPressEffect.onTileLongClick()
+
+            // THEN the long click is handled
+            assertThat(longClicks).isTrue()
+        }
+
     private fun testWithScope(initialize: Boolean = true, test: suspend TestScope.() -> Unit) =
         with(kosmos) {
             testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
index 639737b..76434ee 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
@@ -27,9 +27,11 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
 import com.android.systemui.inputdevice.tutorial.domain.interactor.KeyboardTouchpadConnectionInteractor
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEY
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEYBOARD
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEY
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME
 import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.ACTION_KEY
 import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.BACK_GESTURE
 import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.HOME_GESTURE
@@ -66,8 +68,8 @@
     private val sysUiState = kosmos.sysUiState
     private val touchpadRepo = PrettyFakeTouchpadRepository()
     private val keyboardRepo = kosmos.keyboardRepository
-    private var startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
-    private val viewModel by lazy { createViewModel(startingPeripheral) }
+    private var tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
+    private val viewModel by lazy { createViewModel(tutorialScope) }
 
     // createUnsafe so its methods don't have to be called on Main thread
     private val lifecycle = LifecycleRegistry.createUnsafe(mock(LifecycleOwner::class.java))
@@ -75,7 +77,7 @@
     @get:Rule val mainDispatcherRule = MainDispatcherRule(kosmos.testDispatcher)
 
     private fun createViewModel(
-        startingPeripheral: String = INTENT_TUTORIAL_TYPE_TOUCHPAD,
+        scope: String = INTENT_TUTORIAL_SCOPE_TOUCHPAD,
         hasTouchpadTutorialScreens: Boolean = true,
     ): KeyboardTouchpadTutorialViewModel {
         val viewModel =
@@ -84,7 +86,7 @@
                 KeyboardTouchpadConnectionInteractor(keyboardRepo, touchpadRepo),
                 hasTouchpadTutorialScreens,
                 mock<InputDeviceTutorialLogger>(),
-                SavedStateHandle(mapOf(INTENT_TUTORIAL_TYPE_KEY to startingPeripheral))
+                SavedStateHandle(mapOf(INTENT_TUTORIAL_SCOPE_KEY to scope)),
             )
         lifecycle.addObserver(viewModel)
         return viewModel
@@ -169,7 +171,7 @@
     @Test
     fun screensOrder_whenGoingBackAndOnlyKeyboardConnected() =
         testScope.runTest {
-            startingPeripheral = INTENT_TUTORIAL_TYPE_KEYBOARD
+            tutorialScope = INTENT_TUTORIAL_SCOPE_KEYBOARD
             val screens by collectValues(viewModel.screen)
             val closeActivity by collectLastValue(viewModel.closeActivity)
             peripheralsState(keyboardConnected = true, touchpadConnected = false)
@@ -185,7 +187,7 @@
     @Test
     fun screensOrder_whenTouchpadConnected() =
         testScope.runTest {
-            startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
+            tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
             val screens by collectValues(viewModel.screen)
             val closeActivity by collectLastValue(viewModel.closeActivity)
 
@@ -193,22 +195,47 @@
 
             goToNextScreen()
             goToNextScreen()
-            goToNextScreen()
 
             assertThat(screens).containsExactly(BACK_GESTURE, HOME_GESTURE).inOrder()
             assertThat(closeActivity).isTrue()
         }
 
     @Test
-    fun screensOrder_whenKeyboardConnected() =
+    fun screensOrder_withBackGestureScope() =
         testScope.runTest {
-            startingPeripheral = INTENT_TUTORIAL_TYPE_KEYBOARD
+            tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK
             val screens by collectValues(viewModel.screen)
             val closeActivity by collectLastValue(viewModel.closeActivity)
-
-            peripheralsState(keyboardConnected = true)
+            peripheralsState(touchpadConnected = true)
 
             goToNextScreen()
+
+            assertThat(screens).containsExactly(BACK_GESTURE).inOrder()
+            assertThat(closeActivity).isTrue()
+        }
+
+    @Test
+    fun screensOrder_withHomeGestureScope() =
+        testScope.runTest {
+            tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME
+            val screens by collectValues(viewModel.screen)
+            val closeActivity by collectLastValue(viewModel.closeActivity)
+            peripheralsState(touchpadConnected = true)
+
+            goToNextScreen()
+
+            assertThat(screens).containsExactly(HOME_GESTURE).inOrder()
+            assertThat(closeActivity).isTrue()
+        }
+
+    @Test
+    fun screensOrder_withKeyboardScope() =
+        testScope.runTest {
+            tutorialScope = INTENT_TUTORIAL_SCOPE_KEYBOARD
+            val screens by collectValues(viewModel.screen)
+            val closeActivity by collectLastValue(viewModel.closeActivity)
+            peripheralsState(keyboardConnected = true)
+
             goToNextScreen()
 
             assertThat(screens).containsExactly(ACTION_KEY).inOrder()
@@ -218,7 +245,7 @@
     @Test
     fun touchpadGesturesDisabled_onlyDuringTouchpadTutorial() =
         testScope.runTest {
-            startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
+            tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
             collectValues(viewModel.screen) // just to initialize viewModel
             peripheralsState(keyboardConnected = true, touchpadConnected = true)
 
@@ -234,8 +261,8 @@
         testScope.runTest {
             val viewModel =
                 createViewModel(
-                    startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD,
-                    hasTouchpadTutorialScreens = false
+                    scope = INTENT_TUTORIAL_SCOPE_TOUCHPAD,
+                    hasTouchpadTutorialScreens = false,
                 )
             val screens by collectValues(viewModel.screen)
             val closeActivity by collectLastValue(viewModel.closeActivity)
@@ -248,7 +275,7 @@
     @Test
     fun touchpadGesturesDisabled_whenTutorialGoesToForeground() =
         testScope.runTest {
-            startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
+            tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
             collectValues(viewModel.screen) // just to initialize viewModel
             peripheralsState(touchpadConnected = true)
 
@@ -260,7 +287,7 @@
     @Test
     fun touchpadGesturesNotDisabled_whenTutorialGoesToBackground() =
         testScope.runTest {
-            startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
+            tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
             collectValues(viewModel.screen)
             peripheralsState(touchpadConnected = true)
 
@@ -288,7 +315,7 @@
 
     private fun TestScope.peripheralsState(
         keyboardConnected: Boolean = false,
-        touchpadConnected: Boolean = false
+        touchpadConnected: Boolean = false,
     ) {
         keyboardRepo.setIsAnyKeyboardConnected(keyboardConnected)
         touchpadRepo.setIsAnyTouchpadConnected(touchpadConnected)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt
index 27b8c59..0d32b7f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt
@@ -18,27 +18,30 @@
 
 import android.content.Context
 import android.content.Context.INPUT_SERVICE
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS
 import android.hardware.input.fakeInputManager
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.view.KeyEvent.KEYCODE_SLASH
-import android.view.KeyEvent.META_ALT_ON
 import android.view.KeyEvent.META_CAPS_LOCK_ON
-import android.view.KeyEvent.META_CTRL_ON
-import android.view.KeyEvent.META_FUNCTION_ON
 import android.view.KeyEvent.META_META_ON
-import android.view.KeyEvent.META_SHIFT_ON
-import android.view.KeyEvent.META_SYM_ON
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.hardware.input.Flags.FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES
 import com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
 import com.android.systemui.keyboard.shortcut.customShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.ALL_SUPPORTED_MODIFIERS
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allAppsInputGestureData
 import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allCustomizableInputGesturesWithSimpleShortcutCombinations
 import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.customizableInputGestureWithUnknownKeyGestureType
 import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedShortcutCategoriesWithSimpleShortcutCombination
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.goHomeInputGestureData
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardAddCustomShortcutRequestInfo
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardDeleteCustomShortcutRequestInfo
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardKeyCombination
 import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
 import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
@@ -66,24 +69,21 @@
             it.userTracker = FakeUserTracker(onCreateCurrentUserContext = { mockUserContext })
         }
 
-    private val fakeInputManager = kosmos.fakeInputManager
+    private val inputManager = kosmos.fakeInputManager.inputManager
     private val testScope = kosmos.testScope
     private val helper = kosmos.shortcutHelperTestHelper
     private val repo = kosmos.customShortcutCategoriesRepository
 
     @Before
     fun setup() {
-        whenever(mockUserContext.getSystemService(INPUT_SERVICE))
-            .thenReturn(fakeInputManager.inputManager)
+        whenever(mockUserContext.getSystemService(INPUT_SERVICE)).thenReturn(inputManager)
     }
 
     @Test
     @EnableFlags(FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES, FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
     fun categories_emitsCorrectlyConvertedShortcutCategories() {
         testScope.runTest {
-            whenever(
-                    fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull())
-                )
+            whenever(inputManager.getCustomInputGestures(/* filter= */ anyOrNull()))
                 .thenReturn(allCustomizableInputGesturesWithSimpleShortcutCombinations)
 
             helper.toggle(deviceId = 123)
@@ -98,9 +98,7 @@
     @DisableFlags(FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES, FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
     fun categories_emitsEmptyListWhenFlagIsDisabled() {
         testScope.runTest {
-            whenever(
-                    fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull())
-                )
+            whenever(inputManager.getCustomInputGestures(/* filter= */ anyOrNull()))
                 .thenReturn(allCustomizableInputGesturesWithSimpleShortcutCombinations)
 
             helper.toggle(deviceId = 123)
@@ -114,9 +112,7 @@
     @EnableFlags(FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES, FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
     fun categories_ignoresUnknownKeyGestureTypes() {
         testScope.runTest {
-            whenever(
-                    fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull())
-                )
+            whenever(inputManager.getCustomInputGestures(/* filter= */ anyOrNull()))
                 .thenReturn(customizableInputGestureWithUnknownKeyGestureType)
 
             helper.toggle(deviceId = 123)
@@ -143,7 +139,7 @@
             helper.toggle(deviceId = 123)
             val pressedKeys by collectLastValue(repo.pressedKeys)
             repo.updateUserKeyCombination(
-                KeyCombination(modifiers = allSupportedModifiers, keyCode = null)
+                KeyCombination(modifiers = ALL_SUPPORTED_MODIFIERS, keyCode = null)
             )
 
             assertThat(pressedKeys)
@@ -188,11 +184,71 @@
         }
     }
 
-    private val allSupportedModifiers =
-        META_META_ON or
-            META_CTRL_ON or
-            META_FUNCTION_ON or
-            META_SHIFT_ON or
-            META_ALT_ON or
-            META_SYM_ON
+    @Test
+    fun shortcutBeingCustomized_updatedOnCustomizationRequested() {
+        testScope.runTest {
+            repo.onCustomizationRequested(standardAddCustomShortcutRequestInfo)
+
+            val shortcutBeingCustomized = repo.getShortcutBeingCustomized()
+
+            assertThat(shortcutBeingCustomized).isEqualTo(standardAddCustomShortcutRequestInfo)
+        }
+    }
+
+    @Test
+    fun buildInputGestureDataForShortcutBeingCustomized_noShortcutBeingCustomized_returnsNull() {
+        testScope.runTest {
+            helper.toggle(deviceId = 123)
+            repo.updateUserKeyCombination(standardKeyCombination)
+
+            val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()
+
+            assertThat(inputGestureData).isNull()
+        }
+    }
+
+    @Test
+    fun buildInputGestureDataForShortcutBeingCustomized_noKeyCombinationSelected_returnsNull() {
+        testScope.runTest {
+            helper.toggle(deviceId = 123)
+            repo.onCustomizationRequested(standardAddCustomShortcutRequestInfo)
+
+            val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()
+
+            assertThat(inputGestureData).isNull()
+        }
+    }
+
+    @Test
+    fun buildInputGestureDataForShortcutBeingCustomized_successfullyBuildInputGestureData() {
+        testScope.runTest {
+            helper.toggle(deviceId = 123)
+            repo.onCustomizationRequested(standardAddCustomShortcutRequestInfo)
+            repo.updateUserKeyCombination(standardKeyCombination)
+            val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()
+
+            // using toString as we're testing for only structural equality not referential.
+            // inputGestureData is a java class and isEqual Tests for referential equality
+            // as well which would cause this assert to fail
+            assertThat(inputGestureData.toString()).isEqualTo(allAppsInputGestureData.toString())
+        }
+    }
+
+    @Test
+    @EnableFlags(FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES, FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
+    fun deleteShortcut_successfullyRetrievesGestureDataAndDeletesShortcut() {
+        testScope.runTest {
+            whenever(inputManager.getCustomInputGestures(anyOrNull()))
+                .thenReturn(listOf(allAppsInputGestureData, goHomeInputGestureData))
+            whenever(inputManager.removeCustomInputGesture(allAppsInputGestureData))
+                .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_SUCCESS)
+
+            helper.toggle(deviceId = 123)
+            repo.onCustomizationRequested(standardDeleteCustomShortcutRequestInfo)
+
+            val result = repo.deleteShortcutCurrentlyBeingCustomized()
+
+            assertThat(result).isEqualTo(ShortcutCustomizationRequestResult.SUCCESS)
+        }
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
index a1e7ef4..8466eab 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
@@ -19,9 +19,23 @@
 import android.hardware.input.InputGestureData
 import android.hardware.input.InputGestureData.createKeyTrigger
 import android.hardware.input.KeyGestureEvent
+import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
+import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_HOME
+import android.os.SystemClock
 import android.view.KeyEvent
+import android.view.KeyEvent.ACTION_DOWN
+import android.view.KeyEvent.KEYCODE_A
+import android.view.KeyEvent.META_ALT_ON
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_FUNCTION_ON
+import android.view.KeyEvent.META_META_LEFT_ON
+import android.view.KeyEvent.META_META_ON
+import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyEvent.META_SHIFT_RIGHT_ON
+import android.view.KeyEvent.META_SYM_ON
 import android.view.KeyboardShortcutGroup
 import android.view.KeyboardShortcutInfo
+import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
 import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
@@ -29,9 +43,11 @@
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
 import com.android.systemui.keyboard.shortcut.shared.model.shortcut
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
 import com.android.systemui.res.R
 
 object TestShortcuts {
@@ -525,4 +541,110 @@
                 keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER
             ),
         )
+
+    val standardAddCustomShortcutRequestInfo =
+        ShortcutCustomizationRequestInfo.Add(
+            label = "Open apps list",
+            categoryType = System,
+            subCategoryLabel = "System controls",
+        )
+
+    val standardDeleteCustomShortcutRequestInfo =
+        ShortcutCustomizationRequestInfo.Delete(
+            label = "Open apps list",
+            categoryType = System,
+            subCategoryLabel = "System controls",
+        )
+
+    val standardKeyCombination =
+        KeyCombination(
+            modifiers = META_META_ON or META_SHIFT_ON or META_META_LEFT_ON or META_SHIFT_RIGHT_ON,
+            keyCode = KEYCODE_A,
+        )
+
+    const val ALL_SUPPORTED_MODIFIERS =
+        META_META_ON or
+            META_CTRL_ON or
+            META_FUNCTION_ON or
+            META_SHIFT_ON or
+            META_ALT_ON or
+            META_SYM_ON
+
+    val allAppsInputGestureData: InputGestureData =
+        InputGestureData.Builder()
+            .setKeyGestureType(KEY_GESTURE_TYPE_ALL_APPS)
+            .setTrigger(
+                createKeyTrigger(
+                    /* keycode = */ standardKeyCombination.keyCode!!,
+                    /* modifierState = */ standardKeyCombination.modifiers and
+                        ALL_SUPPORTED_MODIFIERS,
+                )
+            )
+            .build()
+
+    val goHomeInputGestureData: InputGestureData =
+        InputGestureData.Builder()
+            .setKeyGestureType(KEY_GESTURE_TYPE_HOME)
+            .setTrigger(
+                createKeyTrigger(
+                    /* keycode = */ standardKeyCombination.keyCode!!,
+                    /* modifierState = */ standardKeyCombination.modifiers and
+                        ALL_SUPPORTED_MODIFIERS,
+                )
+            )
+            .build()
+
+    val expectedStandardDeleteShortcutUiState =
+        ShortcutCustomizationUiState.DeleteShortcutDialog(isDialogShowing = false)
+
+    val keyDownEventWithoutActionKeyPressed =
+        androidx.compose.ui.input.key.KeyEvent(
+            android.view.KeyEvent(
+                /* downTime = */ SystemClock.uptimeMillis(),
+                /* eventTime = */ SystemClock.uptimeMillis(),
+                /* action = */ ACTION_DOWN,
+                /* code = */ KEYCODE_A,
+                /* repeat = */ 0,
+                /* metaState = */ META_CTRL_ON,
+            )
+        )
+
+    val keyDownEventWithActionKeyPressed =
+        androidx.compose.ui.input.key.KeyEvent(
+            android.view.KeyEvent(
+                /* downTime = */ SystemClock.uptimeMillis(),
+                /* eventTime = */ SystemClock.uptimeMillis(),
+                /* action = */ ACTION_DOWN,
+                /* code = */ KEYCODE_A,
+                /* repeat = */ 0,
+                /* metaState = */ META_CTRL_ON or META_META_ON,
+            )
+        )
+
+    val keyUpEventWithActionKeyPressed =
+        androidx.compose.ui.input.key.KeyEvent(
+            android.view.KeyEvent(
+                /* downTime = */ SystemClock.uptimeMillis(),
+                /* eventTime = */ SystemClock.uptimeMillis(),
+                /* action = */ ACTION_DOWN,
+                /* code = */ KEYCODE_A,
+                /* repeat = */ 0,
+                /* metaState = */ 0,
+            )
+        )
+
+    val standardAddShortcutRequest =
+        ShortcutCustomizationRequestInfo.Add(
+            label = "Standard shortcut",
+            categoryType = ShortcutCategoryType.System,
+            subCategoryLabel = "Standard subcategory",
+        )
+
+    val expectedStandardAddShortcutUiState =
+        ShortcutCustomizationUiState.AddShortcutDialog(
+            shortcutLabel = "Standard shortcut",
+            defaultCustomShortcutModifierKey =
+                ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta),
+            isDialogShowing = false,
+        )
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
new file mode 100644
index 0000000..d0ce34c
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
@@ -0,0 +1,316 @@
+/*
+ * 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.keyboard.shortcut.ui.viewmodel
+
+import android.content.Context
+import android.content.Context.INPUT_SERVICE
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_ALREADY_EXISTS
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_OTHER
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_RESERVED_GESTURE
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS
+import android.hardware.input.fakeInputManager
+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.keyboard.shortcut.data.source.TestShortcuts.allAppsInputGestureData
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedStandardAddShortcutUiState
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedStandardDeleteShortcutUiState
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.goHomeInputGestureData
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.keyDownEventWithActionKeyPressed
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.keyDownEventWithoutActionKeyPressed
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.keyUpEventWithActionKeyPressed
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardAddCustomShortcutRequestInfo
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardAddShortcutRequest
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardDeleteCustomShortcutRequestInfo
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
+import com.android.systemui.keyboard.shortcut.shortcutCustomizationViewModelFactory
+import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.settings.userTracker
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ShortcutCustomizationViewModelTest : SysuiTestCase() {
+
+    private val mockUserContext: Context = mock()
+    private val kosmos =
+        Kosmos().also {
+            it.testCase = this
+            it.userTracker = FakeUserTracker(onCreateCurrentUserContext = { mockUserContext })
+        }
+    private val testScope = kosmos.testScope
+    private val inputManager = kosmos.fakeInputManager.inputManager
+    private val helper = kosmos.shortcutHelperTestHelper
+    private val viewModel = kosmos.shortcutCustomizationViewModelFactory.create()
+
+    @Before
+    fun setup() {
+        helper.showFromActivity()
+        whenever(mockUserContext.getSystemService(INPUT_SERVICE)).thenReturn(inputManager)
+    }
+
+    @Test
+    fun uiState_inactiveByDefault() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+
+            assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive)
+        }
+    }
+
+    @Test
+    fun uiState_correctlyUpdatedWhenAddShortcutCustomizationIsRequested() {
+        testScope.runTest {
+            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+
+            assertThat(uiState).isEqualTo(expectedStandardAddShortcutUiState)
+        }
+    }
+
+    @Test
+    fun uiState_correctlyUpdatedWhenDeleteShortcutCustomizationIsRequested() {
+        testScope.runTest {
+            viewModel.onShortcutCustomizationRequested(standardDeleteCustomShortcutRequestInfo)
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+
+            assertThat(uiState).isEqualTo(expectedStandardDeleteShortcutUiState)
+        }
+    }
+
+    @Test
+    fun uiState_consumedOnAddDialogShown() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+            viewModel.onDialogShown()
+
+            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).isDialogShowing)
+                .isTrue()
+        }
+    }
+
+    @Test
+    fun uiState_consumedOnDeleteDialogShown() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            viewModel.onShortcutCustomizationRequested(standardDeleteCustomShortcutRequestInfo)
+            viewModel.onDialogShown()
+
+            assertThat(
+                    (uiState as ShortcutCustomizationUiState.DeleteShortcutDialog).isDialogShowing
+                )
+                .isTrue()
+        }
+    }
+
+    @Test
+    fun uiState_inactiveAfterDialogIsDismissed() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+            viewModel.onDialogShown()
+            viewModel.onDialogDismissed()
+            assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive)
+        }
+    }
+
+    @Test
+    fun uiState_pressedKeys_emptyByDefault() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).pressedKeys)
+                .isEmpty()
+        }
+    }
+
+    @Test
+    fun uiState_becomeInactiveAfterSuccessfullySettingShortcut() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            whenever(inputManager.addCustomInputGesture(any()))
+                .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_SUCCESS)
+
+            openAddShortcutDialogAndSetShortcut()
+
+            assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive)
+        }
+    }
+
+    @Test
+    fun uiState_errorMessage_isEmptyByDefault() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            viewModel.onShortcutCustomizationRequested(standardAddCustomShortcutRequestInfo)
+            viewModel.onDialogShown()
+
+            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).errorMessage)
+                .isEmpty()
+        }
+    }
+
+    @Test
+    fun uiState_errorMessage_isKeyCombinationInUse_whenKeyCombinationAlreadyExists() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            whenever(inputManager.addCustomInputGesture(any()))
+                .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_ERROR_ALREADY_EXISTS)
+
+            openAddShortcutDialogAndSetShortcut()
+
+            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).errorMessage)
+                .isEqualTo(
+                    context.getString(
+                        R.string.shortcut_customizer_key_combination_in_use_error_message
+                    )
+                )
+        }
+    }
+
+    @Test
+    fun uiState_errorMessage_isKeyCombinationInUse_whenKeyCombinationIsReserved() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            whenever(inputManager.addCustomInputGesture(any()))
+                .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_ERROR_RESERVED_GESTURE)
+
+            openAddShortcutDialogAndSetShortcut()
+
+            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).errorMessage)
+                .isEqualTo(
+                    context.getString(
+                        R.string.shortcut_customizer_key_combination_in_use_error_message
+                    )
+                )
+        }
+    }
+
+    @Test
+    fun uiState_errorMessage_isGenericError_whenErrorIsUnknown() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            whenever(inputManager.addCustomInputGesture(any()))
+                .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_ERROR_OTHER)
+
+            openAddShortcutDialogAndSetShortcut()
+
+            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).errorMessage)
+                .isEqualTo(context.getString(R.string.shortcut_customizer_generic_error_message))
+        }
+    }
+
+    @Test
+    fun uiState_becomesInactiveAfterSuccessfullyDeletingShortcut() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            whenever(inputManager.getCustomInputGestures(any()))
+                .thenReturn(listOf(goHomeInputGestureData, allAppsInputGestureData))
+            whenever(inputManager.removeCustomInputGesture(any()))
+                .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_SUCCESS)
+
+            openDeleteShortcutDialogAndDeleteShortcut()
+
+            assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive)
+        }
+    }
+
+    @Test
+    fun onKeyPressed_handlesKeyEvents_whereActionKeyIsAlsoPressed() {
+        testScope.runTest {
+            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+            val isHandled = viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
+
+            assertThat(isHandled).isTrue()
+        }
+    }
+
+    @Test
+    fun onKeyPressed_doesNotHandleKeyEvents_whenActionKeyIsNotAlsoPressed() {
+        testScope.runTest {
+            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+            val isHandled = viewModel.onKeyPressed(keyDownEventWithoutActionKeyPressed)
+
+            assertThat(isHandled).isFalse()
+        }
+    }
+
+    @Test
+    fun onKeyPressed_convertsKeyEventsAndUpdatesUiStatesPressedKey() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+            viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
+            viewModel.onKeyPressed(keyUpEventWithActionKeyPressed)
+
+            // Note that Action Key is excluded as it's already displayed on the UI
+            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).pressedKeys)
+                .containsExactly(ShortcutKey.Text("Ctrl"), ShortcutKey.Text("A"))
+        }
+    }
+
+    @Test
+    fun uiState_pressedKeys_resetsToEmptyListAfterDialogIsDismissedAndReopened() {
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+            viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
+            viewModel.onKeyPressed(keyUpEventWithActionKeyPressed)
+
+            // Note that Action Key is excluded as it's already displayed on the UI
+            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).pressedKeys)
+                .containsExactly(ShortcutKey.Text("Ctrl"), ShortcutKey.Text("A"))
+
+            // Close the dialog and show it again
+            viewModel.onDialogDismissed()
+            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).pressedKeys)
+                .isEmpty()
+        }
+    }
+
+    private suspend fun openAddShortcutDialogAndSetShortcut() {
+        viewModel.onShortcutCustomizationRequested(standardAddCustomShortcutRequestInfo)
+        viewModel.onDialogShown()
+
+        viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
+        viewModel.onKeyPressed(keyUpEventWithActionKeyPressed)
+
+        viewModel.onSetShortcut()
+    }
+
+    private suspend fun openDeleteShortcutDialogAndDeleteShortcut() {
+        viewModel.onShortcutCustomizationRequested(standardDeleteCustomShortcutRequestInfo)
+        viewModel.onDialogShown()
+
+        viewModel.deleteShortcutCurrentlyBeingCustomized()
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt
new file mode 100644
index 0000000..77c615c
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.data.quickaffordance
+
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.repository.communalSceneRepository
+import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.setCommunalEnabled
+import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.andSceneContainer
+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.shared.model.Scenes
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+@EnableFlags(Flags.FLAG_GLANCEABLE_HUB_SHORTCUT_BUTTON)
+@RunWith(ParameterizedAndroidJunit4::class)
+class GlanceableHubQuickAffordanceConfigTest(flags: FlagsParameterization?) : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+
+    private lateinit var underTest: GlanceableHubQuickAffordanceConfig
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags!!)
+    }
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        underTest =
+            GlanceableHubQuickAffordanceConfig(
+                context = context,
+                communalInteractor = kosmos.communalInteractor,
+                communalSceneRepository = kosmos.communalSceneRepository,
+                sceneInteractor = kosmos.sceneInteractor,
+            )
+    }
+
+    @Test
+    fun lockscreenState_whenGlanceableHubEnabled_returnsVisible() =
+        testScope.runTest {
+            kosmos.setCommunalEnabled(true)
+            runCurrent()
+
+            val lockScreenState by collectLastValue(underTest.lockScreenState)
+
+            assertTrue(lockScreenState is KeyguardQuickAffordanceConfig.LockScreenState.Visible)
+        }
+
+    @Test
+    fun lockscreenState_whenGlanceableHubDisabled_returnsHidden() =
+        testScope.runTest {
+            kosmos.setCommunalEnabled(false)
+            val lockScreenState by collectLastValue(underTest.lockScreenState)
+            runCurrent()
+
+            assertTrue(lockScreenState is KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
+        }
+
+    @Test
+    fun pickerScreenState_whenGlanceableHubEnabled_returnsDefault() =
+        testScope.runTest {
+            kosmos.setCommunalEnabled(true)
+            runCurrent()
+
+            assertThat(underTest.getPickerScreenState())
+                .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
+        }
+
+    @Test
+    fun pickerScreenState_whenGlanceableHubDisabled_returnsDisabled() =
+        testScope.runTest {
+            kosmos.setCommunalEnabled(false)
+            runCurrent()
+
+            assertThat(
+                underTest.getPickerScreenState()
+                    is KeyguardQuickAffordanceConfig.PickerScreenState.Disabled
+            )
+        }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
+    fun onTriggered_changesSceneToCommunal() =
+        testScope.runTest {
+            underTest.onTriggered(expandable = null)
+            runCurrent()
+
+            assertThat(kosmos.communalSceneRepository.currentScene.value)
+                .isEqualTo(CommunalScenes.Communal)
+        }
+
+    @Test
+    @EnableFlags(Flags.FLAG_SCENE_CONTAINER)
+    fun testTransitionToGlanceableHub_sceneContainer() =
+        testScope.runTest {
+            underTest.onTriggered(expandable = null)
+            runCurrent()
+
+            assertThat(kosmos.sceneContainerRepository.currentScene.value)
+                .isEqualTo(Scenes.Communal)
+        }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return FlagsParameterization.allCombinationsOf(
+                    Flags.FLAG_GLANCEABLE_HUB_SHORTCUT_BUTTON
+                )
+                .andSceneContainer()
+        }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
index 0329794..0a4198a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
@@ -32,7 +32,8 @@
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -125,14 +126,11 @@
             )
 
         underTest =
-            HomeControlsKeyguardQuickAffordanceConfig(
-                context = context,
-                component = component,
-            )
+            HomeControlsKeyguardQuickAffordanceConfig(context = context, component = component)
     }
 
     @Test
-    fun state() = runBlockingTest {
+    fun state() = runTest(UnconfinedTestDispatcher()) {
         whenever(component.isEnabled()).thenReturn(isFeatureEnabled)
         whenever(controlsController.getFavorites())
             .thenReturn(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
index 7d68cc0..0003d07 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
@@ -19,19 +19,20 @@
 
 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.animation.Expandable
 import com.android.systemui.controls.controller.ControlsController
 import com.android.systemui.controls.dagger.ControlsComponent
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
+import com.android.systemui.res.R
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -54,14 +55,11 @@
         whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))
 
         underTest =
-            HomeControlsKeyguardQuickAffordanceConfig(
-                context = context,
-                component = component,
-            )
+            HomeControlsKeyguardQuickAffordanceConfig(context = context, component = component)
     }
 
     @Test
-    fun state_whenCannotShowWhileLocked_returnsHidden() = runBlockingTest {
+    fun state_whenCannotShowWhileLocked_returnsHidden() = runTest(UnconfinedTestDispatcher()) {
         whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
         whenever(component.isEnabled()).thenReturn(true)
         whenever(component.getTileImageId()).thenReturn(R.drawable.controls_icon)
@@ -81,7 +79,7 @@
     }
 
     @Test
-    fun state_whenListingControllerIsMissing_returnsHidden() = runBlockingTest {
+    fun state_whenListingControllerIsMissing_returnsHidden() = runTest(UnconfinedTestDispatcher()) {
         whenever(component.isEnabled()).thenReturn(true)
         whenever(component.getTileImageId()).thenReturn(R.drawable.controls_icon)
         whenever(component.getTileTitleId()).thenReturn(R.string.quick_controls_title)
@@ -100,23 +98,26 @@
     }
 
     @Test
-    fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsTrue() = runBlockingTest {
-        whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))
+    fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsTrue() =
+        runTest(UnconfinedTestDispatcher()) {
+            whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))
 
-        val onClickedResult = underTest.onTriggered(expandable)
+            val onClickedResult = underTest.onTriggered(expandable)
 
-        assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
-        assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked).isTrue()
-    }
+            assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
+            assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked)
+                .isTrue()
+        }
 
     @Test
-    fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsFalse() = runBlockingTest {
-        whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
+    fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsFalse() =
+        runTest(UnconfinedTestDispatcher()) {
+            whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
 
-        val onClickedResult = underTest.onTriggered(expandable)
+            val onClickedResult = underTest.onTriggered(expandable)
 
-        assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
-        assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked)
-            .isFalse()
-    }
+            assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
+            assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked)
+                .isFalse()
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
index ca64cec..05a74c0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
@@ -29,7 +29,7 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -56,60 +56,63 @@
     }
 
     @Test
-    fun affordance_setsUpRegistrationAndDeliversInitialModel() = runBlockingTest {
-        whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
-        var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+    fun affordance_setsUpRegistrationAndDeliversInitialModel() =
+        runTest(UnconfinedTestDispatcher()) {
+            whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+            var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
 
-        val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+            val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
 
-        val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
-        verify(controller).addCallback(callbackCaptor.capture())
-        verify(controller)
-            .registerQRCodeScannerChangeObservers(
-                QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
-                QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE
-            )
-        assertVisibleState(latest)
+            val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+            verify(controller).addCallback(callbackCaptor.capture())
+            verify(controller)
+                .registerQRCodeScannerChangeObservers(
+                    QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
+                    QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE,
+                )
+            assertVisibleState(latest)
 
-        job.cancel()
-        verify(controller).removeCallback(callbackCaptor.value)
-    }
+            job.cancel()
+            verify(controller).removeCallback(callbackCaptor.value)
+        }
 
     @Test
-    fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() = runBlockingTest {
-        whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
-        var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
-        val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
-        val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
-        verify(controller).addCallback(callbackCaptor.capture())
+    fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() =
+        runTest(UnconfinedTestDispatcher()) {
+            whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+            var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+            val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+            val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+            verify(controller).addCallback(callbackCaptor.capture())
 
-        whenever(controller.intent).thenReturn(INTENT_2)
-        callbackCaptor.value.onQRCodeScannerActivityChanged()
+            whenever(controller.intent).thenReturn(INTENT_2)
+            callbackCaptor.value.onQRCodeScannerActivityChanged()
 
-        assertVisibleState(latest)
+            assertVisibleState(latest)
 
-        job.cancel()
-        verify(controller).removeCallback(callbackCaptor.value)
-    }
+            job.cancel()
+            verify(controller).removeCallback(callbackCaptor.value)
+        }
 
     @Test
-    fun affordance_scannerPreferenceChanged_deliversVisibleModel() = runBlockingTest {
-        var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
-        val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
-        val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
-        verify(controller).addCallback(callbackCaptor.capture())
+    fun affordance_scannerPreferenceChanged_deliversVisibleModel() =
+        runTest(UnconfinedTestDispatcher()) {
+            var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+            val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+            val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+            verify(controller).addCallback(callbackCaptor.capture())
 
-        whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
-        callbackCaptor.value.onQRCodeScannerPreferenceChanged()
+            whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+            callbackCaptor.value.onQRCodeScannerPreferenceChanged()
 
-        assertVisibleState(latest)
+            assertVisibleState(latest)
 
-        job.cancel()
-        verify(controller).removeCallback(callbackCaptor.value)
-    }
+            job.cancel()
+            verify(controller).removeCallback(callbackCaptor.value)
+        }
 
     @Test
-    fun affordance_scannerPreferenceChanged_deliversNone() = runBlockingTest {
+    fun affordance_scannerPreferenceChanged_deliversNone() = runTest(UnconfinedTestDispatcher()) {
         var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
         val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
         val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
@@ -128,30 +131,29 @@
     fun onQuickAffordanceTriggered() {
         assertThat(underTest.onTriggered(mock()))
             .isEqualTo(
-                OnTriggeredResult.StartActivity(
-                    intent = INTENT_1,
-                    canShowWhileLocked = true,
-                )
+                OnTriggeredResult.StartActivity(intent = INTENT_1, canShowWhileLocked = true)
             )
     }
 
     @Test
-    fun getPickerScreenState_enabledIfConfiguredOnDevice_isEnabledForPickerState() = runTest {
-        whenever(controller.isAllowedOnLockScreen).thenReturn(true)
-        whenever(controller.isAbleToLaunchScannerActivity).thenReturn(true)
+    fun getPickerScreenState_enabledIfConfiguredOnDevice_isEnabledForPickerState() =
+        runTest(UnconfinedTestDispatcher()) {
+            whenever(controller.isAllowedOnLockScreen).thenReturn(true)
+            whenever(controller.isAbleToLaunchScannerActivity).thenReturn(true)
 
-        assertThat(underTest.getPickerScreenState())
-            .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
-    }
+            assertThat(underTest.getPickerScreenState())
+                .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
+        }
 
     @Test
-    fun getPickerScreenState_disabledIfConfiguredOnDevice_isDisabledForPickerState() = runTest {
-        whenever(controller.isAllowedOnLockScreen).thenReturn(true)
-        whenever(controller.isAbleToLaunchScannerActivity).thenReturn(false)
+    fun getPickerScreenState_disabledIfConfiguredOnDevice_isDisabledForPickerState() =
+        runTest(UnconfinedTestDispatcher()) {
+            whenever(controller.isAllowedOnLockScreen).thenReturn(true)
+            whenever(controller.isAbleToLaunchScannerActivity).thenReturn(false)
 
-        assertThat(underTest.getPickerScreenState())
-            .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
-    }
+            assertThat(underTest.getPickerScreenState())
+                .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
+        }
 
     private fun assertVisibleState(latest: KeyguardQuickAffordanceConfig.LockScreenState?) {
         assertThat(latest)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt
index bd26e42..bef995f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt
@@ -18,6 +18,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.internal.widget.lockPatternUtils
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
@@ -33,6 +34,8 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.whenever
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -52,14 +55,21 @@
         testScope.runTest {
             val values by collectValues(underTest.lockWhileAwakeEvents)
 
-            underTest.onKeyguardServiceDoKeyguardTimeout(options = null)
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true)
+            runCurrent()
+
+            kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(
+                options = null
+            )
             runCurrent()
 
             assertThat(values)
                 .containsExactly(LockWhileAwakeReason.KEYGUARD_TIMEOUT_WHILE_SCREEN_ON)
 
             advanceTimeBy(1000)
-            underTest.onKeyguardServiceDoKeyguardTimeout(options = null)
+            kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(
+                options = null
+            )
             runCurrent()
 
             assertThat(values)
@@ -69,8 +79,15 @@
                 )
         }
 
+    /**
+     * We re-show keyguard when it's re-enabled, but only if it was originally showing when we
+     * disabled it.
+     *
+     * If it wasn't showing when originally disabled it, re-enabling it should do nothing (the
+     * keyguard will re-show next time we're locked).
+     */
     @Test
-    fun emitsWhenKeyguardEnabled_onlyIfShowingWhenDisabled() =
+    fun emitsWhenKeyguardReenabled_onlyIfShowingWhenDisabled() =
         testScope.runTest {
             val values by collectValues(underTest.lockWhileAwakeEvents)
 
@@ -98,4 +115,49 @@
 
             assertThat(values).containsExactly(LockWhileAwakeReason.KEYGUARD_REENABLED)
         }
+
+    /**
+     * Un-suppressing keyguard should never cause us to re-show. We'll re-show when we're next
+     * locked, even if we were showing when originally suppressed.
+     */
+    @Test
+    fun doesNotEmit_keyguardNoLongerSuppressed() =
+        testScope.runTest {
+            val values by collectValues(underTest.lockWhileAwakeEvents)
+
+            // Enable keyguard and then suppress it.
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true)
+            whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true)
+            runCurrent()
+
+            assertEquals(0, values.size)
+
+            // Un-suppress keyguard.
+            whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false)
+            runCurrent()
+
+            assertEquals(0, values.size)
+        }
+
+    /**
+     * Lockdown and lockNow() should not cause us to lock while awake if we are suppressed via adb.
+     */
+    @Test
+    fun doesNotEmit_fromLockdown_orFromLockNow_ifEnabledButSuppressed() =
+        testScope.runTest {
+            val values by collectValues(underTest.lockWhileAwakeEvents)
+
+            // Set keyguard enabled, but then disable lockscreen (suppress it).
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true)
+            whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true)
+            runCurrent()
+
+            kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(null)
+            runCurrent()
+
+            kosmos.biometricSettingsRepository.setIsUserInLockdown(true)
+            runCurrent()
+
+            assertEquals(0, values.size)
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
index 7e249e8..ead151e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
@@ -87,9 +87,9 @@
 
             assertEquals(
                 listOf(
-                    false, // Defaults to false.
+                    false // Defaults to false.
                 ),
-                canWake
+                canWake,
             )
 
             repository.setKeyguardEnabled(false)
@@ -100,33 +100,26 @@
                     false, // Default to false.
                     true, // True now that keyguard service is disabled
                 ),
-                canWake
+                canWake,
             )
 
             repository.setKeyguardEnabled(true)
             runCurrent()
 
-            assertEquals(
-                listOf(
-                    false,
-                    true,
-                    false,
-                ),
-                canWake
-            )
+            assertEquals(listOf(false, true, false), canWake)
         }
 
     @Test
     @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
-    fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled() =
+    fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled_onlyAfterWakefulnessChange() =
         testScope.runTest {
             val canWake by collectValues(underTest.canWakeDirectlyToGone)
 
             assertEquals(
                 listOf(
-                    false, // Defaults to false.
+                    false // Defaults to false.
                 ),
-                canWake
+                canWake,
             )
 
             whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true)
@@ -136,9 +129,9 @@
                 listOf(
                     // Still false - isLockScreenDisabled only causes canWakeDirectlyToGone to
                     // update on the next wake/sleep event.
-                    false,
+                    false
                 ),
-                canWake
+                canWake,
             )
 
             kosmos.powerInteractor.setAsleepForTest()
@@ -150,7 +143,7 @@
                     // True since we slept after setting isLockScreenDisabled=true
                     true,
                 ),
-                canWake
+                canWake,
             )
 
             kosmos.powerInteractor.setAwakeForTest()
@@ -159,25 +152,75 @@
             kosmos.powerInteractor.setAsleepForTest()
             runCurrent()
 
-            assertEquals(
-                listOf(
-                    false,
-                    true,
-                ),
-                canWake
-            )
+            assertEquals(listOf(false, true), canWake)
 
             whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false)
             kosmos.powerInteractor.setAwakeForTest()
             runCurrent()
 
+            assertEquals(listOf(false, true, false), canWake)
+        }
+
+    @Test
+    @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+    fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled_lockNowEvent() =
+        testScope.runTest {
+            val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+            assertEquals(
+                listOf(
+                    false // Defaults to false.
+                ),
+                canWake,
+            )
+
+            whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true)
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    // Still false - isLockScreenDisabled only causes canWakeDirectlyToGone to
+                    // update on the next wakefulness or lockNow event.
+                    false
+                ),
+                canWake,
+            )
+
+            kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(null)
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    // True when lockNow() called after setting isLockScreenDisabled=true
+                    true,
+                ),
+                canWake,
+            )
+
+            whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false)
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    // Still true since no lockNow() calls made.
+                    true,
+                ),
+                canWake,
+            )
+
+            kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(null)
+            runCurrent()
+
             assertEquals(
                 listOf(
                     false,
                     true,
+                    // False again after the lockNow() call.
                     false,
                 ),
-                canWake
+                canWake,
             )
         }
 
@@ -189,9 +232,9 @@
 
             assertEquals(
                 listOf(
-                    false, // Defaults to false.
+                    false // Defaults to false.
                 ),
-                canWake
+                canWake,
             )
 
             repository.setBiometricUnlockState(BiometricUnlockMode.WAKE_AND_UNLOCK)
@@ -213,9 +256,9 @@
 
             assertEquals(
                 listOf(
-                    false, // Defaults to false.
+                    false // Defaults to false.
                 ),
-                canWake
+                canWake,
             )
 
             repository.setCanIgnoreAuthAndReturnToGone(true)
@@ -237,9 +280,9 @@
 
             assertEquals(
                 listOf(
-                    false, // Defaults to false.
+                    false // Defaults to false.
                 ),
-                canWake
+                canWake,
             )
 
             whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt()))
@@ -257,13 +300,7 @@
             )
             runCurrent()
 
-            assertEquals(
-                listOf(
-                    false,
-                    true,
-                ),
-                canWake
-            )
+            assertEquals(listOf(false, true), canWake)
 
             verify(kosmos.alarmManager)
                 .setExactAndAllowWhileIdle(
@@ -281,9 +318,9 @@
 
             assertEquals(
                 listOf(
-                    false, // Defaults to false.
+                    false // Defaults to false.
                 ),
-                canWake
+                canWake,
             )
 
             whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt()))
@@ -312,7 +349,7 @@
                     // Timed out, so we can ignore auth/return to GONE.
                     true,
                 ),
-                canWake
+                canWake,
             )
 
             verify(kosmos.alarmManager)
@@ -338,7 +375,7 @@
                     // alarm in flight that should be canceled.
                     false,
                 ),
-                canWake
+                canWake,
             )
 
             kosmos.powerInteractor.setAsleepForTest(
@@ -354,25 +391,17 @@
                     // Back to sleep.
                     true,
                 ),
-                canWake
+                canWake,
             )
 
             // Simulate the first sleep's alarm coming in.
             lastRegisteredBroadcastReceiver?.onReceive(
                 kosmos.mockedContext,
-                Intent("com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD")
+                Intent("com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"),
             )
             runCurrent()
 
             // It should not have any effect.
-            assertEquals(
-                listOf(
-                    false,
-                    true,
-                    false,
-                    true,
-                ),
-                canWake
-            )
+            assertEquals(listOf(false, true, false, true), canWake)
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
index 2c12f87..2101987 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.authentication.domain.interactor.authenticationInteractor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.EnableSceneContainer
@@ -34,10 +35,12 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.model.asIterable
+import com.android.systemui.scene.data.model.sceneStackOf
 import com.android.systemui.scene.data.repository.Idle
 import com.android.systemui.scene.data.repository.Transition
-import com.android.systemui.scene.data.repository.sceneContainerRepository
 import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.domain.interactor.sceneBackInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
@@ -52,6 +55,7 @@
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -85,7 +89,7 @@
     fun setUp() {
         // lazy value needs to be called here otherwise flow collection misbehaves
         underTest.value
-        kosmos.sceneContainerRepository.setTransitionState(sceneTransitions)
+        kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Lockscreen))
     }
 
     @Test
@@ -883,6 +887,7 @@
 
     @Test
     @EnableSceneContainer
+    @Ignore("b/378766637")
     fun lockscreenVisibilityWithScenes() =
         testScope.runTest {
             val isDeviceUnlocked by
@@ -967,15 +972,56 @@
 
     @Test
     @EnableSceneContainer
+    fun lockscreenVisibilityWithScenes_staysTrue_despiteEnteringIndirectly() =
+        testScope.runTest {
+            val isDeviceUnlocked by
+                collectLastValue(
+                    kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }
+                )
+            assertThat(isDeviceUnlocked).isFalse()
+
+            val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+
+            val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility)
+            assertThat(lockscreenVisibility).isTrue()
+
+            kosmos.setSceneTransition(Idle(Scenes.Shade))
+            kosmos.sceneInteractor.changeScene(Scenes.Shade, "")
+            kosmos.sceneBackInteractor.onSceneChange(from = Scenes.Lockscreen, to = Scenes.Shade)
+            assertThat(currentScene).isEqualTo(Scenes.Shade)
+            assertThat(lockscreenVisibility).isTrue()
+            val sceneBackStack by collectLastValue(kosmos.sceneBackInteractor.backStack)
+            assertThat(sceneBackStack?.asIterable()?.toList()).isEqualTo(listOf(Scenes.Lockscreen))
+
+            val isDeviceEntered by collectLastValue(kosmos.deviceEntryInteractor.isDeviceEntered)
+            val isDeviceEnteredDirectly by
+                collectLastValue(kosmos.deviceEntryInteractor.isDeviceEnteredDirectly)
+            runCurrent()
+            assertThat(isDeviceEntered).isFalse()
+            assertThat(isDeviceEnteredDirectly).isFalse()
+
+            kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
+            kosmos.sceneBackInteractor.updateBackStack { sceneStackOf(Scenes.Gone) }
+            assertThat(sceneBackStack?.asIterable()?.toList()).isEqualTo(listOf(Scenes.Gone))
+
+            assertThat(isDeviceEntered).isTrue()
+            assertThat(isDeviceEnteredDirectly).isFalse()
+            assertThat(isDeviceUnlocked).isTrue()
+            assertThat(lockscreenVisibility).isTrue()
+        }
+
+    @Test
+    @EnableSceneContainer
     fun sceneContainer_usingGoingAwayAnimation_duringTransitionToGone() =
         testScope.runTest {
             val usingKeyguardGoingAwayAnimation by
                 collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation)
 
-            sceneTransitions.value = lsToGone
+            kosmos.setSceneTransition(lsToGone)
             assertThat(usingKeyguardGoingAwayAnimation).isTrue()
 
-            sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone)
+            kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone))
             assertThat(usingKeyguardGoingAwayAnimation).isFalse()
         }
 
@@ -986,14 +1032,14 @@
             val usingKeyguardGoingAwayAnimation by
                 collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation)
 
-            sceneTransitions.value = lsToGone
+            kosmos.setSceneTransition(lsToGone)
             surfaceBehindIsAnimatingFlow.emit(true)
             assertThat(usingKeyguardGoingAwayAnimation).isTrue()
 
-            sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone)
+            kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone))
             assertThat(usingKeyguardGoingAwayAnimation).isTrue()
 
-            sceneTransitions.value = goneToLs
+            kosmos.setSceneTransition(goneToLs)
             assertThat(usingKeyguardGoingAwayAnimation).isTrue()
 
             surfaceBehindIsAnimatingFlow.emit(false)
@@ -1003,11 +1049,6 @@
     companion object {
         private val progress = MutableStateFlow(0f)
 
-        private val sceneTransitions =
-            MutableStateFlow<ObservableTransitionState>(
-                ObservableTransitionState.Idle(Scenes.Lockscreen)
-            )
-
         private val lsToGone =
             ObservableTransitionState.Transition(
                 Scenes.Lockscreen,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
index 5c4b743..62cc763 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
@@ -32,12 +32,11 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.communal.domain.interactor.communalInteractor
 import com.android.systemui.communal.domain.interactor.setCommunalAvailable
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.lifecycle.activateIn
 import com.android.systemui.power.data.repository.fakePowerRepository
@@ -48,7 +47,6 @@
 import com.android.systemui.scene.shared.model.TransitionKeys
 import com.android.systemui.scene.ui.viewmodel.SceneContainerEdge
 import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.math.pow
@@ -69,12 +67,13 @@
 class LockscreenUserActionsViewModelTest : SysuiTestCase() {
 
     companion object {
-        private const val parameterCount = 6
+        private const val parameterCount = 7
 
         @Parameters(
             name =
                 "canSwipeToEnter={0}, downWithTwoPointers={1}, downFromEdge={2}," +
-                    " isSingleShade={3}, isCommunalAvailable={4}, isShadeTouchable={5}"
+                    " isSingleShade={3}, isCommunalAvailable={4}, isShadeTouchable={5}," +
+                    " isOccluded={6}"
         )
         @JvmStatic
         fun combinations() = buildList {
@@ -87,6 +86,7 @@
                             /* isSingleShade= */ combination and 8 != 0,
                             /* isCommunalAvailable= */ combination and 16 != 0,
                             /* isShadeTouchable= */ combination and 32 != 0,
+                            /* isOccluded= */ combination and 64 != 0,
                         )
                         .also { check(it.size == parameterCount) }
                 )
@@ -116,10 +116,12 @@
             downFromEdge: Boolean,
             isNarrowScreen: Boolean,
             isShadeTouchable: Boolean,
+            isOccluded: Boolean,
         ): SceneKey? {
             return when {
                 !isShadeTouchable -> null
-                downFromEdge && isNarrowScreen -> Scenes.QuickSettings
+                downFromEdge && isNarrowScreen && !isOccluded -> Scenes.QuickSettings
+                downFromEdge && isNarrowScreen && isOccluded -> null
                 else -> Scenes.Shade
             }
         }
@@ -168,8 +170,9 @@
     @JvmField @Parameter(3) var isNarrowScreen: Boolean = true
     @JvmField @Parameter(4) var isCommunalAvailable: Boolean = false
     @JvmField @Parameter(5) var isShadeTouchable: Boolean = false
+    @JvmField @Parameter(6) var isOccluded: Boolean = false
 
-    private val underTest by lazy { createLockscreenSceneViewModel() }
+    private val underTest by lazy { kosmos.lockscreenUserActionsViewModel }
 
     @Test
     @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
@@ -196,6 +199,7 @@
                         WakefulnessState.ASLEEP
                     }
             )
+            kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = isOccluded)
 
             val userActions by collectLastValue(underTest.actions)
             val downDestination =
@@ -217,6 +221,7 @@
                         downFromEdge = downFromEdge,
                         isNarrowScreen = isNarrowScreen,
                         isShadeTouchable = isShadeTouchable,
+                        isOccluded = isOccluded,
                     )
                 )
 
@@ -285,6 +290,7 @@
                         WakefulnessState.ASLEEP
                     }
             )
+            kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = isOccluded)
 
             val userActions by collectLastValue(underTest.actions)
 
@@ -354,12 +360,4 @@
                     )
                 )
         }
-
-    private fun createLockscreenSceneViewModel(): LockscreenUserActionsViewModel {
-        return LockscreenUserActionsViewModel(
-            deviceEntryInteractor = kosmos.deviceEntryInteractor,
-            communalInteractor = kosmos.communalInteractor,
-            shadeInteractor = kosmos.shadeInteractor,
-        )
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
index 02825a5..ff00bfb5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
@@ -18,6 +18,7 @@
 
 import android.hardware.display.displayManager
 import android.media.projection.MediaProjectionInfo
+import android.media.projection.StopReason
 import android.os.Binder
 import android.os.Handler
 import android.os.UserHandle
@@ -339,8 +340,9 @@
     @Test
     fun stopProjecting_invokesManager() =
         testScope.runTest {
-            repo.stopProjecting()
+            repo.stopProjecting(StopReason.STOP_QS_TILE)
 
-            verify(fakeMediaProjectionManager.mediaProjectionManager).stopActiveProjection()
+            verify(fakeMediaProjectionManager.mediaProjectionManager)
+                .stopActiveProjection(StopReason.STOP_QS_TILE)
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
index 646722b..555ba56 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
@@ -90,6 +90,7 @@
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.NavBarHelper;
 import com.android.systemui.navigationbar.NavigationBarController;
@@ -116,8 +117,7 @@
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.data.repository.LightBarControllerStore;
-import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.AutoHideControllerStore;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
@@ -148,6 +148,7 @@
 @SmallTest
 public class NavigationBarTest extends SysuiTestCase {
     private static final int EXTERNAL_DISPLAY_ID = 2;
+    private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
 
     private NavigationBar mNavigationBar;
     private NavigationBar mExternalDisplayNavigationBar;
@@ -209,11 +210,7 @@
     @Mock
     private LightBarController mLightBarController;
     @Mock
-    private LightBarControllerStore mLightBarControllerStore;
-    @Mock
-    private AutoHideController mAutoHideController;
-    @Mock
-    private AutoHideController.Factory mAutoHideControllerFactory;
+    private LightBarController.Factory mLightBarcontrollerFactory;
     @Mock
     private WindowManager mWindowManager;
     @Mock
@@ -248,6 +245,8 @@
     private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake();
     private TaskStackChangeListeners mTaskStackChangeListeners =
             TaskStackChangeListeners.getTestInstance();
+    private final AutoHideControllerStore mAutoHideControllerStore =
+            mKosmos.getAutoHideControllerStore();
 
     @Rule
     public final LeakCheckedTest.SysuiLeakCheck mLeakCheck = new LeakCheckedTest.SysuiLeakCheck();
@@ -258,8 +257,7 @@
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        when(mLightBarControllerStore.forDisplay(anyInt())).thenReturn(mLightBarController);
-        when(mAutoHideControllerFactory.create(any(Context.class))).thenReturn(mAutoHideController);
+        when(mLightBarcontrollerFactory.create(any(Context.class))).thenReturn(mLightBarController);
         when(mNavigationBarView.getHomeButton()).thenReturn(mHomeButton);
         when(mNavigationBarView.getRecentsButton()).thenReturn(mRecentsButton);
         when(mNavigationBarView.getAccessibilityButton()).thenReturn(mAccessibilityButton);
@@ -650,9 +648,9 @@
                 mFakeExecutor,
                 mUiEventLogger,
                 mNavBarHelper,
-                mLightBarControllerStore,
-                mAutoHideController,
-                mAutoHideControllerFactory,
+                mLightBarController,
+                mLightBarcontrollerFactory,
+                mAutoHideControllerStore,
                 Optional.of(mTelecomManager),
                 mInputMethodManager,
                 mDeadZone,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt
index 4acf3ee..645efae 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt
@@ -27,7 +27,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MutableSelectionStateTest : SysuiTestCase() {
-    private val underTest = MutableSelectionState({}, {})
+    private val underTest = MutableSelectionState()
 
     @Test
     fun selectTile_isCorrectlySelected() {
@@ -48,120 +48,6 @@
         assertThat(underTest.selection?.manual).isFalse()
     }
 
-    @Test
-    fun startResize_createsResizingState() {
-        assertThat(underTest.resizingState).isNull()
-
-        // Resizing starts but no tile is selected
-        underTest.onResizingDragStart(TileWidths(0, 0, 1))
-        assertThat(underTest.resizingState).isNull()
-
-        // Resizing starts with a selected tile
-        underTest.select(TEST_SPEC, manual = true)
-        underTest.onResizingDragStart(TileWidths(0, 0, 1))
-
-        assertThat(underTest.resizingState).isNotNull()
-    }
-
-    @Test
-    fun endResize_clearsResizingState() {
-        val spec = TileSpec.create("testSpec")
-
-        // Resizing starts with a selected tile
-        underTest.select(spec, manual = true)
-        underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
-        assertThat(underTest.resizingState).isNotNull()
-
-        underTest.onResizingDragEnd()
-        assertThat(underTest.resizingState).isNull()
-    }
-
-    @Test
-    fun unselect_clearsResizingState() {
-        // Resizing starts with a selected tile
-        underTest.select(TEST_SPEC, manual = true)
-        underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
-        assertThat(underTest.resizingState).isNotNull()
-
-        underTest.unSelect()
-        assertThat(underTest.resizingState).isNull()
-    }
-
-    @Test
-    fun onResizingDrag_updatesResizingState() {
-        // Resizing starts with a selected tile
-        underTest.select(TEST_SPEC, manual = true)
-        underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
-        assertThat(underTest.resizingState).isNotNull()
-
-        underTest.onResizingDrag(5f)
-        assertThat(underTest.resizingState?.width).isEqualTo(5)
-
-        underTest.onResizingDrag(2f)
-        assertThat(underTest.resizingState?.width).isEqualTo(7)
-
-        underTest.onResizingDrag(-6f)
-        assertThat(underTest.resizingState?.width).isEqualTo(1)
-    }
-
-    @Test
-    fun onResizingDrag_receivesResizeCallback() {
-        var resized = false
-        val onResize: (TileSpec) -> Unit = {
-            assertThat(it).isEqualTo(TEST_SPEC)
-            resized = !resized
-        }
-        val underTest = MutableSelectionState(onResize = onResize, {})
-
-        // Resizing starts with a selected tile
-        underTest.select(TEST_SPEC, true)
-        underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
-        assertThat(underTest.resizingState).isNotNull()
-
-        // Drag under the threshold
-        underTest.onResizingDrag(1f)
-        assertThat(resized).isFalse()
-
-        // Drag over the threshold
-        underTest.onResizingDrag(5f)
-        assertThat(resized).isTrue()
-
-        // Drag back under the threshold
-        underTest.onResizingDrag(-5f)
-        assertThat(resized).isFalse()
-    }
-
-    @Test
-    fun onResizingEnded_receivesResizeEndCallback() {
-        var resizeEnded = false
-        val onResizeEnd: (TileSpec) -> Unit = { resizeEnded = true }
-        val underTest = MutableSelectionState({}, onResizeEnd = onResizeEnd)
-
-        // Resizing starts with a selected tile
-        underTest.select(TEST_SPEC, true)
-        underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
-
-        underTest.onResizingDragEnd()
-        assertThat(resizeEnded).isTrue()
-    }
-
-    @Test
-    fun onResizingEnded_setsSelectionAutomatically() {
-        val underTest = MutableSelectionState({}, {})
-
-        // Resizing starts with a selected tile
-        underTest.select(TEST_SPEC, manual = true)
-        underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
-
-        // Assert the selection was manual
-        assertThat(underTest.selection?.manual).isTrue()
-
-        underTest.onResizingDragEnd()
-
-        // Assert the selection is no longer manual due to the resizing
-        assertThat(underTest.selection?.manual).isFalse()
-    }
-
     companion object {
         private val TEST_SPEC = TileSpec.create("testSpec")
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingStateTest.kt
index 6e66783..2206f4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingStateTest.kt
@@ -19,7 +19,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -27,36 +29,32 @@
 @RunWith(AndroidJUnit4::class)
 class ResizingStateTest : SysuiTestCase() {
 
+    private val underTest =
+        ResizingState(TileSpec.create("a"), startsAsIcon = true).apply { updateAnchors(10f, 20f) }
+
     @Test
-    fun drag_updatesStateCorrectly() {
-        var resized = false
-        val underTest =
-            ResizingState(TileWidths(base = 0, min = 0, max = 10)) { resized = !resized }
-
-        assertThat(underTest.width).isEqualTo(0)
-
-        underTest.onDrag(2f)
-        assertThat(underTest.width).isEqualTo(2)
-
-        underTest.onDrag(1f)
-        assertThat(underTest.width).isEqualTo(3)
-        assertThat(resized).isTrue()
-
-        underTest.onDrag(-1f)
-        assertThat(underTest.width).isEqualTo(2)
-        assertThat(resized).isFalse()
+    fun newResizingState_setInitialValueCorrectly() {
+        assertThat(underTest.anchoredDraggableState.currentValue).isEqualTo(QSDragAnchor.Icon)
     }
 
     @Test
-    fun dragOutOfBounds_isClampedCorrectly() {
-        val underTest = ResizingState(TileWidths(base = 0, min = 0, max = 10)) {}
+    fun updateAnchors_setBoundsCorrectly() {
+        assertThat(underTest.bounds).isEqualTo(10f to 20f)
+    }
 
-        assertThat(underTest.width).isEqualTo(0)
+    @Test
+    fun dragOverThreshold_resizesToLarge() = runTest {
+        underTest.anchoredDraggableState.anchoredDrag { dragTo(16f) }
 
-        underTest.onDrag(100f)
-        assertThat(underTest.width).isEqualTo(10)
+        assertThat(underTest.temporaryResizeOperation.spec).isEqualTo(TileSpec.create("a"))
+        assertThat(underTest.temporaryResizeOperation.toIcon).isFalse()
+    }
 
-        underTest.onDrag(-200f)
-        assertThat(underTest.width).isEqualTo(0)
+    @Test
+    fun dragUnderThreshold_staysIcon() = runTest {
+        underTest.anchoredDraggableState.anchoredDrag { dragTo(12f) }
+
+        assertThat(underTest.temporaryResizeOperation.spec).isEqualTo(TileSpec.create("a"))
+        assertThat(underTest.temporaryResizeOperation.toIcon).isTrue()
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
new file mode 100644
index 0000000..98770c7
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.viewmodel
+
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.FakeQSTile
+import com.android.systemui.qs.pipeline.data.repository.tileSpecRepository
+import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class DetailsViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private lateinit var underTest: DetailsViewModel
+    private val spec = TileSpec.create("internet")
+    private val specNoDetails = TileSpec.create("NoDetailsTile")
+
+    @Before
+    fun setUp() {
+        underTest = kosmos.detailsViewModel
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun changeTileDetailsViewModel() = with(kosmos) {
+        testScope.runTest {
+            val specs = listOf(
+                spec,
+                specNoDetails,
+            )
+            tileSpecRepository.setTiles(0, specs)
+            runCurrent()
+
+            val tiles = currentTilesInteractor.currentTiles.value
+
+            assertThat(currentTilesInteractor.currentTilesSpecs.size).isEqualTo(2)
+            assertThat(tiles!![1].spec).isEqualTo(specNoDetails)
+            (tiles!![1].tile as FakeQSTile).hasDetailsViewModel = false
+
+            assertThat(underTest.activeTileDetails).isNull()
+
+            // Click on the tile who has the `spec`.
+            assertThat(underTest.onTileClicked(spec)).isTrue()
+            assertThat(underTest.activeTileDetails).isNotNull()
+            assertThat(underTest.activeTileDetails?.getTitle()).isEqualTo("internet")
+
+            // Click on a tile who dose not have a valid spec.
+            assertThat(underTest.onTileClicked(null)).isFalse()
+            assertThat(underTest.activeTileDetails).isNull()
+
+            // Click again on the tile who has the `spec`.
+            assertThat(underTest.onTileClicked(spec)).isTrue()
+            assertThat(underTest.activeTileDetails).isNotNull()
+            assertThat(underTest.activeTileDetails?.getTitle()).isEqualTo("internet")
+
+            // Click on a tile who dose not have a detailed view.
+            assertThat(underTest.onTileClicked(specNoDetails)).isFalse()
+            assertThat(underTest.activeTileDetails).isNull()
+
+            underTest.closeDetailedView()
+            assertThat(underTest.activeTileDetails).isNull()
+
+            assertThat(underTest.onTileClicked(null)).isFalse()
+        }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt
new file mode 100644
index 0000000..f2bfd72
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt
@@ -0,0 +1,63 @@
+/*
+ * 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 androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.fakeFalsingManager
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class EditModeButtonViewModelTest : SysuiTestCase() {
+    val kosmos = testKosmos()
+
+    val underTest = kosmos.editModeButtonViewModelFactory.create()
+
+    @Test
+    fun falsingFalseTap_editModeDoesntStart() =
+        kosmos.runTest {
+            val isEditing by collectLastValue(editModeViewModel.isEditing)
+
+            fakeFalsingManager.setFalseTap(true)
+
+            underTest.onButtonClick()
+            runCurrent()
+
+            assertThat(isEditing).isFalse()
+        }
+
+    @Test
+    fun falsingNotFalseTap_editModeStarted() =
+        kosmos.runTest {
+            val isEditing by collectLastValue(editModeViewModel.isEditing)
+
+            fakeFalsingManager.setFalseTap(false)
+
+            underTest.onButtonClick()
+            runCurrent()
+
+            assertThat(isEditing).isTrue()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
index 8995f46..165ff7b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
@@ -691,6 +691,32 @@
             verify(logger, never()).logTileUserChanged(TileSpec.create("a"), 0)
         }
 
+
+    @Test
+    fun getTileDetails() =
+        testScope.runTest(USER_INFO_0) {
+            val tiles by collectLastValue(underTest.currentTiles)
+            val tileA = TileSpec.create("a")
+            val tileB = TileSpec.create("b")
+            val tileNoDetails = TileSpec.create("NoDetails")
+
+            val specs = listOf(tileA, tileB, tileNoDetails)
+
+            assertThat(tiles!!.isEmpty()).isTrue()
+
+            tileSpecRepository.setTiles(USER_INFO_0.id, specs)
+            assertThat(tiles!!.size).isEqualTo(3)
+
+            // The third tile doesn't have a details view.
+            assertThat(tiles!![2].spec).isEqualTo(tileNoDetails)
+            (tiles!![2].tile as FakeQSTile).hasDetailsViewModel = false
+
+            assertThat(tiles!![0].tile.detailsViewModel.getTitle()).isEqualTo("a")
+            assertThat(tiles!![1].tile.detailsViewModel.getTitle()).isEqualTo("b")
+            assertThat(tiles!![2].tile.detailsViewModel).isNull()
+        }
+
+
     private fun QSTile.State.fillIn(state: Int, label: CharSequence, secondaryLabel: CharSequence) {
         this.state = state
         this.label = label
@@ -770,7 +796,7 @@
         private val USER_INFO_0 = UserInfo().apply { id = 0 }
         private val USER_INFO_1 = UserInfo().apply { id = 1 }
 
-        private val VALID_TILES = setOf("a", "b", "c", "d", "e")
+        private val VALID_TILES = setOf("a", "b", "c", "d", "e", "NoDetails")
         private val TEST_COMPONENT = ComponentName("pkg", "cls")
         private val CUSTOM_TILE_SPEC = TileSpec.Companion.create(TEST_COMPONENT)
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorTest.kt
new file mode 100644
index 0000000..08225a77
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorTest.kt
@@ -0,0 +1,145 @@
+/*
+ * 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.scene.domain.interactor
+
+import android.app.StatusBarManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.Swipe
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.scene.shared.model.Overlays
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.launch
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DisabledContentInteractorTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+
+    private val underTest = kosmos.disabledContentInteractor
+
+    @Test
+    fun isDisabled_notificationsShade() =
+        kosmos.runTest {
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NONE)
+            assertThat(underTest.isDisabled(Overlays.NotificationsShade)).isFalse()
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+            assertThat(underTest.isDisabled(Overlays.NotificationsShade)).isTrue()
+        }
+
+    @Test
+    fun isDisabled_qsShade() =
+        kosmos.runTest {
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NONE)
+            assertThat(underTest.isDisabled(Overlays.QuickSettingsShade)).isFalse()
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+            assertThat(underTest.isDisabled(Overlays.QuickSettingsShade)).isTrue()
+        }
+
+    @Test
+    fun repeatWhenDisabled() =
+        kosmos.runTest {
+            var notificationDisabledCount = 0
+            applicationCoroutineScope.launch {
+                underTest.repeatWhenDisabled(Overlays.NotificationsShade) {
+                    notificationDisabledCount++
+                }
+            }
+            var qsDisabledCount = 0
+            applicationCoroutineScope.launch {
+                underTest.repeatWhenDisabled(Overlays.QuickSettingsShade) { qsDisabledCount++ }
+            }
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+            assertThat(notificationDisabledCount).isEqualTo(0)
+            assertThat(qsDisabledCount).isEqualTo(1)
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(
+                    disable2 =
+                        StatusBarManager.DISABLE2_NOTIFICATION_SHADE or
+                            StatusBarManager.DISABLE2_QUICK_SETTINGS
+                )
+            assertThat(notificationDisabledCount).isEqualTo(1)
+            assertThat(qsDisabledCount).isEqualTo(1)
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+            assertThat(notificationDisabledCount).isEqualTo(1)
+            assertThat(qsDisabledCount).isEqualTo(1)
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+            assertThat(notificationDisabledCount).isEqualTo(1)
+            assertThat(qsDisabledCount).isEqualTo(2)
+        }
+
+    @Test
+    fun filteredUserActions() =
+        kosmos.runTest {
+            val map =
+                mapOf<UserAction, UserActionResult>(
+                    Swipe.Up to UserActionResult.ShowOverlay(Overlays.NotificationsShade),
+                    Swipe.Down to UserActionResult.ShowOverlay(Overlays.QuickSettingsShade),
+                )
+            val unfiltered = MutableStateFlow(map)
+            val filtered by collectLastValue(underTest.filteredUserActions(unfiltered))
+            assertThat(filtered).isEqualTo(map)
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+            assertThat(filtered)
+                .isEqualTo(
+                    mapOf(Swipe.Down to UserActionResult.ShowOverlay(Overlays.QuickSettingsShade))
+                )
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+            assertThat(filtered)
+                .isEqualTo(
+                    mapOf(Swipe.Up to UserActionResult.ShowOverlay(Overlays.NotificationsShade))
+                )
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(
+                    disable2 =
+                        StatusBarManager.DISABLE2_NOTIFICATION_SHADE or
+                            StatusBarManager.DISABLE2_QUICK_SETTINGS
+                )
+            assertThat(filtered).isEqualTo(emptyMap<UserAction, UserActionResult>())
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index 7fe3d8d..48edded 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -18,6 +18,7 @@
 
 package com.android.systemui.scene.domain.interactor
 
+import android.app.StatusBarManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.compose.animation.scene.ObservableTransitionState
@@ -30,6 +31,8 @@
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.data.repository.Idle
 import com.android.systemui.scene.data.repository.Transition
@@ -43,6 +46,8 @@
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -523,4 +528,51 @@
 
             assertThat(currentScene).isEqualTo(Scenes.Gone)
         }
+
+    @Test
+    fun showOverlay_overlayDisabled_doesNothing() =
+        kosmos.runTest {
+            val currentOverlays by collectLastValue(underTest.currentOverlays)
+            val disabledOverlay = Overlays.QuickSettingsShade
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+            assertThat(disabledContentInteractor.isDisabled(disabledOverlay)).isTrue()
+            assertThat(currentOverlays).doesNotContain(disabledOverlay)
+
+            underTest.showOverlay(disabledOverlay, "reason")
+
+            assertThat(currentOverlays).doesNotContain(disabledOverlay)
+        }
+
+    @Test
+    fun replaceOverlay_withDisabledOverlay_doesNothing() =
+        kosmos.runTest {
+            val currentOverlays by collectLastValue(underTest.currentOverlays)
+            val showingOverlay = Overlays.NotificationsShade
+            underTest.showOverlay(showingOverlay, "reason")
+            assertThat(currentOverlays).isEqualTo(setOf(showingOverlay))
+            val disabledOverlay = Overlays.QuickSettingsShade
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+            assertThat(disabledContentInteractor.isDisabled(disabledOverlay)).isTrue()
+
+            underTest.replaceOverlay(showingOverlay, disabledOverlay, "reason")
+
+            assertThat(currentOverlays).isEqualTo(setOf(showingOverlay))
+        }
+
+    @Test
+    fun changeScene_toDisabledScene_doesNothing() =
+        kosmos.runTest {
+            val currentScene by collectLastValue(underTest.currentScene)
+            val disabledScene = Scenes.Shade
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+            assertThat(disabledContentInteractor.isDisabled(disabledScene)).isTrue()
+            assertThat(currentScene).isNotEqualTo(disabledScene)
+
+            underTest.changeScene(disabledScene, "reason")
+
+            assertThat(currentScene).isNotEqualTo(disabledScene)
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
index db2297c..3d014b6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
@@ -35,9 +35,9 @@
 import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
 import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.init.NotificationsController
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 48deee5..79bb0c4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -56,6 +56,7 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryHapticsInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.deviceentry.shared.model.DeviceUnlockStatus
 import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationStatus
 import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus
 import com.android.systemui.flags.EnableSceneContainer
@@ -80,6 +81,9 @@
 import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.model.sysUiState
 import com.android.systemui.power.data.repository.fakePowerRepository
@@ -100,6 +104,8 @@
 import com.android.systemui.shade.shared.flag.DualShade
 import com.android.systemui.shared.system.QuickStepContract
 import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
 import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
 import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
 import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRepository
@@ -2533,6 +2539,88 @@
         }
 
     @Test
+    fun handleDeviceUnlockStatus_deviceLockedWhileOnDream_stayOnDream() =
+        testScope.runTest {
+            val transitionState =
+                prepareState(
+                    isDeviceUnlocked = false,
+                    initialSceneKey = Scenes.Lockscreen,
+                    authenticationMethod = AuthenticationMethodModel.Pin,
+                )
+            underTest.start()
+
+            val isUnlocked by
+                collectLastValue(
+                    kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }
+                )
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+
+            // Unlock device.
+            kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+
+            // Change to Dream.
+            sceneInteractor.changeScene(Scenes.Dream, "test")
+            transitionState.value = ObservableTransitionState.Idle(Scenes.Dream)
+            runCurrent()
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(Scenes.Dream)
+
+            // Lock device, and verify stay on dream.
+            kosmos.fakeDeviceEntryRepository.deviceUnlockStatus.value =
+                DeviceUnlockStatus(isUnlocked = false, deviceUnlockSource = null)
+            runCurrent()
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(Scenes.Dream)
+        }
+
+    @Test
+    fun handleDeviceUnlockStatus_deviceLockedWhileOnCommunal_stayOnCommunal() =
+        testScope.runTest {
+            val transitionState =
+                prepareState(
+                    isDeviceUnlocked = false,
+                    initialSceneKey = Scenes.Lockscreen,
+                    authenticationMethod = AuthenticationMethodModel.Pin,
+                )
+            underTest.start()
+
+            val isUnlocked by
+                collectLastValue(
+                    kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }
+                )
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+
+            // Unlock device.
+            kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+
+            // Change to Communal.
+            sceneInteractor.changeScene(Scenes.Communal, "test")
+            transitionState.value = ObservableTransitionState.Idle(Scenes.Communal)
+            runCurrent()
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(Scenes.Communal)
+
+            // Lock device, and verify stay on Communal.
+            kosmos.fakeDeviceEntryRepository.deviceUnlockStatus.value =
+                DeviceUnlockStatus(isUnlocked = false, deviceUnlockSource = null)
+            runCurrent()
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(Scenes.Communal)
+        }
+
+    @Test
     fun replacesLockscreenSceneOnBackStack_whenFaceUnlocked_fromShade_noAlternateBouncer() =
         testScope.runTest {
             val transitionState =
@@ -2590,6 +2678,25 @@
             assertThat(isAlternateBouncerVisible).isFalse()
         }
 
+    @Test
+    fun handleDisableFlags() =
+        kosmos.runTest {
+            underTest.start()
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+            sceneInteractor.changeScene(Scenes.Shade, "reason")
+            sceneInteractor.showOverlay(Overlays.NotificationsShade, "reason")
+            assertThat(currentScene).isEqualTo(Scenes.Shade)
+            assertThat(currentOverlays).contains(Overlays.NotificationsShade)
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+            runCurrent()
+
+            assertThat(currentScene).isNotEqualTo(Scenes.Shade)
+            assertThat(currentOverlays).isEmpty()
+        }
+
     private fun TestScope.emulateSceneTransition(
         transitionStateFlow: MutableStateFlow<ObservableTransitionState>,
         toScene: SceneKey,
@@ -2754,9 +2861,7 @@
         )
 
     private fun fakeHeadsUpRowRepository(key: String, isPinned: Boolean) =
-        FakeHeadsUpRowRepository(key = key, elementKey = Any()).apply {
-            this.isPinned.value = isPinned
-        }
+        FakeHeadsUpRowRepository(key = key, elementKey = Any(), isPinned = isPinned)
 
     private fun setFingerprintSensorType(fingerprintSensorType: FingerprintSensorType) {
         kosmos.fingerprintPropertyRepository.setProperties(
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 94a19c8..0d8d57e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -150,7 +150,7 @@
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.ConversationNotificationManager;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinatorLogger;
 import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardViewStateRepository;
@@ -178,12 +178,12 @@
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.phone.ShadeTouchableRegionManager;
 import com.android.systemui.statusbar.phone.TapAgainViewController;
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
@@ -245,7 +245,7 @@
     @Mock protected NotificationPanelView mView;
     @Mock protected LayoutInflater mLayoutInflater;
     @Mock protected DynamicPrivacyController mDynamicPrivacyController;
-    @Mock protected StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    @Mock protected ShadeTouchableRegionManager mShadeTouchableRegionManager;
     @Mock protected KeyguardStateController mKeyguardStateController;
     @Mock protected DozeLog mDozeLog;
     private final ShadeLogger mShadeLog = new ShadeLogger(logcatLogBuffer());
@@ -349,6 +349,7 @@
     @Mock private KeyguardClockPositionAlgorithm mKeyguardClockPositionAlgorithm;
     @Mock private NaturalScrollingSettingObserver mNaturalScrollingSettingObserver;
     @Mock private LargeScreenHeaderHelper mLargeScreenHeaderHelper;
+    @Mock private StatusBarLongPressGestureDetector mStatusBarLongPressGestureDetector;
     protected final int mMaxUdfpsBurnInOffsetY = 5;
     protected FakeFeatureFlagsClassic mFeatureFlags = new FakeFeatureFlagsClassic();
     protected KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
@@ -702,7 +703,7 @@
                 mMetricsLogger,
                 mShadeLog,
                 mConfigurationController,
-                () -> flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager,
+                () -> flingAnimationUtilsBuilder, mShadeTouchableRegionManager,
                 mConversationNotificationManager, mMediaHierarchyManager,
                 mStatusBarKeyguardViewManager,
                 mGutsManager,
@@ -818,7 +819,8 @@
                 mLockscreenShadeTransitionController,
                 mNotificationShadeDepthController,
                 mShadeHeaderController,
-                mStatusBarTouchableRegionManager,
+                mShadeTouchableRegionManager,
+                () -> mStatusBarLongPressGestureDetector,
                 mKeyguardStateController,
                 mKeyguardBypassController,
                 mScrimController,
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 ef132d5..b58c13c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
@@ -71,8 +71,8 @@
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.ShadeTouchableRegionManager;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
@@ -125,7 +125,8 @@
     @Mock protected LockscreenShadeTransitionController mLockscreenShadeTransitionController;
     @Mock protected NotificationShadeDepthController mNotificationShadeDepthController;
     @Mock protected ShadeHeaderController mShadeHeaderController;
-    @Mock protected StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    @Mock protected ShadeTouchableRegionManager mShadeTouchableRegionManager;
+    @Mock protected StatusBarLongPressGestureDetector mStatusBarLongPressGestureDetector;
     @Mock protected DozeParameters mDozeParameters;
     @Mock protected KeyguardStateController mKeyguardStateController;
     @Mock protected KeyguardBypassController mKeyguardBypassController;
@@ -249,7 +250,8 @@
                 mLockscreenShadeTransitionController,
                 mNotificationShadeDepthController,
                 mShadeHeaderController,
-                mStatusBarTouchableRegionManager,
+                mShadeTouchableRegionManager,
+                () -> mStatusBarLongPressGestureDetector,
                 mKeyguardStateController,
                 mKeyguardBypassController,
                 mScrimController,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
index 0f476d0..c6ce581 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
@@ -36,10 +36,10 @@
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.NotificationShadeWindowController
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt
new file mode 100644
index 0000000..0966759
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt
@@ -0,0 +1,89 @@
+/*
+ * 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.data.repository
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shade.display.ShadeDisplayPolicy
+import com.android.systemui.shade.display.SpecificDisplayIdPolicy
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ShadeDisplaysRepositoryTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val defaultPolicy = SpecificDisplayIdPolicy(0)
+
+    private val shadeDisplaysRepository =
+        ShadeDisplaysRepositoryImpl(defaultPolicy, testScope.backgroundScope)
+
+    @Test
+    fun policy_changing_propagatedFromTheLatestPolicy() =
+        testScope.runTest {
+            val displayIds by collectValues(shadeDisplaysRepository.displayId)
+            val policy1 = MutablePolicy()
+            val policy2 = MutablePolicy()
+
+            assertThat(displayIds).containsExactly(0)
+
+            shadeDisplaysRepository.policy.value = policy1
+
+            policy1.sendDisplayId(1)
+
+            assertThat(displayIds).containsExactly(0, 1)
+
+            policy1.sendDisplayId(2)
+
+            assertThat(displayIds).containsExactly(0, 1, 2)
+
+            shadeDisplaysRepository.policy.value = policy2
+
+            assertThat(displayIds).containsExactly(0, 1, 2, 0)
+
+            policy1.sendDisplayId(4)
+
+            // Changes to the first policy don't affect the output now
+            assertThat(displayIds).containsExactly(0, 1, 2, 0)
+
+            policy2.sendDisplayId(5)
+
+            assertThat(displayIds).containsExactly(0, 1, 2, 0, 5)
+        }
+
+    private class MutablePolicy : ShadeDisplayPolicy {
+        fun sendDisplayId(id: Int) {
+            _displayId.value = id
+        }
+
+        private val _displayId = MutableStateFlow(0)
+        override val name: String
+            get() = "mutable_policy"
+
+        override val displayId: StateFlow<Int>
+            get() = _displayId
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt
index af01547..d584dc9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt
@@ -23,12 +23,17 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.display.data.repository.displayRepository
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.shade.ShadePrimaryDisplayCommand
+import com.android.systemui.shade.display.ShadeDisplayPolicy
 import com.android.systemui.statusbar.commandline.commandRegistry
 import com.android.systemui.testKosmos
+import com.google.common.truth.StringSubject
 import com.google.common.truth.Truth.assertThat
 import java.io.PrintWriter
 import java.io.StringWriter
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -37,15 +42,26 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ShadePrimaryDisplayCommandTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
     private val testScope = kosmos.testScope
     private val commandRegistry = kosmos.commandRegistry
     private val displayRepository = kosmos.displayRepository
-    private val shadeDisplaysRepository = ShadeDisplaysRepositoryImpl()
+    private val defaultPolicy = kosmos.defaultShadeDisplayPolicy
+    private val policy1 = makePolicy("policy_1")
+    private val shadeDisplaysRepository = kosmos.shadeDisplaysRepository
     private val pw = PrintWriter(StringWriter())
 
+    private val policies =
+        setOf(defaultPolicy, policy1, makePolicy("policy_2"), makePolicy("policy_3"))
+
     private val underTest =
-        ShadePrimaryDisplayCommand(commandRegistry, displayRepository, shadeDisplaysRepository)
+        ShadePrimaryDisplayCommand(
+            commandRegistry,
+            displayRepository,
+            shadeDisplaysRepository,
+            policies,
+            defaultPolicy,
+        )
 
     @Before
     fun setUp() {
@@ -96,4 +112,41 @@
 
             assertThat(displayId).isEqualTo(newDisplayId)
         }
+
+    @Test
+    fun policies_listsAllPolicies() =
+        testScope.runTest {
+            val stringWriter = StringWriter()
+            commandRegistry.onShellCommand(
+                PrintWriter(stringWriter),
+                arrayOf("shade_display_override", "policies"),
+            )
+            val result = stringWriter.toString()
+
+            assertThat(result).containsAllIn(policies.map { it.name })
+        }
+
+    @Test
+    fun policies_setsSpecificPolicy() =
+        testScope.runTest {
+            val policy by collectLastValue(shadeDisplaysRepository.policy)
+
+            commandRegistry.onShellCommand(pw, arrayOf("shade_display_override", policy1.name))
+
+            assertThat(policy!!.name).isEqualTo(policy1.name)
+        }
+
+    private fun makePolicy(policyName: String): ShadeDisplayPolicy {
+        return object : ShadeDisplayPolicy {
+            override val name: String
+                get() = policyName
+
+            override val displayId: StateFlow<Int>
+                get() = MutableStateFlow(0)
+        }
+    }
+}
+
+private fun StringSubject.containsAllIn(strings: List<String>) {
+    strings.forEach { contains(it) }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/AnyExternalShadeDisplayPolicyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/AnyExternalShadeDisplayPolicyTest.kt
new file mode 100644
index 0000000..4d4efd1
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/AnyExternalShadeDisplayPolicyTest.kt
@@ -0,0 +1,84 @@
+/*
+ * 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.display
+
+import android.view.Display
+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.display.data.repository.display
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.test.runTest
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AnyExternalShadeDisplayPolicyTest : SysuiTestCase() {
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+    private val testScope = kosmos.testScope
+    private val displayRepository = kosmos.displayRepository
+    val underTest = AnyExternalShadeDisplayPolicy(displayRepository, testScope.backgroundScope)
+
+    @Test
+    fun displayId_ignoresUnwantedTypes() =
+        testScope.runTest {
+            val displayId by collectLastValue(underTest.displayId)
+
+            displayRepository.addDisplays(
+                display(id = 0, type = Display.TYPE_INTERNAL),
+                display(id = 1, type = Display.TYPE_UNKNOWN),
+                display(id = 2, type = Display.TYPE_VIRTUAL),
+                display(id = 3, type = Display.TYPE_EXTERNAL),
+            )
+
+            assertThat(displayId).isEqualTo(3)
+        }
+
+    @Test
+    fun displayId_onceRemoved_goesToNextDisplay() =
+        testScope.runTest {
+            val displayId by collectLastValue(underTest.displayId)
+
+            displayRepository.addDisplays(
+                display(id = 0, type = Display.TYPE_INTERNAL),
+                display(id = 2, type = Display.TYPE_EXTERNAL),
+                display(id = 3, type = Display.TYPE_EXTERNAL),
+            )
+
+            assertThat(displayId).isEqualTo(2)
+
+            displayRepository.removeDisplay(2)
+
+            assertThat(displayId).isEqualTo(3)
+        }
+
+    @Test
+    fun displayId_onlyDefaultDisplay_defaultDisplay() =
+        testScope.runTest {
+            val displayId by collectLastValue(underTest.displayId)
+
+            displayRepository.addDisplays(display(id = 0, type = Display.TYPE_INTERNAL))
+
+            assertThat(displayId).isEqualTo(0)
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
index 8ef1e56..982c51b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
@@ -29,7 +29,7 @@
 import com.android.systemui.display.shared.model.DisplayWindowProperties
 import com.android.systemui.scene.ui.view.WindowRootView
 import com.android.systemui.shade.data.repository.FakeShadeDisplayRepository
-import com.android.systemui.statusbar.phone.ConfigurationForwarder
+import java.util.Optional
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -37,6 +37,7 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.verify
 import org.mockito.kotlin.any
 import org.mockito.kotlin.eq
@@ -51,26 +52,22 @@
 
     private val shadeRootview = mock<WindowRootView>()
     private val positionRepository = FakeShadeDisplayRepository()
-    private val defaultContext = mock<Context>()
-    private val secondaryContext = mock<Context>()
+    private val shadeContext = mock<Context>()
     private val contextStore = FakeDisplayWindowPropertiesRepository()
     private val testScope = TestScope(UnconfinedTestDispatcher())
-    private val configurationForwarder = mock<ConfigurationForwarder>()
-    private val defaultWm = mock<WindowManager>()
-    private val secondaryWm = mock<WindowManager>()
+    private val shadeWm = mock<WindowManager>()
     private val resources = mock<Resources>()
     private val configuration = mock<Configuration>()
     private val display = mock<Display>()
 
     private val interactor =
         ShadeDisplaysInteractor(
-            shadeRootview,
+            Optional.of(shadeRootview),
             positionRepository,
-            defaultContext,
-            contextStore,
-            testScope,
-            configurationForwarder,
-            testScope.coroutineContext,
+            shadeContext,
+            shadeWm,
+            testScope.backgroundScope,
+            testScope.backgroundScope.coroutineContext,
         )
 
     @Before
@@ -79,30 +76,16 @@
         whenever(display.displayId).thenReturn(0)
 
         whenever(resources.configuration).thenReturn(configuration)
-        whenever(resources.configuration).thenReturn(configuration)
 
-        whenever(defaultContext.displayId).thenReturn(0)
-        whenever(defaultContext.getSystemService(any())).thenReturn(defaultWm)
-        whenever(defaultContext.resources).thenReturn(resources)
+        whenever(shadeContext.displayId).thenReturn(0)
+        whenever(shadeContext.getSystemService(any())).thenReturn(shadeWm)
+        whenever(shadeContext.resources).thenReturn(resources)
         contextStore.insert(
             DisplayWindowProperties(
                 displayId = 0,
                 windowType = TYPE_NOTIFICATION_SHADE,
-                context = defaultContext,
-                windowManager = defaultWm,
-                layoutInflater = mock(),
-            )
-        )
-
-        whenever(secondaryContext.displayId).thenReturn(1)
-        whenever(secondaryContext.getSystemService(any())).thenReturn(secondaryWm)
-        whenever(secondaryContext.resources).thenReturn(resources)
-        contextStore.insert(
-            DisplayWindowProperties(
-                displayId = 1,
-                windowType = TYPE_NOTIFICATION_SHADE,
-                context = secondaryContext,
-                windowManager = secondaryWm,
+                context = shadeContext,
+                windowManager = shadeWm,
                 layoutInflater = mock(),
             )
         )
@@ -115,8 +98,7 @@
         interactor.start()
         testScope.advanceUntilIdle()
 
-        verifyNoMoreInteractions(defaultWm)
-        verifyNoMoreInteractions(secondaryWm)
+        verifyNoMoreInteractions(shadeWm)
     }
 
     @Test
@@ -124,10 +106,11 @@
         whenever(display.displayId).thenReturn(0)
         positionRepository.setDisplayId(1)
         interactor.start()
-        testScope.advanceUntilIdle()
 
-        verify(defaultWm).removeView(eq(shadeRootview))
-        verify(secondaryWm).addView(eq(shadeRootview), any())
+        inOrder(shadeWm).apply {
+            verify(shadeWm).removeView(eq(shadeRootview))
+            verify(shadeWm).addView(eq(shadeRootview), any())
+        }
     }
 
     @Test
@@ -135,25 +118,12 @@
         whenever(display.displayId).thenReturn(0)
         positionRepository.setDisplayId(0)
         interactor.start()
-        testScope.advanceUntilIdle()
 
         positionRepository.setDisplayId(1)
-        testScope.advanceUntilIdle()
 
-        verify(defaultWm).removeView(eq(shadeRootview))
-        verify(secondaryWm).addView(eq(shadeRootview), any())
-    }
-
-    @Test
-    fun start_shadePositionChanges_newConfigPropagated() {
-        whenever(display.displayId).thenReturn(0)
-        positionRepository.setDisplayId(0)
-        interactor.start()
-        testScope.advanceUntilIdle()
-
-        positionRepository.setDisplayId(1)
-        testScope.advanceUntilIdle()
-
-        verify(configurationForwarder).onConfigurationChanged(eq(configuration))
+        inOrder(shadeWm).apply {
+            verify(shadeWm).removeView(eq(shadeRootview))
+            verify(shadeWm).addView(eq(shadeRootview), any())
+        }
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt
index 558606f..a9d5790 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.shade.ui.viewmodel
 
+import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS
 import android.platform.test.annotations.DisableFlags
 import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -42,6 +43,7 @@
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.shade.shared.flag.DualShade
 import com.android.systemui.shade.shared.model.ShadeMode
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
 import com.android.systemui.testKosmos
 import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
 import com.google.common.truth.Truth.assertThat
@@ -49,6 +51,7 @@
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.update
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -158,10 +161,7 @@
                         underTest.unfoldTranslationX(isOnStartSide = true),
                         underTest.unfoldTranslationX(isOnStartSide = false),
                     ) { start, end ->
-                        Translations(
-                            start = start,
-                            end = end,
-                        )
+                        Translations(start = start, end = end)
                     }
                 )
 
@@ -186,6 +186,20 @@
             assertThat(translations?.end).isEqualTo(-0f)
         }
 
+    @Test
+    fun disable2QuickSettings_isQsEnabledIsFalse() =
+        testScope.runTest {
+            val isQsEnabled by collectLastValue(underTest.isQsEnabled)
+            assertThat(isQsEnabled).isTrue()
+
+            kosmos.fakeDisableFlagsRepository.disableFlags.update {
+                it.copy(disable2 = DISABLE2_QUICK_SETTINGS)
+            }
+            runCurrent()
+
+            assertThat(isQsEnabled).isFalse()
+        }
+
     private fun prepareConfiguration(): Int {
         val configuration = context.resources.configuration
         configuration.setLayoutDirection(Locale.US)
@@ -193,7 +207,7 @@
         val maxTranslation = 10
         kosmos.fakeConfigurationRepository.setDimensionPixelSize(
             R.dimen.notification_side_paddings,
-            maxTranslation
+            maxTranslation,
         )
         return maxTranslation
     }
@@ -224,8 +238,5 @@
         runCurrent()
     }
 
-    private data class Translations(
-        val start: Float,
-        val end: Float,
-    )
+    private data class Translations(val start: Float, val end: Float)
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginActionManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/plugins/PluginActionManagerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginActionManagerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/shared/plugins/PluginActionManagerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index da0029f..32a9f54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -48,7 +48,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyObject;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
@@ -1633,7 +1632,7 @@
         } else {
             verify(mRotateTextViewController).hideIndication(type);
             verify(mRotateTextViewController, never()).updateIndication(eq(type),
-                    anyObject(), anyBoolean());
+                    any(), anyBoolean());
         }
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
index 9907740..cd66ef3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
@@ -26,10 +26,10 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.row.ExpandableView
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.util.mockito.mock
 import kotlinx.coroutines.flow.MutableStateFlow
 import org.junit.Before
@@ -76,7 +76,7 @@
                 falsingManager,
                 shadeInteractor,
                 lockscreenShadeTransitionController,
-                dumpManager
+                dumpManager,
             )
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
new file mode 100644
index 0000000..7fed47a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.chips.notification.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.data.repository.activityManagerRepository
+import com.android.systemui.activity.data.repository.fake
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SingleNotificationChipInteractorTest : SysuiTestCase() {
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+    val factory = kosmos.singleNotificationChipInteractorFactory
+
+    @Test
+    fun notificationChip_startsWithStartingModel() =
+        kosmos.runTest {
+            val icon = mock<StatusBarIconView>()
+            val startingNotif = activeNotificationModel(key = "notif1", statusBarChipIcon = icon)
+
+            val underTest = factory.create(startingNotif)
+
+            val latest by collectLastValue(underTest.notificationChip)
+
+            assertThat(latest!!.key).isEqualTo("notif1")
+            assertThat(latest!!.statusBarChipIconView).isEqualTo(icon)
+        }
+
+    @Test
+    fun notificationChip_updatesAfterSet() =
+        kosmos.runTest {
+            val originalIconView = mock<StatusBarIconView>()
+            val underTest =
+                factory.create(
+                    activeNotificationModel(key = "notif1", statusBarChipIcon = originalIconView)
+                )
+
+            val latest by collectLastValue(underTest.notificationChip)
+
+            val newIconView = mock<StatusBarIconView>()
+            underTest.setNotification(
+                activeNotificationModel(key = "notif1", statusBarChipIcon = newIconView)
+            )
+
+            assertThat(latest!!.key).isEqualTo("notif1")
+            assertThat(latest!!.statusBarChipIconView).isEqualTo(newIconView)
+        }
+
+    @Test
+    fun notificationChip_ignoresSetWithDifferentKey() =
+        kosmos.runTest {
+            val originalIconView = mock<StatusBarIconView>()
+            val underTest =
+                factory.create(
+                    activeNotificationModel(key = "notif1", statusBarChipIcon = originalIconView)
+                )
+
+            val latest by collectLastValue(underTest.notificationChip)
+
+            val newIconView = mock<StatusBarIconView>()
+            underTest.setNotification(
+                activeNotificationModel(key = "other_notif", statusBarChipIcon = newIconView)
+            )
+
+            assertThat(latest!!.key).isEqualTo("notif1")
+            assertThat(latest!!.statusBarChipIconView).isEqualTo(originalIconView)
+        }
+
+    @Test
+    fun notificationChip_missingStatusBarIconChipView_inConstructor_emitsNull() =
+        kosmos.runTest {
+            val underTest =
+                factory.create(activeNotificationModel(key = "notif1", statusBarChipIcon = null))
+
+            val latest by collectLastValue(underTest.notificationChip)
+
+            assertThat(latest).isNull()
+        }
+
+    @Test
+    fun notificationChip_missingStatusBarIconChipView_inSet_emitsNull() =
+        kosmos.runTest {
+            val startingNotif = activeNotificationModel(key = "notif1", statusBarChipIcon = mock())
+            val underTest = factory.create(startingNotif)
+            val latest by collectLastValue(underTest.notificationChip)
+            assertThat(latest).isNotNull()
+
+            underTest.setNotification(
+                activeNotificationModel(key = "notif1", statusBarChipIcon = null)
+            )
+
+            assertThat(latest).isNull()
+        }
+
+    @Test
+    fun notificationChip_appIsVisibleOnCreation_emitsNull() =
+        kosmos.runTest {
+            activityManagerRepository.fake.startingIsAppVisibleValue = true
+
+            val underTest =
+                factory.create(
+                    activeNotificationModel(key = "notif", uid = UID, statusBarChipIcon = mock())
+                )
+
+            val latest by collectLastValue(underTest.notificationChip)
+
+            assertThat(latest).isNull()
+        }
+
+    @Test
+    fun notificationChip_appNotVisibleOnCreation_emitsValue() =
+        kosmos.runTest {
+            activityManagerRepository.fake.startingIsAppVisibleValue = false
+
+            val underTest =
+                factory.create(
+                    activeNotificationModel(key = "notif", uid = UID, statusBarChipIcon = mock())
+                )
+
+            val latest by collectLastValue(underTest.notificationChip)
+
+            assertThat(latest).isNotNull()
+        }
+
+    @Test
+    fun notificationChip_hidesWhenAppIsVisible() =
+        kosmos.runTest {
+            val underTest =
+                factory.create(
+                    activeNotificationModel(key = "notif", uid = UID, statusBarChipIcon = mock())
+                )
+
+            val latest by collectLastValue(underTest.notificationChip)
+
+            activityManagerRepository.fake.setIsAppVisible(UID, false)
+            assertThat(latest).isNotNull()
+
+            activityManagerRepository.fake.setIsAppVisible(UID, true)
+            assertThat(latest).isNull()
+
+            activityManagerRepository.fake.setIsAppVisible(UID, false)
+            assertThat(latest).isNotNull()
+        }
+
+    // Note: This test is theoretically impossible because the notification key should contain the
+    // UID, so if the UID changes then the key would also change and a new interactor would be
+    // created. But, test it just in case.
+    @Test
+    fun notificationChip_updatedUid_rechecksAppVisibility_oldObserverUnregistered() =
+        kosmos.runTest {
+            activityManagerRepository.fake.startingIsAppVisibleValue = false
+
+            val hiddenUid = 100
+            val shownUid = 101
+
+            val underTest =
+                factory.create(
+                    activeNotificationModel(
+                        key = "notif",
+                        uid = hiddenUid,
+                        statusBarChipIcon = mock(),
+                    )
+                )
+            val latest by collectLastValue(underTest.notificationChip)
+            assertThat(latest).isNotNull()
+
+            // WHEN the notif gets a new UID that starts as visible
+            activityManagerRepository.fake.startingIsAppVisibleValue = true
+            underTest.setNotification(
+                activeNotificationModel(key = "notif", uid = shownUid, statusBarChipIcon = mock())
+            )
+
+            // THEN we re-fetch the app visibility state with the new UID, and since that UID is
+            // visible, we hide the chip
+            assertThat(latest).isNull()
+        }
+
+    companion object {
+        private const val UID = 885
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt
index 19ed6a5..702e101 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt
@@ -16,30 +16,277 @@
 
 package com.android.systemui.statusbar.chips.notification.domain.interactor
 
+import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 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.coroutines.collectValues
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
+import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
+import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
+import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlinx.coroutines.test.runTest
 import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@EnableFlags(StatusBarNotifChips.FLAG_NAME)
 class StatusBarNotificationChipsInteractorTest : SysuiTestCase() {
     private val kosmos = testKosmos().useUnconfinedTestDispatcher()
     private val testScope = kosmos.testScope
+    private val activeNotificationListRepository = kosmos.activeNotificationListRepository
 
-    private val underTest = kosmos.statusBarNotificationChipsInteractor
+    private val underTest by lazy {
+        kosmos.statusBarNotificationChipsInteractor.also { it.start() }
+    }
 
     @Test
+    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun notificationChips_flagOff_noNotifs() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.notificationChips)
+
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = mock<StatusBarIconView>(),
+                        isPromoted = true,
+                    )
+                )
+            )
+
+            assertThat(latest).isEmpty()
+        }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun notificationChips_noNotifs_empty() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.notificationChips)
+
+            setNotifs(emptyList())
+
+            assertThat(latest).isEmpty()
+        }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun notificationChips_notifMissingStatusBarChipIconView_empty() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.notificationChips)
+
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = null,
+                        isPromoted = true,
+                    )
+                )
+            )
+
+            assertThat(latest).isEmpty()
+        }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun notificationChips_onePromotedNotif_statusBarIconViewMatches() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.notificationChips)
+
+            val icon = mock<StatusBarIconView>()
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = icon,
+                        isPromoted = true,
+                    )
+                )
+            )
+
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].key).isEqualTo("notif")
+            assertThat(latest!![0].statusBarChipIconView).isEqualTo(icon)
+        }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun notificationChips_onlyForPromotedNotifs() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.notificationChips)
+
+            val firstIcon = mock<StatusBarIconView>()
+            val secondIcon = mock<StatusBarIconView>()
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif1",
+                        statusBarChipIcon = firstIcon,
+                        isPromoted = true,
+                    ),
+                    activeNotificationModel(
+                        key = "notif2",
+                        statusBarChipIcon = secondIcon,
+                        isPromoted = true,
+                    ),
+                    activeNotificationModel(
+                        key = "notif3",
+                        statusBarChipIcon = mock<StatusBarIconView>(),
+                        isPromoted = false,
+                    ),
+                )
+            )
+
+            assertThat(latest).hasSize(2)
+            assertThat(latest!![0].key).isEqualTo("notif1")
+            assertThat(latest!![0].statusBarChipIconView).isEqualTo(firstIcon)
+            assertThat(latest!![1].key).isEqualTo("notif2")
+            assertThat(latest!![1].statusBarChipIconView).isEqualTo(secondIcon)
+        }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun notificationChips_notifUpdatesGoThrough() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.notificationChips)
+
+            val firstIcon = mock<StatusBarIconView>()
+            val secondIcon = mock<StatusBarIconView>()
+            val thirdIcon = mock<StatusBarIconView>()
+
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = firstIcon,
+                        isPromoted = true,
+                    )
+                )
+            )
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].key).isEqualTo("notif")
+            assertThat(latest!![0].statusBarChipIconView).isEqualTo(firstIcon)
+
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = secondIcon,
+                        isPromoted = true,
+                    )
+                )
+            )
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].key).isEqualTo("notif")
+            assertThat(latest!![0].statusBarChipIconView).isEqualTo(secondIcon)
+
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = thirdIcon,
+                        isPromoted = true,
+                    )
+                )
+            )
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].key).isEqualTo("notif")
+            assertThat(latest!![0].statusBarChipIconView).isEqualTo(thirdIcon)
+        }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun notificationChips_promotedNotifDisappearsThenReappears() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.notificationChips)
+
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = mock(),
+                        isPromoted = true,
+                    )
+                )
+            )
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].key).isEqualTo("notif")
+
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = mock(),
+                        isPromoted = false,
+                    )
+                )
+            )
+            assertThat(latest).isEmpty()
+
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = mock(),
+                        isPromoted = true,
+                    )
+                )
+            )
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].key).isEqualTo("notif")
+        }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun notificationChips_notifChangesKey() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.notificationChips)
+
+            val firstIcon = mock<StatusBarIconView>()
+            val secondIcon = mock<StatusBarIconView>()
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif|uid1",
+                        statusBarChipIcon = firstIcon,
+                        isPromoted = true,
+                    )
+                )
+            )
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].key).isEqualTo("notif|uid1")
+            assertThat(latest!![0].statusBarChipIconView).isEqualTo(firstIcon)
+
+            // WHEN a notification changes UID, which is a key change
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif|uid2",
+                        statusBarChipIcon = secondIcon,
+                        isPromoted = true,
+                    )
+                )
+            )
+
+            // THEN we correctly update
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].key).isEqualTo("notif|uid2")
+            assertThat(latest!![0].statusBarChipIconView).isEqualTo(secondIcon)
+        }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
     fun onPromotedNotificationChipTapped_emitsKeys() =
         testScope.runTest {
             val latest by collectValues(underTest.promotedNotificationChipTapEvent)
@@ -56,6 +303,7 @@
         }
 
     @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
     fun onPromotedNotificationChipTapped_sameKeyTwice_emitsTwice() =
         testScope.runTest {
             val latest by collectValues(underTest.promotedNotificationChipTapEvent)
@@ -67,4 +315,11 @@
             assertThat(latest[0]).isEqualTo("fakeKey")
             assertThat(latest[1]).isEqualTo("fakeKey")
         }
+
+    private fun setNotifs(notifs: List<ActiveNotificationModel>) {
+        activeNotificationListRepository.activeNotifications.value =
+            ActiveNotificationsStore.Builder()
+                .apply { notifs.forEach { addIndividualNotif(it) } }
+                .build()
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
index 1b41329..16376c5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
@@ -22,7 +22,9 @@
 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.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
@@ -34,26 +36,28 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
+import org.junit.Before
 import org.junit.runner.RunWith
 import org.mockito.kotlin.mock
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 @EnableFlags(StatusBarNotifChips.FLAG_NAME)
 class NotifChipsViewModelTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
-    private val testScope = kosmos.testScope
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
     private val activeNotificationListRepository = kosmos.activeNotificationListRepository
 
-    private val underTest = kosmos.notifChipsViewModel
+    private val underTest by lazy { kosmos.notifChipsViewModel }
+
+    @Before
+    fun setUp() {
+        kosmos.statusBarNotificationChipsInteractor.start()
+    }
 
     @Test
     fun chips_noNotifs_empty() =
-        testScope.runTest {
+        kosmos.runTest {
             val latest by collectLastValue(underTest.chips)
 
             setNotifs(emptyList())
@@ -63,7 +67,7 @@
 
     @Test
     fun chips_notifMissingStatusBarChipIconView_empty() =
-        testScope.runTest {
+        kosmos.runTest {
             val latest by collectLastValue(underTest.chips)
 
             setNotifs(
@@ -81,7 +85,7 @@
 
     @Test
     fun chips_onePromotedNotif_statusBarIconViewMatches() =
-        testScope.runTest {
+        kosmos.runTest {
             val latest by collectLastValue(underTest.chips)
 
             val icon = mock<StatusBarIconView>()
@@ -103,7 +107,7 @@
 
     @Test
     fun chips_onlyForPromotedNotifs() =
-        testScope.runTest {
+        kosmos.runTest {
             val latest by collectLastValue(underTest.chips)
 
             val firstIcon = mock<StatusBarIconView>()
@@ -135,7 +139,7 @@
 
     @Test
     fun chips_clickingChipNotifiesInteractor() =
-        testScope.runTest {
+        kosmos.runTest {
             val latest by collectLastValue(underTest.chips)
             val latestChipTap by
                 collectLastValue(
@@ -163,7 +167,6 @@
             ActiveNotificationsStore.Builder()
                 .apply { notifs.forEach { addIndividualNotif(it) } }
                 .build()
-        testScope.runCurrent()
     }
 
     companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
index 25d5ce5..eb0978e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
@@ -27,6 +27,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
 import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
@@ -38,6 +39,7 @@
 import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.setUpPackageManagerForMediaProjection
 import com.android.systemui.statusbar.chips.notification.demo.ui.viewmodel.DemoNotifChipViewModelTest.Companion.addDemoNotifChip
 import com.android.systemui.statusbar.chips.notification.demo.ui.viewmodel.demoNotifChipViewModel
+import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.chips.notification.ui.viewmodel.NotifChipsViewModelTest.Companion.assertIsNotifChip
 import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
@@ -67,6 +69,7 @@
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.any
@@ -79,7 +82,7 @@
 @OptIn(ExperimentalCoroutinesApi::class)
 @EnableFlags(StatusBarNotifChips.FLAG_NAME)
 class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
     private val testScope = kosmos.testScope
     private val systemClock = kosmos.fakeSystemClock
     private val commandRegistry = kosmos.commandRegistry
@@ -103,12 +106,13 @@
                 .thenReturn(chipBackgroundView)
         }
 
-    private val underTest = kosmos.ongoingActivityChipsViewModel
+    private val underTest by lazy { kosmos.ongoingActivityChipsViewModel }
 
     @Before
     fun setUp() {
         setUpPackageManagerForMediaProjection(kosmos)
         kosmos.demoNotifChipViewModel.start()
+        kosmos.statusBarNotificationChipsInteractor.start()
         val icon =
             BitmapDrawable(
                 context.resources,
@@ -616,6 +620,7 @@
         }
 
     @Test
+    @Ignore("b/364653005") // We'll need to re-do the animation story when we implement RON chips
     fun primaryChip_screenRecordStoppedViaDialog_chipHiddenWithoutAnimation() =
         testScope.runTest {
             screenRecordState.value = ScreenRecordModel.Recording
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorControllerTest.kt
index cb92b77..a1772e3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorControllerTest.kt
@@ -14,11 +14,11 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
 import com.android.systemui.statusbar.notification.data.repository.NotificationLaunchAnimationRepository
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
+import com.android.systemui.statusbar.notification.headsup.HeadsUpUtil
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.policy.HeadsUpManager
-import com.android.systemui.statusbar.policy.HeadsUpUtil
 import com.android.systemui.testKosmos
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
@@ -69,7 +69,7 @@
                 headsUpManager,
                 notification,
                 kosmos.interactionJankMonitor,
-                onFinishAnimationCallback
+                onFinishAnimationCallback,
             )
     }
 
@@ -95,7 +95,7 @@
                 notificationKey,
                 /* releaseImmediately= */ true,
                 /* animate= */ true,
-                /* reason= */ "onIntentStarted(willAnimate=false)"
+                /* reason= */ "onIntentStarted(willAnimate=false)",
             )
         verify(onFinishAnimationCallback).run()
     }
@@ -118,7 +118,7 @@
                 notificationKey,
                 /* releaseImmediately= */ true,
                 /* animate= */ true,
-                /* reason= */ "onLaunchAnimationCancelled()"
+                /* reason= */ "onLaunchAnimationCancelled()",
             )
         verify(onFinishAnimationCallback).run()
     }
@@ -141,7 +141,7 @@
                 notificationKey,
                 /* releaseImmediately= */ true,
                 /* animate= */ false,
-                /* reason= */ "onLaunchAnimationEnd()"
+                /* reason= */ "onLaunchAnimationEnd()",
             )
         verify(onFinishAnimationCallback).run()
     }
@@ -180,14 +180,14 @@
                 summary.key,
                 /* releaseImmediately= */ true,
                 /* animate= */ false,
-                /* reason= */ "onLaunchAnimationEnd()"
+                /* reason= */ "onLaunchAnimationEnd()",
             )
         verify(headsUpManager, never())
             .removeNotification(
                 notification.entry.key,
                 /* releaseImmediately= */ true,
                 /* animate= */ false,
-                /* reason= */ "onLaunchAnimationEnd()"
+                /* reason= */ "onLaunchAnimationEnd()",
             )
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
index c4b1b84..0dc01a6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
@@ -39,13 +39,13 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.ShadeViewController.Companion.WAKEUP_ANIMATION_DELAY_MS
 import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_WAKEUP
 import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
index 1f29255..544d201 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification.collection.coordinator;
 
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.Notification.FLAG_PROMOTED_ONGOING;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
@@ -24,12 +25,18 @@
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.Person;
 import android.content.Intent;
 import android.graphics.Color;
 import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -38,11 +45,14 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -136,6 +146,60 @@
         assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
     }
 
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void testIncludePromotedOngoingInSection_flagEnabled() {
+        // GIVEN the notification has FLAG_PROMOTED_ONGOING
+        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
+
+        // THEN the entry is in the fgs section
+        assertTrue(mFgsSection.isInSection(mEntryBuilder.build()));
+    }
+
+    @Test
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void testDiscludePromotedOngoingInSection_flagDisabled() {
+        // GIVEN the notification has FLAG_PROMOTED_ONGOING
+        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
+
+        // THEN the entry is NOT in the fgs section
+        assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void promoterSelectsPromotedOngoing_flagEnabled() {
+        ArgumentCaptor<NotifPromoter> captor = ArgumentCaptor.forClass(NotifPromoter.class);
+        verify(mNotifPipeline).addPromoter(captor.capture());
+        NotifPromoter promoter = captor.getValue();
+
+        // GIVEN the notification has FLAG_PROMOTED_ONGOING
+        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
+
+        // THEN the entry is promoted to top level
+        assertTrue(promoter.shouldPromoteToTopLevel(mEntryBuilder.build()));
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void promoterIgnoresNonPromotedOngoing_flagEnabled() {
+        ArgumentCaptor<NotifPromoter> captor = ArgumentCaptor.forClass(NotifPromoter.class);
+        verify(mNotifPipeline).addPromoter(captor.capture());
+        NotifPromoter promoter = captor.getValue();
+
+        // GIVEN the notification does not have FLAG_PROMOTED_ONGOING
+        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, false);
+
+        // THEN the entry is NOT promoted to top level
+        assertFalse(promoter.shouldPromoteToTopLevel(mEntryBuilder.build()));
+    }
+
+    @Test
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void noPromoterAdded_flagDisabled() {
+        verify(mNotifPipeline, never()).addPromoter(any());
+    }
+
     private Notification.CallStyle makeCallStyle() {
         final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
                 new Intent("action"), PendingIntent.FLAG_IMMUTABLE);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index 2c488e3..1d7f257 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
@@ -38,12 +38,13 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
 import com.android.systemui.statusbar.notification.collection.mockNotifCollection
-import com.android.systemui.statusbar.notification.collection.notifCollection
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender.OnEndLifetimeExtensionCallback
 import com.android.systemui.statusbar.notification.collection.provider.LaunchFullScreenIntentProvider
 import com.android.systemui.statusbar.notification.collection.render.NodeController
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManagerImpl
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener
 import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper.DecisionImpl
@@ -51,8 +52,6 @@
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider
 import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback
 import com.android.systemui.statusbar.phone.NotificationGroupTestHelper
-import com.android.systemui.statusbar.policy.BaseHeadsUpManager
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
 import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
@@ -84,7 +83,9 @@
 class HeadsUpCoordinatorTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
-    private val statusBarNotificationChipsInteractor = kosmos.statusBarNotificationChipsInteractor
+    private val statusBarNotificationChipsInteractor by lazy {
+        kosmos.statusBarNotificationChipsInteractor
+    }
     private val notifCollection = kosmos.mockNotifCollection
 
     private lateinit var coordinator: HeadsUpCoordinator
@@ -101,7 +102,7 @@
 
     private val notifPipeline: NotifPipeline = mock()
     private val logger = HeadsUpCoordinatorLogger(logcatLogBuffer(), verbose = true)
-    private val headsUpManager: BaseHeadsUpManager = mock()
+    private val headsUpManager: HeadsUpManagerImpl = mock()
     private val headsUpViewBinder: HeadsUpViewBinder = mock()
     private val visualInterruptionDecisionProvider: VisualInterruptionDecisionProvider = mock()
     private val remoteInputManager: NotificationRemoteInputManager = mock()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/LockScreenMinimalismCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/LockScreenMinimalismCoordinatorTest.kt
index d772e3e..14148cd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/LockScreenMinimalismCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/LockScreenMinimalismCoordinatorTest.kt
@@ -21,7 +21,6 @@
 import android.app.NotificationManager.IMPORTANCE_DEFAULT
 import android.app.NotificationManager.IMPORTANCE_LOW
 import android.platform.test.annotations.EnableFlags
-import android.provider.Settings
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -43,6 +42,7 @@
 import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
 import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
 import com.android.systemui.statusbar.notification.domain.interactor.lockScreenNotificationMinimalismSetting
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import com.android.systemui.statusbar.notification.shared.NotificationMinimalism
 import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
 import com.android.systemui.testKosmos
@@ -394,7 +394,7 @@
             assertThatTopUnseenKey().isEqualTo(solo1.key)
 
             // TEST: even being pinned doesn't take effect immediately
-            hunRepo1.isPinned.value = true
+            hunRepo1.pinnedStatus.value = PinnedStatus.PinnedBySystem
             testScheduler.advanceTimeBy(0.5.seconds)
             onBeforeTransformGroupsListener.onBeforeTransformGroups(listEntryList)
             assertThatTopUnseenKey().isEqualTo(solo1.key)
@@ -406,8 +406,8 @@
 
             // TEST: repeat; being heads up and pinned for 1 second triggers seen
             kosmos.headsUpNotificationRepository.orderedHeadsUpRows.value = listOf(hunRepo2)
-            hunRepo1.isPinned.value = false
-            hunRepo2.isPinned.value = true
+            hunRepo1.pinnedStatus.value = PinnedStatus.NotPinned
+            hunRepo2.pinnedStatus.value = PinnedStatus.PinnedBySystem
             testScheduler.advanceTimeBy(1.seconds)
             onBeforeTransformGroupsListener.onBeforeTransformGroups(listEntryList)
             assertThatTopUnseenKey().isEqualTo(null)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt
index 3fd9c21..d38fb50 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.keyguardRepository
-import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionStep
@@ -48,9 +47,9 @@
 import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.lockScreenShowOnlyUnseenNotificationsSetting
 import com.android.systemui.statusbar.notification.domain.interactor.seenNotificationsInteractor
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener
+import com.android.systemui.statusbar.notification.headsup.headsUpManager
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
-import com.android.systemui.statusbar.policy.headsUpManager
 import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.util.settings.fakeSettings
@@ -155,7 +154,7 @@
         runKeyguardCoordinatorTest {
             kosmos.setTransition(
                 sceneTransition = Idle(Scenes.Gone),
-                stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
+                stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE),
             )
 
             // WHEN: A notification is posted
@@ -170,7 +169,7 @@
             keyguardRepository.setKeyguardShowing(true)
             kosmos.setTransition(
                 sceneTransition = Idle(Scenes.Lockscreen),
-                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.AOD)
+                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.AOD),
             )
 
             // THEN: The notification is recognized as "seen" and is filtered out.
@@ -180,7 +179,7 @@
             keyguardRepository.setKeyguardShowing(false)
             kosmos.setTransition(
                 sceneTransition = Idle(Scenes.Gone),
-                stateTransition = TransitionStep(KeyguardState.AOD, KeyguardState.GONE)
+                stateTransition = TransitionStep(KeyguardState.AOD, KeyguardState.GONE),
             )
 
             // THEN: The notification is shown regardless
@@ -359,14 +358,14 @@
             keyguardRepository.setKeyguardShowing(false)
             kosmos.setTransition(
                 sceneTransition = Idle(Scenes.Gone),
-                stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
+                stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE),
             )
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
             kosmos.setTransition(
                 sceneTransition = Idle(Scenes.Lockscreen),
-                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.AOD)
+                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.AOD),
             )
 
             // THEN: The notification is now recognized as "seen" and is filtered out.
@@ -412,7 +411,7 @@
         runKeyguardCoordinatorTest {
             kosmos.setTransition(
                 sceneTransition = Idle(Scenes.Lockscreen),
-                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.LOCKSCREEN)
+                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.LOCKSCREEN),
             )
             val firstEntry = NotificationEntryBuilder().setId(1).build()
             collectionListener.onEntryAdded(firstEntry)
@@ -435,14 +434,14 @@
             keyguardRepository.setKeyguardShowing(false)
             kosmos.setTransition(
                 sceneTransition = Idle(Scenes.Gone),
-                stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
+                stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE),
             )
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
             kosmos.setTransition(
                 sceneTransition = Idle(Scenes.Lockscreen),
-                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.LOCKSCREEN)
+                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.LOCKSCREEN),
             )
 
             // THEN: The first notification is considered seen and is filtered out.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
index 3ad41a5..ba85e32 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -67,7 +67,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
 import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.util.time.FakeSystemClock;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
index d717fe4..dc0231f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
 import com.android.systemui.statusbar.notification.data.repository.notificationsKeyguardViewStateRepository
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
 import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
 import com.android.systemui.testKosmos
@@ -102,7 +103,7 @@
         }
 
     @Test
-    fun hasPinnedRows_rowGetsPinned_true() =
+    fun hasPinnedRows_rowGetsPinnedNormally_true() =
         testScope.runTest {
             val hasPinnedRows by collectLastValue(underTest.hasPinnedRows)
             // GIVEN no rows are pinned
@@ -115,8 +116,30 @@
             headsUpRepository.setNotifications(rows)
             runCurrent()
 
-            // WHEN a row gets pinned
-            rows[0].isPinned.value = true
+            // WHEN a row gets pinned normally
+            rows[0].pinnedStatus.value = PinnedStatus.PinnedBySystem
+            runCurrent()
+
+            // THEN hasPinnedRows updates to true
+            assertThat(hasPinnedRows).isTrue()
+        }
+
+    @Test
+    fun hasPinnedRows_rowGetsPinnedByUser_true() =
+        testScope.runTest {
+            val hasPinnedRows by collectLastValue(underTest.hasPinnedRows)
+            // GIVEN no rows are pinned
+            val rows =
+                arrayListOf(
+                    fakeHeadsUpRowRepository("key 0"),
+                    fakeHeadsUpRowRepository("key 1"),
+                    fakeHeadsUpRowRepository("key 2"),
+                )
+            headsUpRepository.setNotifications(rows)
+            runCurrent()
+
+            // WHEN a row gets pinned due to a chip tap
+            rows[0].pinnedStatus.value = PinnedStatus.PinnedByUser
             runCurrent()
 
             // THEN hasPinnedRows updates to true
@@ -138,7 +161,7 @@
             runCurrent()
 
             // THEN that row gets unpinned
-            rows[0].isPinned.value = false
+            rows[0].pinnedStatus.value = PinnedStatus.NotPinned
             runCurrent()
 
             // THEN hasPinnedRows updates to false
@@ -246,7 +269,7 @@
             runCurrent()
 
             // WHEN all rows gets pinned
-            rows[2].isPinned.value = true
+            rows[2].pinnedStatus.value = PinnedStatus.PinnedBySystem
             runCurrent()
 
             // THEN no rows are filtered
@@ -271,7 +294,7 @@
             assertThat(activeHeadsUpRows).containsExactly(rows[0], rows[1], rows[2])
 
             // WHEN all rows gets pinned
-            rows[2].isPinned.value = true
+            rows[2].pinnedStatus.value = PinnedStatus.PinnedBySystem
             runCurrent()
 
             // THEN no change
@@ -329,7 +352,7 @@
             runCurrent()
 
             // WHEN a row gets unpinned
-            rows[0].isPinned.value = false
+            rows[0].pinnedStatus.value = PinnedStatus.NotPinned
             runCurrent()
 
             // THEN the unpinned row is filtered
@@ -351,7 +374,7 @@
             runCurrent()
 
             // WHEN a row gets unpinned
-            rows[0].isPinned.value = false
+            rows[0].pinnedStatus.value = PinnedStatus.NotPinned
             runCurrent()
 
             // THEN all rows are still present
@@ -372,15 +395,15 @@
             headsUpRepository.setNotifications(rows)
             runCurrent()
 
-            rows[0].isPinned.value = true
+            rows[0].pinnedStatus.value = PinnedStatus.PinnedBySystem
             runCurrent()
             assertThat(pinnedHeadsUpRows).containsExactly(rows[0])
 
-            rows[0].isPinned.value = false
+            rows[0].pinnedStatus.value = PinnedStatus.NotPinned
             runCurrent()
             assertThat(pinnedHeadsUpRows).isEmpty()
 
-            rows[0].isPinned.value = true
+            rows[0].pinnedStatus.value = PinnedStatus.PinnedBySystem
             runCurrent()
             assertThat(pinnedHeadsUpRows).containsExactly(rows[0])
         }
@@ -485,7 +508,5 @@
         }
 
     private fun fakeHeadsUpRowRepository(key: String, isPinned: Boolean = false) =
-        FakeHeadsUpRowRepository(key = key, elementKey = Any()).apply {
-            this.isPinned.value = isPinned
-        }
+        FakeHeadsUpRowRepository(key = key, isPinned = isPinned)
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/AvalancheControllerTest.kt
similarity index 96%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/AvalancheControllerTest.kt
index c5eed73..22a9c64 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/AvalancheControllerTest.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.statusbar.policy
+package com.android.systemui.statusbar.notification.headsup
 
 import android.app.Notification
 import android.os.Handler
@@ -31,9 +31,11 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
 import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManagerTestUtil.createFullScreenIntentEntry
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
 import com.android.systemui.statusbar.phone.keyguardBypassController
-import com.android.systemui.statusbar.policy.HeadsUpManagerTestUtil.createFullScreenIntentEntry
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
+import com.android.systemui.statusbar.policy.configurationController
 import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.kotlin.JavaAdapter
@@ -76,7 +78,7 @@
     private val mGlobalSettings = FakeGlobalSettings()
     private val mSystemClock = FakeSystemClock()
     private val mExecutor = FakeExecutor(mSystemClock)
-    private lateinit var testableHeadsUpManager: BaseHeadsUpManager
+    private lateinit var testableHeadsUpManager: HeadsUpManagerImpl
 
     @Before
     fun setUp() {
@@ -114,7 +116,7 @@
             )
     }
 
-    private fun createHeadsUpEntry(id: Int): BaseHeadsUpManager.HeadsUpEntry {
+    private fun createHeadsUpEntry(id: Int): HeadsUpManagerImpl.HeadsUpEntry {
         return testableHeadsUpManager.createHeadsUpEntry(
             NotificationEntryBuilder()
                 .setSbn(HeadsUpManagerTestUtil.createSbn(id, Notification.Builder(mContext, "")))
@@ -122,7 +124,7 @@
         )
     }
 
-    private fun createFsiHeadsUpEntry(id: Int): BaseHeadsUpManager.HeadsUpEntry {
+    private fun createFsiHeadsUpEntry(id: Int): HeadsUpManagerImpl.HeadsUpEntry {
         return testableHeadsUpManager.createHeadsUpEntry(createFullScreenIntentEntry(id, mContext))
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.java
similarity index 85%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.java
index abb3e6e..01f78cb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.notification.headsup;
 
 import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
 
@@ -54,18 +54,17 @@
 import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.res.R;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
-import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.util.settings.FakeGlobalSettings;
 import com.android.systemui.util.time.FakeSystemClock;
 
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -73,6 +72,7 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import kotlinx.coroutines.flow.StateFlowKt;
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
 import platform.test.runner.parameterized.Parameters;
 
@@ -81,8 +81,8 @@
 @SmallTest
 @TestableLooper.RunWithLooper
 @RunWith(ParameterizedAndroidJunit4.class)
-// TODO(b/378142453): Merge this with BaseHeadsUpManagerTest.
-public class BaseHeadsUpManagerTest extends SysuiTestCase {
+// TODO(b/378142453): Merge this with HeadsUpManagerPhoneTest.
+public class HeadsUpManagerImplTest extends SysuiTestCase {
     protected KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
 
     @Rule
@@ -119,7 +119,7 @@
         assertThat(TEST_STICKY_AUTO_DISMISS_TIME).isLessThan(TEST_A11Y_AUTO_DISMISS_TIME);
     }
 
-    private BaseHeadsUpManager createHeadsUpManager() {
+    private HeadsUpManagerImpl createHeadsUpManager() {
         return new TestableHeadsUpManager(
                 mContext,
                 mLogger,
@@ -169,7 +169,7 @@
         return FlagsParameterization.allCombinationsOf(NotificationThrottleHun.FLAG_NAME);
     }
 
-    public BaseHeadsUpManagerTest(FlagsParameterization flags) {
+    public HeadsUpManagerImplTest(FlagsParameterization flags) {
         mSetFlagsRule.setFlagsParameterization(flags);
     }
 
@@ -184,7 +184,7 @@
 
     @Test
     public void testHasNotifications_headsUpManagerMapNotEmpty_true() {
-        final BaseHeadsUpManager bhum = createHeadsUpManager();
+        final HeadsUpManagerImpl bhum = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
         bhum.showNotification(entry);
 
@@ -195,10 +195,10 @@
     @Test
     @EnableFlags(NotificationThrottleHun.FLAG_NAME)
     public void testHasNotifications_avalancheMapNotEmpty_true() {
-        final BaseHeadsUpManager bhum = createHeadsUpManager();
+        final HeadsUpManagerImpl bhum = createHeadsUpManager();
         final NotificationEntry notifEntry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0,
                 mContext);
-        final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = bhum.createHeadsUpEntry(notifEntry);
+        final HeadsUpManagerImpl.HeadsUpEntry headsUpEntry = bhum.createHeadsUpEntry(notifEntry);
         mAvalancheController.addToNext(headsUpEntry, () -> {});
 
         assertThat(mAvalancheController.getWaitingEntryList()).isNotEmpty();
@@ -208,7 +208,7 @@
     @Test
     @EnableFlags(NotificationThrottleHun.FLAG_NAME)
     public void testHasNotifications_false() {
-        final BaseHeadsUpManager bhum = createHeadsUpManager();
+        final HeadsUpManagerImpl bhum = createHeadsUpManager();
         assertThat(bhum.mHeadsUpEntryMap).isEmpty();
         assertThat(mAvalancheController.getWaitingEntryList()).isEmpty();
         assertThat(bhum.hasNotifications()).isFalse();
@@ -217,10 +217,10 @@
     @Test
     @EnableFlags(NotificationThrottleHun.FLAG_NAME)
     public void testGetHeadsUpEntryList_includesAvalancheEntryList() {
-        final BaseHeadsUpManager bhum = createHeadsUpManager();
+        final HeadsUpManagerImpl bhum = createHeadsUpManager();
         final NotificationEntry notifEntry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0,
                 mContext);
-        final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = bhum.createHeadsUpEntry(notifEntry);
+        final HeadsUpManagerImpl.HeadsUpEntry headsUpEntry = bhum.createHeadsUpEntry(notifEntry);
         mAvalancheController.addToNext(headsUpEntry, () -> {});
 
         assertThat(bhum.getHeadsUpEntryList()).contains(headsUpEntry);
@@ -229,10 +229,10 @@
     @Test
     @EnableFlags(NotificationThrottleHun.FLAG_NAME)
     public void testGetHeadsUpEntry_returnsAvalancheEntry() {
-        final BaseHeadsUpManager bhum = createHeadsUpManager();
+        final HeadsUpManagerImpl bhum = createHeadsUpManager();
         final NotificationEntry notifEntry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0,
                 mContext);
-        final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = bhum.createHeadsUpEntry(notifEntry);
+        final HeadsUpManagerImpl.HeadsUpEntry headsUpEntry = bhum.createHeadsUpEntry(notifEntry);
         mAvalancheController.addToNext(headsUpEntry, () -> {});
 
         assertThat(bhum.getHeadsUpEntry(notifEntry.getKey())).isEqualTo(headsUpEntry);
@@ -240,7 +240,7 @@
 
     @Test
     public void testShowNotification_addsEntry() {
-        final BaseHeadsUpManager alm = createHeadsUpManager();
+        final HeadsUpManagerImpl alm = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
 
         alm.showNotification(entry);
@@ -252,7 +252,7 @@
 
     @Test
     public void testShowNotification_autoDismisses() {
-        final BaseHeadsUpManager alm = createHeadsUpManager();
+        final HeadsUpManagerImpl alm = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
 
         alm.showNotification(entry);
@@ -263,7 +263,7 @@
 
     @Test
     public void testRemoveNotification_removeDeferred() {
-        final BaseHeadsUpManager alm = createHeadsUpManager();
+        final HeadsUpManagerImpl alm = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
 
         alm.showNotification(entry);
@@ -276,7 +276,7 @@
 
     @Test
     public void testRemoveNotification_forceRemove() {
-        final BaseHeadsUpManager alm = createHeadsUpManager();
+        final HeadsUpManagerImpl alm = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
 
         alm.showNotification(entry);
@@ -289,7 +289,7 @@
 
     @Test
     public void testReleaseAllImmediately() {
-        final BaseHeadsUpManager alm = createHeadsUpManager();
+        final HeadsUpManagerImpl alm = createHeadsUpManager();
         for (int i = 0; i < TEST_NUM_NOTIFICATIONS; i++) {
             final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(i, mContext);
             entry.setRow(mRow);
@@ -303,7 +303,7 @@
 
     @Test
     public void testCanRemoveImmediately_notShownLongEnough() {
-        final BaseHeadsUpManager alm = createHeadsUpManager();
+        final HeadsUpManagerImpl alm = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
 
         alm.showNotification(entry);
@@ -314,14 +314,16 @@
 
     @Test
     public void testHunRemovedLogging() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry notifEntry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0,
                 mContext);
-        final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = mock(
-                BaseHeadsUpManager.HeadsUpEntry.class);
+        final HeadsUpManagerImpl.HeadsUpEntry headsUpEntry = mock(
+                HeadsUpManagerImpl.HeadsUpEntry.class);
+        when(headsUpEntry.getPinnedStatus())
+                .thenReturn(StateFlowKt.MutableStateFlow(PinnedStatus.NotPinned));
         headsUpEntry.mEntry = notifEntry;
 
-        hum.onEntryRemoved(headsUpEntry);
+        hum.onEntryRemoved(headsUpEntry, "test");
 
         verify(mLogger, times(1)).logNotificationActuallyRemoved(eq(notifEntry));
     }
@@ -329,7 +331,7 @@
 
     @Test
     public void testShowNotification_autoDismissesIncludingTouchAcceptanceDelay() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
         useAccessibilityTimeout(false);
 
@@ -342,7 +344,7 @@
 
     @Test
     public void testShowNotification_autoDismissesWithDefaultTimeout() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
         useAccessibilityTimeout(false);
 
@@ -356,7 +358,7 @@
 
     @Test
     public void testShowNotification_stickyForSomeTime_autoDismissesWithStickyTimeout() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = createStickyForSomeTimeEntry(/* id = */ 0);
         useAccessibilityTimeout(false);
 
@@ -370,7 +372,7 @@
 
     @Test
     public void testShowNotification_sticky_neverAutoDismisses() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = createStickyEntry(/* id = */ 0);
         useAccessibilityTimeout(false);
 
@@ -383,7 +385,7 @@
 
     @Test
     public void testShowNotification_autoDismissesWithAccessibilityTimeout() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
         useAccessibilityTimeout(true);
 
@@ -397,7 +399,7 @@
 
     @Test
     public void testShowNotification_stickyForSomeTime_autoDismissesWithAccessibilityTimeout() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = createStickyForSomeTimeEntry(/* id = */ 0);
         useAccessibilityTimeout(true);
 
@@ -411,7 +413,7 @@
 
     @Test
     public void testRemoveNotification_beforeMinimumDisplayTime() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
         useAccessibilityTimeout(false);
 
@@ -430,7 +432,7 @@
 
     @Test
     public void testRemoveNotification_afterMinimumDisplayTime() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
         useAccessibilityTimeout(false);
 
@@ -448,7 +450,7 @@
 
     @Test
     public void testRemoveNotification_releaseImmediately() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);
 
         hum.showNotification(entry);
@@ -462,7 +464,7 @@
 
     @Test
     public void testIsSticky_rowPinnedAndExpanded_true() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry notifEntry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0,
                 mContext);
         when(mRow.isPinned()).thenReturn(true);
@@ -470,7 +472,7 @@
 
         hum.showNotification(notifEntry);
 
-        final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
+        final HeadsUpManagerImpl.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
                 notifEntry.getKey());
         headsUpEntry.setExpanded(true);
 
@@ -479,13 +481,13 @@
 
     @Test
     public void testIsSticky_remoteInputActive_true() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry notifEntry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0,
                 mContext);
 
         hum.showNotification(notifEntry);
 
-        final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
+        final HeadsUpManagerImpl.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
                 notifEntry.getKey());
         headsUpEntry.mRemoteInputActive = true;
 
@@ -494,7 +496,7 @@
 
     @Test
     public void testIsSticky_hasFullScreenIntent_true() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry notifEntry =
                 HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext);
 
@@ -506,7 +508,7 @@
 
     @Test
     public void testIsSticky_stickyForSomeTime_false() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry entry = createStickyForSomeTimeEntry(/* id = */ 0);
 
         hum.showNotification(entry);
@@ -517,13 +519,13 @@
 
     @Test
     public void testIsSticky_false() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry notifEntry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0,
                 mContext);
 
         hum.showNotification(notifEntry);
 
-        final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
+        final HeadsUpManagerImpl.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
                 notifEntry.getKey());
         headsUpEntry.setExpanded(false);
         headsUpEntry.mRemoteInputActive = false;
@@ -533,7 +535,7 @@
 
     @Test
     public void testCompareTo_withNullEntries() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry alertEntry = new NotificationEntryBuilder().setTag("alert").build();
 
         hum.showNotification(alertEntry);
@@ -545,7 +547,7 @@
 
     @Test
     public void testCompareTo_withNonAlertEntries() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
 
         final NotificationEntry nonAlertEntry1 = new NotificationEntryBuilder().setTag(
                 "nae1").build();
@@ -561,9 +563,9 @@
 
     @Test
     public void testAlertEntryCompareTo_ongoingCallLessThanActiveRemoteInput() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
 
-        final BaseHeadsUpManager.HeadsUpEntry ongoingCall = hum.new HeadsUpEntry(
+        final HeadsUpManagerImpl.HeadsUpEntry ongoingCall = hum.new HeadsUpEntry(
                 new NotificationEntryBuilder()
                         .setSbn(HeadsUpManagerTestUtil.createSbn(/* id = */ 0,
                                 new Notification.Builder(mContext, "")
@@ -571,7 +573,7 @@
                                         .setOngoing(true)))
                         .build());
 
-        final BaseHeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry(
+        final HeadsUpManagerImpl.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry(
                 HeadsUpManagerTestUtil.createEntry(/* id = */ 1, mContext));
         activeRemoteInput.mRemoteInputActive = true;
 
@@ -581,11 +583,11 @@
 
     @Test
     public void testAlertEntryCompareTo_incomingCallLessThanActiveRemoteInput() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
 
         final Person person = new Person.Builder().setName("person").build();
         final PendingIntent intent = mock(PendingIntent.class);
-        final BaseHeadsUpManager.HeadsUpEntry incomingCall = hum.new HeadsUpEntry(
+        final HeadsUpManagerImpl.HeadsUpEntry incomingCall = hum.new HeadsUpEntry(
                 new NotificationEntryBuilder()
                         .setSbn(HeadsUpManagerTestUtil.createSbn(/* id = */ 0,
                                 new Notification.Builder(mContext, "")
@@ -593,7 +595,7 @@
                                                 .forIncomingCall(person, intent, intent))))
                         .build());
 
-        final BaseHeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry(
+        final HeadsUpManagerImpl.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry(
                 HeadsUpManagerTestUtil.createEntry(/* id = */ 1, mContext));
         activeRemoteInput.mRemoteInputActive = true;
 
@@ -604,10 +606,10 @@
     @Test
     @EnableFlags(NotificationThrottleHun.FLAG_NAME)
     public void testPinEntry_logsPeek_throttleEnabled() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
 
         // Needs full screen intent in order to be pinned
-        final BaseHeadsUpManager.HeadsUpEntry entryToPin = hum.new HeadsUpEntry(
+        final HeadsUpManagerImpl.HeadsUpEntry entryToPin = hum.new HeadsUpEntry(
                 HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext));
 
         // Note: the standard way to show a notification would be calling showNotification rather
@@ -620,17 +622,17 @@
         assertEquals(2, mUiEventLoggerFake.numLogs());
         assertEquals(AvalancheController.ThrottleEvent.AVALANCHE_THROTTLING_HUN_SHOWN.getId(),
                 mUiEventLoggerFake.eventId(0));
-        assertEquals(BaseHeadsUpManager.NotificationPeekEvent.NOTIFICATION_PEEK.getId(),
+        assertEquals(HeadsUpManagerImpl.NotificationPeekEvent.NOTIFICATION_PEEK.getId(),
                 mUiEventLoggerFake.eventId(1));
     }
 
     @Test
     @DisableFlags(NotificationThrottleHun.FLAG_NAME)
     public void testPinEntry_logsPeek_throttleDisabled() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
 
         // Needs full screen intent in order to be pinned
-        final BaseHeadsUpManager.HeadsUpEntry entryToPin = hum.new HeadsUpEntry(
+        final HeadsUpManagerImpl.HeadsUpEntry entryToPin = hum.new HeadsUpEntry(
                 HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext));
 
         // Note: the standard way to show a notification would be calling showNotification rather
@@ -641,13 +643,13 @@
         hum.onEntryAdded(entryToPin);
 
         assertEquals(1, mUiEventLoggerFake.numLogs());
-        assertEquals(BaseHeadsUpManager.NotificationPeekEvent.NOTIFICATION_PEEK.getId(),
+        assertEquals(HeadsUpManagerImpl.NotificationPeekEvent.NOTIFICATION_PEEK.getId(),
                 mUiEventLoggerFake.eventId(0));
     }
 
     @Test
     public void testSetUserActionMayIndirectlyRemove() {
-        final BaseHeadsUpManager hum = createHeadsUpManager();
+        final HeadsUpManagerImpl hum = createHeadsUpManager();
         final NotificationEntry notifEntry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0,
                 mContext);
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerPhoneTest.kt
similarity index 92%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerPhoneTest.kt
index 8ebdbaa..35d8253 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerPhoneTest.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.statusbar.policy
+package com.android.systemui.statusbar.notification.headsup
 
 import android.os.Handler
 import android.platform.test.annotations.EnableFlags
@@ -35,6 +35,7 @@
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
 import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
 import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.mockExecutorHandler
 import com.android.systemui.util.kotlin.JavaAdapter
@@ -58,7 +59,7 @@
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 @RunWithLooper
-class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManagerTest(flags) {
+class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : HeadsUpManagerImplTest(flags) {
 
     private val mHeadsUpManagerLogger = HeadsUpManagerLogger(logcatLogBuffer())
 
@@ -82,14 +83,13 @@
     private val mJavaAdapter: JavaAdapter = JavaAdapter(testScope.backgroundScope)
 
     @Mock private lateinit var mShadeInteractor: ShadeInteractor
-
     @Mock private lateinit var dumpManager: DumpManager
     private lateinit var mAvalancheController: AvalancheController
 
     @Mock private lateinit var mBgHandler: Handler
 
-    private fun createHeadsUpManagerPhone(): BaseHeadsUpManager {
-        return BaseHeadsUpManager(
+    private fun createHeadsUpManagerPhone(): HeadsUpManagerImpl {
+        return HeadsUpManagerImpl(
             mContext,
             mHeadsUpManagerLogger,
             statusBarStateController,
@@ -205,6 +205,25 @@
         assertThat(hmp.mEntriesToRemoveWhenReorderingAllowed.contains(notifEntry)).isTrue()
     }
 
+    class TestAnimationStateHandler : AnimationStateHandler {
+        override fun setHeadsUpGoingAwayAnimationsAllowed(allowed: Boolean) {}
+    }
+
+    @Test
+    @EnableFlags(NotificationThrottleHun.FLAG_NAME)
+    fun testReorderingAllowed_clearsListOfEntriesToRemove() {
+        whenever(mVSProvider.isReorderingAllowed).thenReturn(true)
+        val hmp = createHeadsUpManagerPhone()
+
+        val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+        hmp.showNotification(notifEntry)
+        assertThat(hmp.mEntriesToRemoveWhenReorderingAllowed.contains(notifEntry)).isTrue()
+
+        hmp.setAnimationStateHandler(TestAnimationStateHandler())
+        hmp.mOnReorderingAllowedListener.onReorderingAllowed()
+        assertThat(hmp.mEntriesToRemoveWhenReorderingAllowed.isEmpty()).isTrue()
+    }
+
     @Test
     @EnableFlags(NotificationThrottleHun.FLAG_NAME)
     fun testShowNotification_reorderNotAllowed_seenInShadeTrue() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTestUtil.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerTestUtil.java
similarity index 97%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTestUtil.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerTestUtil.java
index 306d6efd..684ce59 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTestUtil.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerTestUtil.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.notification.headsup;
 import android.app.ActivityManager;
 import android.app.Notification;
 import android.app.PendingIntent;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/TestableHeadsUpManager.java
similarity index 90%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/TestableHeadsUpManager.java
index 59987f4..2b077ed 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/TestableHeadsUpManager.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.notification.headsup;
 
 import static com.android.systemui.util.concurrency.MockExecutorHandlerKt.mockExecutorHandler;
 
@@ -33,12 +33,14 @@
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.util.settings.GlobalSettings;
 import com.android.systemui.util.time.SystemClock;
 
-class TestableHeadsUpManager extends BaseHeadsUpManager {
+class TestableHeadsUpManager extends HeadsUpManagerImpl {
 
     private HeadsUpEntry mLastCreatedEntry;
 
@@ -76,10 +78,10 @@
                 shadeInteractor,
                 avalancheController);
 
-        mTouchAcceptanceDelay = BaseHeadsUpManagerTest.TEST_TOUCH_ACCEPTANCE_TIME;
-        mMinimumDisplayTime = BaseHeadsUpManagerTest.TEST_MINIMUM_DISPLAY_TIME;
-        mAutoDismissTime = BaseHeadsUpManagerTest.TEST_AUTO_DISMISS_TIME;
-        mStickyForSomeTimeAutoDismissTime = BaseHeadsUpManagerTest.TEST_STICKY_AUTO_DISMISS_TIME;
+        mTouchAcceptanceDelay = HeadsUpManagerImplTest.TEST_TOUCH_ACCEPTANCE_TIME;
+        mMinimumDisplayTime = HeadsUpManagerImplTest.TEST_MINIMUM_DISPLAY_TIME;
+        mAutoDismissTime = HeadsUpManagerImplTest.TEST_AUTO_DISMISS_TIME;
+        mStickyForSomeTimeAutoDismissTime = HeadsUpManagerImplTest.TEST_STICKY_AUTO_DISMISS_TIME;
     }
 
     @NonNull
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
index 284efc7..d3bde84 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
@@ -70,13 +70,13 @@
 import com.android.systemui.statusbar.notification.NotifPipelineFlags
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.MAX_HUN_WHEN_AGE_MS
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.HUN_SUPPRESSED_OLD_WHEN
 import com.android.systemui.statusbar.policy.FakeDeviceProvisionedController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.util.FakeEventLog
 import com.android.systemui.util.settings.FakeGlobalSettings
 import com.android.systemui.util.settings.FakeSettings
@@ -109,7 +109,7 @@
 
                     override fun isTagLoggable(tagName: String, level: LogLevel): Boolean = true
                 },
-            systrace = false
+            systrace = false,
         )
 
     private val leakCheck = LeakCheckedTest.SysuiLeakCheck()
@@ -162,10 +162,10 @@
     @Before
     fun setUp() {
         val userId = ActivityManager.getCurrentUser()
-        val user = UserInfo(userId, "Current user", /* flags = */ 0)
+        val user = UserInfo(userId, "Current user", /* flags= */ 0)
 
         deviceProvisionedController.currentUser = userId
-        userTracker.set(listOf(user), /* currentUserIndex = */ 0)
+        userTracker.set(listOf(user), /* currentUserIndex= */ 0)
         systemSettings = FakeSettings()
         whenever(bubbles.canShowBubbleNotification()).thenReturn(true)
         whenever(settingsInteractor.isCooldownEnabled).thenReturn(MutableStateFlow(true))
@@ -491,7 +491,7 @@
 
     private fun withPeekAndPulseEntry(
         extendEntry: EntryBuilder.() -> Unit,
-        block: (NotificationEntry) -> Unit
+        block: (NotificationEntry) -> Unit,
     ) {
         ensurePeekState()
         block(buildPeekEntry(extendEntry))
@@ -540,10 +540,10 @@
     @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
     fun testShouldNotHeadsUp_silentNotification() {
         withPeekAndPulseEntry({
-                                  isGrouped = false
-                                  isGroupSummary = false
-                                  isSilent = true
-                              }) {
+            isGrouped = false
+            isGroupSummary = false
+            isSilent = true
+        }) {
             assertShouldNotHeadsUp(it)
             assertNoEventsLogged()
         }
@@ -553,10 +553,10 @@
     @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
     fun testShouldHeadsUp_silentNotificationFalse() {
         withPeekAndPulseEntry({
-                                  isGrouped = false
-                                  isGroupSummary = false
-                                  isSilent = false
-                              }) {
+            isGrouped = false
+            isGroupSummary = false
+            isSilent = false
+        }) {
             assertShouldHeadsUp(it)
             assertNoEventsLogged()
         }
@@ -697,7 +697,7 @@
         forEachFsiState {
             assertShouldNotFsi(
                 buildFsiEntry { suppressedVisualEffects = SUPPRESSED_EFFECT_FULL_SCREEN_INTENT },
-                expectWouldInterruptWithoutDnd = true
+                expectWouldInterruptWithoutDnd = true,
             )
             assertNoEventsLogged()
         }
@@ -719,7 +719,7 @@
                     suppressedVisualEffects = SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
                     importance = IMPORTANCE_DEFAULT
                 },
-                expectWouldInterruptWithoutDnd = false
+                expectWouldInterruptWithoutDnd = false,
             )
             assertNoEventsLogged()
         }
@@ -754,7 +754,7 @@
         assertUiEventLogged(
             FSI_SUPPRESSED_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR,
             entry.sbn.uid,
-            entry.sbn.packageName
+            entry.sbn.packageName,
         )
         assertSystemEventLogged("231322873", entry.sbn.uid, "groupAlertBehavior")
     }
@@ -813,7 +813,7 @@
         assertUiEventLogged(
             FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA,
             entry.sbn.uid,
-            entry.sbn.packageName
+            entry.sbn.packageName,
         )
         assertSystemEventLogged("274759612", entry.sbn.uid, "bubbleMetadata")
     }
@@ -960,7 +960,7 @@
         var keyguardIsShowing: Boolean = false,
         var keyguardIsOccluded: Boolean = false,
         var deviceProvisioned: Boolean = true,
-        var currentUserSetup: Boolean = true
+        var currentUserSetup: Boolean = true,
     )
 
     protected fun setState(state: State): Unit =
@@ -1131,7 +1131,7 @@
 
     protected fun withLegacySuppressor(
         suppressor: NotificationInterruptSuppressor,
-        block: () -> Unit
+        block: () -> Unit,
     ) {
         provider.addLegacySuppressor(suppressor)
         block()
@@ -1166,7 +1166,7 @@
 
     protected fun assertShouldNotFsi(
         entry: NotificationEntry,
-        expectWouldInterruptWithoutDnd: Boolean? = null
+        expectWouldInterruptWithoutDnd: Boolean? = null,
     ) =
         provider.makeUnloggedFullScreenIntentDecision(entry).let {
             provider.logFullScreenIntentDecision(it)
@@ -1175,7 +1175,7 @@
                 assertEquals(
                     "unexpected wouldInterruptWithoutDnd for FSI: ${it.logReason}",
                     expectWouldInterruptWithoutDnd,
-                    it.wouldInterruptWithoutDnd
+                    it.wouldInterruptWithoutDnd,
                 )
             }
         }
@@ -1227,9 +1227,9 @@
                             context,
                             /* requestCode = */ 0,
                             Intent().setPackage(context.packageName),
-                            FLAG_MUTABLE
+                            FLAG_MUTABLE,
                         ),
-                        Icon.createWithResource(context.resources, R.drawable.android)
+                        Icon.createWithResource(context.resources, R.drawable.android),
                     )
                 }
 
@@ -1272,7 +1272,7 @@
                     }
 
                     if (hasFsi) {
-                        nb.setFullScreenIntent(mock(), /* highPriority = */ true)
+                        nb.setFullScreenIntent(mock(), /* highPriority= */ true)
                     }
                 }
                 .build()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
index 7fd9c9f..ff8ef18 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
@@ -27,9 +27,9 @@
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shared.notifications.domain.interactor.NotificationSettingsInteractor
 import com.android.systemui.statusbar.notification.NotifPipelineFlags
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.EventLog
 import com.android.systemui.util.settings.GlobalSettings
@@ -63,7 +63,7 @@
         bubbles: Optional<Bubbles>,
         context: Context,
         notificationManager: NotificationManager,
-        settingsInteractor: NotificationSettingsInteractor
+        settingsInteractor: NotificationSettingsInteractor,
     ): VisualInterruptionDecisionProvider {
         return if (VisualInterruptionRefactor.isEnabled) {
             VisualInterruptionDecisionProviderImpl(
@@ -88,7 +88,7 @@
                 bubbles,
                 context,
                 notificationManager,
-                settingsInteractor
+                settingsInteractor,
             )
         } else {
             NotificationInterruptStateProviderWrapper(
@@ -109,7 +109,7 @@
                     systemClock,
                     globalSettings,
                     eventLog,
-                    bubbles
+                    bubbles,
                 )
             )
         }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorTest.kt
new file mode 100644
index 0000000..6736ccf
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorTest.kt
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.promoted
+
+import android.app.Notification
+import android.app.Notification.BigPictureStyle
+import android.app.Notification.BigTextStyle
+import android.app.Notification.CallStyle
+import android.app.Notification.MessagingStyle
+import android.app.Notification.ProgressStyle
+import android.app.Notification.ProgressStyle.Segment
+import android.app.PendingIntent
+import android.app.Person
+import android.content.Intent
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PromotedNotificationContentExtractorTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+
+    private val provider =
+        FakePromotedNotificationsProvider().also { kosmos.promotedNotificationsProvider = it }
+
+    private val underTest = kosmos.promotedNotificationContentExtractor
+
+    @Test
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun shouldNotExtract_bothFlagsDisabled() {
+        val notif = createEntry().also { provider.promotedEntries.add(it) }
+        val content = extractContent(notif)
+        assertThat(content).isNull()
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun shouldExtract_promotedNotificationUiFlagEnabled() {
+        val entry = createEntry().also { provider.promotedEntries.add(it) }
+        val content = extractContent(entry)
+        assertThat(content).isNotNull()
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+    fun shouldExtract_statusBarNotifChipsFlagEnabled() {
+        val entry = createEntry().also { provider.promotedEntries.add(it) }
+        val content = extractContent(entry)
+        assertThat(content).isNotNull()
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun shouldExtract_bothFlagsEnabled() {
+        val entry = createEntry().also { provider.promotedEntries.add(it) }
+        val content = extractContent(entry)
+        assertThat(content).isNotNull()
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun shouldNotExtract_providerDidNotPromote() {
+        val entry = createEntry().also { provider.promotedEntries.remove(it) }
+        val content = extractContent(entry)
+        assertThat(content).isNull()
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractContent_commonFields() {
+        val entry =
+            createEntry {
+                    setSubText(TEST_SUB_TEXT)
+                    setContentTitle(TEST_CONTENT_TITLE)
+                    setContentText(TEST_CONTENT_TEXT)
+                }
+                .also { provider.promotedEntries.add(it) }
+
+        val content = extractContent(entry)
+
+        assertThat(content).isNotNull()
+        assertThat(content?.subText).isEqualTo(TEST_SUB_TEXT)
+        assertThat(content?.title).isEqualTo(TEST_CONTENT_TITLE)
+        assertThat(content?.text).isEqualTo(TEST_CONTENT_TEXT)
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractContent_fromBigPictureStyle() {
+        val entry =
+            createEntry { setStyle(BigPictureStyle()) }.also { provider.promotedEntries.add(it) }
+
+        val content = extractContent(entry)
+
+        assertThat(content).isNotNull()
+        assertThat(content?.style).isEqualTo(Style.BigPicture)
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractContent_fromBigTextStyle() {
+        val entry =
+            createEntry { setStyle(BigTextStyle()) }.also { provider.promotedEntries.add(it) }
+
+        val content = extractContent(entry)
+
+        assertThat(content).isNotNull()
+        assertThat(content?.style).isEqualTo(Style.BigText)
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractContent_fromCallStyle() {
+        val hangUpIntent =
+            PendingIntent.getBroadcast(context, 0, Intent("hangup"), PendingIntent.FLAG_IMMUTABLE)
+
+        val entry =
+            createEntry { setStyle(CallStyle.forOngoingCall(TEST_PERSON, hangUpIntent)) }
+                .also { provider.promotedEntries.add(it) }
+
+        val content = extractContent(entry)
+
+        assertThat(content).isNotNull()
+        assertThat(content?.style).isEqualTo(Style.Call)
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractContent_fromProgressStyle() {
+        val entry =
+            createEntry {
+                    setStyle(ProgressStyle().addProgressSegment(Segment(100)).setProgress(75))
+                }
+                .also { provider.promotedEntries.add(it) }
+
+        val content = extractContent(entry)
+
+        assertThat(content).isNotNull()
+        assertThat(content?.style).isEqualTo(Style.Progress)
+        assertThat(content?.progress).isNotNull()
+        assertThat(content?.progress?.progress).isEqualTo(75)
+        assertThat(content?.progress?.progressMax).isEqualTo(100)
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractContent_fromIneligibleStyle() {
+        val entry =
+            createEntry {
+                    setStyle(
+                        MessagingStyle(TEST_PERSON).addMessage("message text", 0L, TEST_PERSON)
+                    )
+                }
+                .also { provider.promotedEntries.add(it) }
+
+        val content = extractContent(entry)
+
+        assertThat(content).isNotNull()
+        assertThat(content?.style).isEqualTo(Style.Ineligible)
+    }
+
+    private fun extractContent(entry: NotificationEntry): PromotedNotificationContentModel? {
+        val recoveredBuilder = Notification.Builder(context, entry.sbn.notification)
+        return underTest.extractContent(entry, recoveredBuilder)
+    }
+
+    private fun createEntry(builderBlock: Notification.Builder.() -> Unit = {}): NotificationEntry {
+        val notif = Notification.Builder(context, "a").also(builderBlock).build()
+        return NotificationEntryBuilder().setNotification(notif).build()
+    }
+
+    companion object {
+        private const val TEST_SUB_TEXT = "sub text"
+        private const val TEST_CONTENT_TITLE = "content title"
+        private const val TEST_CONTENT_TEXT = "content text"
+
+        private const val TEST_PERSON_NAME = "person name"
+        private const val TEST_PERSON_KEY = "person key"
+        private val TEST_PERSON =
+            Person.Builder().setKey(TEST_PERSON_KEY).setName(TEST_PERSON_NAME).build()
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java
new file mode 100644
index 0000000..b2962ee
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row;
+
+import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME;
+import static android.service.notification.NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.INotificationManager;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
+import android.service.notification.NotificationAssistantService;
+import android.service.notification.StatusBarNotification;
+import android.telecom.TelecomManager;
+import android.testing.TestableLooper;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.systemui.Dependency;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.AssistantFeedbackController;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+
+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.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@TestableLooper.RunWithLooper
+public class BundleNotificationInfoTest extends SysuiTestCase {
+    private static final String TEST_PACKAGE_NAME = "test_package";
+    private static final String TEST_SYSTEM_PACKAGE_NAME = PRINT_SPOOLER_PACKAGE_NAME;
+    private static final int TEST_UID = 1;
+    private static final String TEST_CHANNEL = "test_channel";
+    private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME";
+
+    private TestableLooper mTestableLooper;
+    private BundleNotificationInfo mInfo;
+    private NotificationChannel mNotificationChannel;
+    private StatusBarNotification mSbn;
+    private NotificationEntry mEntry;
+    private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
+
+    @Rule
+    public MockitoRule mockito = MockitoJUnit.rule();
+    @Mock
+    private MetricsLogger mMetricsLogger;
+    @Mock
+    private INotificationManager mMockINotificationManager;
+    @Mock
+    private PackageManager mMockPackageManager;
+    @Mock
+    private OnUserInteractionCallback mOnUserInteractionCallback;
+    @Mock
+    private ChannelEditorDialogController mChannelEditorDialogController;
+    @Mock
+    private AssistantFeedbackController mAssistantFeedbackController;
+    @Mock
+    private TelecomManager mTelecomManager;
+
+    @Before
+    public void setUp() throws Exception {
+        mTestableLooper = TestableLooper.get(this);
+
+        mContext.addMockSystemService(TelecomManager.class, mTelecomManager);
+
+        mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
+        // Inflate the layout
+        final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+        mInfo = (BundleNotificationInfo) layoutInflater.inflate(R.layout.bundle_notification_info,
+                null);
+        mInfo.setGutsParent(mock(NotificationGuts.class));
+        // Our view is never attached to a window so the View#post methods in
+        // BundleNotificationInfo never get called. Setting this will skip the post and do the
+        // action immediately.
+        mInfo.mSkipPost = true;
+
+        // PackageManager must return a packageInfo and applicationInfo.
+        final PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = TEST_PACKAGE_NAME;
+        when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt()))
+                .thenReturn(packageInfo);
+        final ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.uid = TEST_UID;  // non-zero
+        final PackageInfo systemPackageInfo = new PackageInfo();
+        systemPackageInfo.packageName = TEST_SYSTEM_PACKAGE_NAME;
+        when(mMockPackageManager.getPackageInfo(eq(TEST_SYSTEM_PACKAGE_NAME), anyInt()))
+                .thenReturn(systemPackageInfo);
+        when(mMockPackageManager.getPackageInfo(eq("android"), anyInt()))
+                .thenReturn(packageInfo);
+
+        // Package has one channel by default.
+        when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+                eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(1);
+
+        // Some test channels.
+        mNotificationChannel = new NotificationChannel(
+                TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_LOW);
+        Notification notification = new Notification();
+        notification.extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, applicationInfo);
+        mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
+                notification, UserHandle.getUserHandleForUid(TEST_UID), null, 0);
+        mEntry = new NotificationEntryBuilder().setSbn(mSbn).build();
+        when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(false);
+        when(mAssistantFeedbackController.getInlineDescriptionResource(any()))
+                .thenReturn(R.string.notification_channel_summary_automatic);
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testBindNotification_setsOnClickListenerForFeedback() throws Exception {
+        // When Notification Assistant is available,
+        when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(
+                new ComponentName("assistantPkg", "assistantCls"));
+
+        // ...and Package manager has an intent that matches.
+        ArrayList<ResolveInfo> resolveInfos = new ArrayList<>();
+        ResolveInfo info = new ResolveInfo();
+        info.activityInfo = new ActivityInfo();
+        info.activityInfo.packageName = "assistantPkg";
+        info.activityInfo.name = "assistantCls";
+        resolveInfos.add(info);
+        when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(resolveInfos);
+
+        // And we attempt to bind the notification to the Info object
+        final CountDownLatch latch = new CountDownLatch(1);
+        mInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mOnUserInteractionCallback,
+                mChannelEditorDialogController,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                (View v, Intent intent) -> {
+                    // Assert that the intent action and package match.
+                    assertEquals(intent.getAction(),
+                            ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS);
+                    assertEquals(intent.getPackage(), "assistantPkg");
+                    latch.countDown();
+                },
+                mUiEventLogger,
+                true,
+                false,
+                true,
+                mAssistantFeedbackController,
+                mMetricsLogger);
+        // and the feedback button is clicked,
+        final View feedbackButton = mInfo.findViewById(R.id.notification_guts_bundle_feedback);
+        feedbackButton.performClick();
+
+        // then of the intents queried for is the feedback intent,
+        ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockPackageManager, atLeastOnce()).queryIntentActivities(captor.capture(),
+                anyInt());
+        List<Intent> capturedIntents = captor.getAllValues();
+        Intent feedbackIntent = null;
+        for (int i = 0; i < capturedIntents.size(); i++) {
+            final Intent capturedIntent = capturedIntents.get(i);
+            if (capturedIntent.getAction() == ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS
+                    && capturedIntent.getPackage().equals("assistantPkg")) {
+                feedbackIntent = capturedIntent;
+            }
+        }
+        assertNotNull("feedbackIntent should be not null", feedbackIntent);
+        assertEquals(mSbn.getKey(),
+                feedbackIntent.getExtra(NotificationAssistantService.EXTRA_NOTIFICATION_KEY));
+
+        // and verify that listener was triggered.
+        assertEquals(0, latch.getCount());
+        assertEquals(View.VISIBLE, feedbackButton.getVisibility());
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testBindNotification_hidesFeedbackButtonWhenNoNAS() throws Exception {
+        // When the Notification Assistant is not available
+        when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(null);
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        mInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mOnUserInteractionCallback,
+                mChannelEditorDialogController,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                (View v, Intent intent) -> {
+                    // Assert that the intent action and package match.
+                    assertEquals(intent.getAction(),
+                            ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS);
+                    assertEquals(intent.getPackage(), "assistantPkg");
+                    latch.countDown();
+                },
+                mUiEventLogger,
+                true,
+                false,
+                true,
+                mAssistantFeedbackController,
+                mMetricsLogger);
+
+        final View feedbackButton = mInfo.findViewById(R.id.notification_guts_bundle_feedback);
+        feedbackButton.performClick();
+        // Listener was not triggered
+        assertEquals(1, latch.getCount());
+        assertEquals(View.GONE, feedbackButton.getVisibility());
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testBindNotification_hidesFeedbackButtonWhenNoIntent() throws Exception {
+        // When the Notification Assistant is available,
+        when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(
+                new ComponentName("assistantPkg", "assistantCls"));
+
+        // But the intent activity is null
+        when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(null);
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        mInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mOnUserInteractionCallback,
+                mChannelEditorDialogController,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                (View v, Intent intent) -> {
+                    // Assert that the intent action and package match.
+                    assertEquals(intent.getAction(),
+                            ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS);
+                    assertEquals(intent.getPackage(), "assistantPkg");
+                    latch.countDown();
+                },
+                mUiEventLogger,
+                true,
+                false,
+                true,
+                mAssistantFeedbackController,
+                mMetricsLogger);
+
+        final View feedbackButton = mInfo.findViewById(R.id.notification_guts_bundle_feedback);
+        feedbackButton.performClick();
+        // Listener was not triggered
+        assertEquals(1, latch.getCount());
+        assertEquals(View.GONE, feedbackButton.getVisibility());
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
index 657e9df..ca0f9ef 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
@@ -42,6 +42,7 @@
 import com.android.systemui.statusbar.notification.collection.render.FakeNodeController
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController.BUBBLES_SETTING_URI
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer
@@ -49,7 +50,6 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationRowStatsLogger
 import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.SmartReplyConstants
 import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent
 import com.android.systemui.util.mockito.any
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragControllerTest.java
index 1c5f37c..979a1d0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragControllerTest.java
@@ -40,8 +40,9 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.shade.ShadeController;
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
 import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -91,7 +92,7 @@
         ExpandableNotificationRowDragController controller = createSpyController();
         mRow.setDragController(controller);
         mRow.setHeadsUp(true);
-        mRow.setPinned(true);
+        mRow.setPinnedStatus(PinnedStatus.PinnedBySystem);
 
         mRow.doLongClickCallback(0, 0);
         mRow.doDragCallback(0, 0);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index b278f1a..6eb2764 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -42,6 +43,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.TypedValue;
@@ -56,8 +58,12 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.media.controls.util.MediaFeatureFlag;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
 import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
@@ -99,6 +105,7 @@
     @Mock private NotifLayoutInflaterFactory.Provider mNotifLayoutInflaterFactoryProvider;
     @Mock private HeadsUpStyleProvider mHeadsUpStyleProvider;
     @Mock private NotifLayoutInflaterFactory mNotifLayoutInflaterFactory;
+    @Mock private PromotedNotificationContentExtractor mPromotedNotificationContentExtractor;
 
     private final SmartReplyStateInflater mSmartReplyStateInflater =
             new SmartReplyStateInflater() {
@@ -142,6 +149,7 @@
                 mSmartReplyStateInflater,
                 mNotifLayoutInflaterFactoryProvider,
                 mHeadsUpStyleProvider,
+                mPromotedNotificationContentExtractor,
                 mock(NotificationRowContentBinderLogger.class));
     }
 
@@ -382,6 +390,75 @@
         verify(mRow, times(0)).onNotificationUpdated();
     }
 
+    @Test
+    @DisableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME})
+    public void testExtractsPromotedContent_notWhenBothFlagsDisabled() throws Exception {
+        final PromotedNotificationContentModel content =
+                new PromotedNotificationContentModel.Builder("key").build();
+        when(mPromotedNotificationContentExtractor.extractContent(any(), any()))
+                .thenReturn(content);
+
+        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);
+
+        verify(mPromotedNotificationContentExtractor, never()).extractContent(any(), any());
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+    public void testExtractsPromotedContent_whenPromotedNotificationUiFlagEnabled()
+            throws Exception {
+        final PromotedNotificationContentModel content =
+                new PromotedNotificationContentModel.Builder("key").build();
+        when(mPromotedNotificationContentExtractor.extractContent(any(), any()))
+                .thenReturn(content);
+
+        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);
+
+        verify(mPromotedNotificationContentExtractor, times(1)).extractContent(any(), any());
+        assertEquals(content, mRow.getEntry().getPromotedNotificationContentModel());
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void testExtractsPromotedContent_whenStatusBarNotifChipsFlagEnabled() throws Exception {
+        final PromotedNotificationContentModel content =
+                new PromotedNotificationContentModel.Builder("key").build();
+        when(mPromotedNotificationContentExtractor.extractContent(any(), any()))
+                .thenReturn(content);
+
+        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);
+
+        verify(mPromotedNotificationContentExtractor, times(1)).extractContent(any(), any());
+        assertEquals(content, mRow.getEntry().getPromotedNotificationContentModel());
+    }
+
+    @Test
+    @EnableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME})
+    public void testExtractsPromotedContent_whenBothFlagsEnabled() throws Exception {
+        final PromotedNotificationContentModel content =
+                new PromotedNotificationContentModel.Builder("key").build();
+        when(mPromotedNotificationContentExtractor.extractContent(any(), any()))
+                .thenReturn(content);
+
+        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);
+
+        verify(mPromotedNotificationContentExtractor, times(1)).extractContent(any(), any());
+        assertEquals(content, mRow.getEntry().getPromotedNotificationContentModel());
+    }
+
+    @Test
+    @EnableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME})
+    public void testExtractsPromotedContent_null() throws Exception {
+        when(mPromotedNotificationContentExtractor.extractContent(any(), any())).thenReturn(null);
+
+        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);
+
+        verify(mPromotedNotificationContentExtractor, times(1)).extractContent(any(), any());
+        assertNull(mRow.getEntry().getPromotedNotificationContentModel());
+    }
+
     private static void inflateAndWait(NotificationContentInflater inflater,
             @InflationFlag int contentToInflate,
             ExpandableNotificationRow row)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
index a1b63b1..6a0a5bb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
@@ -71,10 +71,10 @@
 import com.android.systemui.statusbar.notification.NotificationActivityStarter
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.testKosmos
 import com.android.systemui.util.kotlin.JavaAdapter
 import com.android.systemui.wmshell.BubblesManager
@@ -168,7 +168,10 @@
         @JvmStatic
         @Parameters(name = "{0}")
         fun getParams(): List<FlagsParameterization> {
-            return FlagsParameterization.allCombinationsOf().andSceneContainer()
+            return FlagsParameterization.allCombinationsOf(
+                    android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI
+                )
+                .andSceneContainer()
         }
     }
 
@@ -614,6 +617,43 @@
             )
     }
 
+    @Test
+    @Throws(Exception::class)
+    fun testInitializeBundleNotificationInfoView() {
+        val infoView: BundleNotificationInfo = mock()
+        val row = spy(helper.createRow())
+        val entry = row.entry
+
+        // Modify the notification entry to have a channel that is in SYSTEM_RESERVED_IDS
+        val channel = NotificationChannel(NotificationChannel.NEWS_ID, "name", 2)
+        NotificationEntryHelper.modifyRanking(entry).setChannel(channel).build()
+
+        whenever(row.isNonblockable).thenReturn(false)
+        val statusBarNotification = entry.sbn
+        // Can we change this to a call to bindGuts instead? We have the row,
+        // we need a MenuItem that we can put the infoView into.
+        gutsManager.initializeBundleNotificationInfo(row, infoView)
+
+        verify(infoView)
+            .bindNotification(
+                any<PackageManager>(),
+                any<INotificationManager>(),
+                eq(onUserInteractionCallback),
+                eq(channelEditorDialogController),
+                eq(statusBarNotification.packageName),
+                any<NotificationChannel>(),
+                eq(entry),
+                any<NotificationInfo.OnSettingsClickListener>(),
+                any<NotificationInfo.OnAppSettingsClickListener>(),
+                any<UiEventLogger>(),
+                /* isDeviceProvisioned = */ eq(false),
+                /* isNonblockable = */ eq(false),
+                /* wasShownHighPriority = */ eq(false),
+                eq(assistantFeedbackController),
+                eq(metricsLogger),
+            )
+    }
+
     private fun createTestNotificationRow(): ExpandableNotificationRow {
         val nb =
             Notification.Builder(mContext, testNotificationChannel.id)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
index 48608eb..1851799 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
@@ -21,6 +21,7 @@
 import android.os.AsyncTask
 import android.os.Build
 import android.os.CancellationSignal
+import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper.RunWithLooper
 import android.util.TypedValue
@@ -33,8 +34,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
@@ -62,6 +67,7 @@
 import org.mockito.kotlin.any
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
 import org.mockito.kotlin.spy
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
@@ -82,7 +88,7 @@
         object : NotifLayoutInflaterFactory.Provider {
             override fun provide(
                 row: ExpandableNotificationRow,
-                layoutType: Int
+                layoutType: Int,
             ): NotifLayoutInflaterFactory = mock()
         }
     private val smartReplyStateInflater: SmartReplyStateInflater =
@@ -95,7 +101,7 @@
                 notifPackageContext: Context,
                 entry: NotificationEntry,
                 existingSmartReplyState: InflatedSmartReplyState?,
-                newSmartReplyState: InflatedSmartReplyState
+                newSmartReplyState: InflatedSmartReplyState,
             ): InflatedSmartReplyViewHolder {
                 return inflatedSmartReplies
             }
@@ -104,6 +110,7 @@
                 return inflatedSmartReplyState
             }
         }
+    private val promotedNotificationContentExtractor: PromotedNotificationContentExtractor = mock()
 
     @Before
     fun setUp() {
@@ -125,7 +132,8 @@
                 smartReplyStateInflater,
                 layoutInflaterFactoryProvider,
                 mock<HeadsUpStyleProvider>(),
-                mock()
+                promotedNotificationContentExtractor,
+                mock(),
             )
     }
 
@@ -142,7 +150,8 @@
             FLAG_CONTENT_VIEW_ALL,
             builder,
             mContext,
-            smartReplyStateInflater
+            smartReplyStateInflater,
+            mock(),
         )
         verify(builder).createHeadsUpContentView(true)
     }
@@ -160,7 +169,8 @@
             FLAG_CONTENT_VIEW_ALL,
             builder,
             mContext,
-            smartReplyStateInflater
+            smartReplyStateInflater,
+            mock(),
         )
         verify(builder).createContentView(true)
     }
@@ -187,7 +197,7 @@
             true /* expectingException */,
             notificationInflater,
             FLAG_CONTENT_VIEW_ALL,
-            row
+            row,
         )
         Assert.assertTrue(row.privateLayout.childCount == 0)
         verify(row, times(0)).onNotificationUpdated()
@@ -210,7 +220,7 @@
             FLAG_CONTENT_VIEW_ALL,
             BindParams(),
             false /* forceInflate */,
-            null /* callback */
+            null, /* callback */
         )
         Assert.assertNull(row.entry.runningTask)
     }
@@ -223,7 +233,8 @@
             NotificationRowContentBinderImpl.InflationProgress(
                 packageContext = mContext,
                 remoteViews = NewRemoteViews(),
-                contentModel = NotificationContentModel(headsUpStatusBarModel)
+                contentModel = NotificationContentModel(headsUpStatusBarModel),
+                extractedPromotedNotificationContentModel = null,
             )
         val countDownLatch = CountDownLatch(1)
         NotificationRowContentBinderImpl.applyRemoteView(
@@ -261,7 +272,7 @@
                         get() =
                             AsyncFailRemoteView(
                                 mContext.packageName,
-                                com.android.systemui.tests.R.layout.custom_view_dark
+                                com.android.systemui.tests.R.layout.custom_view_dark,
                             )
                 },
             logger = mock(),
@@ -280,7 +291,7 @@
         val decoratedMediaView = builder.createContentView()
         Assert.assertFalse(
             "The decorated media style doesn't allow a view to be reapplied!",
-            NotificationRowContentBinderImpl.canReapplyRemoteView(mediaView, decoratedMediaView)
+            NotificationRowContentBinderImpl.canReapplyRemoteView(mediaView, decoratedMediaView),
         )
     }
 
@@ -304,7 +315,7 @@
         Assert.assertEquals(
             "Binder inflated a new view even though the old one was cached and usable.",
             view,
-            row.privateLayout.contractedChild
+            row.privateLayout.contractedChild,
         )
     }
 
@@ -327,7 +338,7 @@
         Assert.assertNotEquals(
             "Binder (somehow) used the same view when inflating.",
             view,
-            row.privateLayout.contractedChild
+            row.privateLayout.contractedChild,
         )
     }
 
@@ -396,7 +407,7 @@
     private fun getValidationError(
         measuredHeightDp: Float,
         targetSdk: Int,
-        contentView: RemoteViews?
+        contentView: RemoteViews?,
     ): String? {
         val view: View = mock()
         whenever(view.measuredHeight)
@@ -404,7 +415,7 @@
                 TypedValue.applyDimension(
                         COMPLEX_UNIT_SP,
                         measuredHeightDp,
-                        mContext.resources.displayMetrics
+                        mContext.resources.displayMetrics,
                     )
                     .toInt()
             )
@@ -419,7 +430,7 @@
         row.entry.sbn.notification.contentView =
             RemoteViews(
                 mContext.packageName,
-                com.android.systemui.tests.R.layout.invalid_notification_height
+                com.android.systemui.tests.R.layout.invalid_notification_height,
             )
         inflateAndWait(true, notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
         Assert.assertEquals(0, row.privateLayout.childCount.toLong())
@@ -451,7 +462,7 @@
             false,
             notificationInflater,
             FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
-            messagingRow
+            messagingRow,
         )
         Assert.assertNotNull(messagingRow.publicLayout.mSingleLineView)
         // assert this is the conversation layout
@@ -460,6 +471,59 @@
         )
     }
 
+    @Test
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun testExtractsPromotedContent_notWhenBothFlagsDisabled() {
+        val content = PromotedNotificationContentModel.Builder("key").build()
+        whenever(promotedNotificationContentExtractor.extractContent(any(), any()))
+            .thenReturn(content)
+
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
+
+        verify(promotedNotificationContentExtractor, never()).extractContent(any(), any())
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun testExtractsPromotedContent_whenPromotedNotificationUiFlagEnabled() {
+        val content = PromotedNotificationContentModel.Builder("key").build()
+        whenever(promotedNotificationContentExtractor.extractContent(any(), any()))
+            .thenReturn(content)
+
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
+
+        verify(promotedNotificationContentExtractor, times(1)).extractContent(any(), any())
+        Assert.assertEquals(content, row.entry.promotedNotificationContentModel)
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+    fun testExtractsPromotedContent_whenStatusBarNotifChipsFlagEnabled() {
+        val content = PromotedNotificationContentModel.Builder("key").build()
+        whenever(promotedNotificationContentExtractor.extractContent(any(), any()))
+            .thenReturn(content)
+
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
+
+        verify(promotedNotificationContentExtractor, times(1)).extractContent(any(), any())
+        Assert.assertEquals(content, row.entry.promotedNotificationContentModel)
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun testExtractsPromotedContent_whenBothFlagsEnabled() {
+        val content = PromotedNotificationContentModel.Builder("key").build()
+        whenever(promotedNotificationContentExtractor.extractContent(any(), any()))
+            .thenReturn(content)
+
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
+
+        verify(promotedNotificationContentExtractor, times(1)).extractContent(any(), any())
+        Assert.assertEquals(content, row.entry.promotedNotificationContentModel)
+    }
+
     private class ExceptionHolder {
         var exception: Exception? = null
     }
@@ -476,7 +540,7 @@
             parent: ViewGroup,
             executor: Executor,
             listener: OnViewAppliedListener,
-            handler: InteractionHandler?
+            handler: InteractionHandler?,
         ): CancellationSignal {
             executor.execute { listener.onError(RuntimeException("Failed to inflate async")) }
             return CancellationSignal()
@@ -486,7 +550,7 @@
             context: Context,
             parent: ViewGroup,
             executor: Executor,
-            listener: OnViewAppliedListener
+            listener: OnViewAppliedListener,
         ): CancellationSignal {
             return applyAsync(context, parent, executor, listener, null)
         }
@@ -496,7 +560,7 @@
         private fun inflateAndWait(
             inflater: NotificationRowContentBinderImpl,
             @InflationFlag contentToInflate: Int,
-            row: ExpandableNotificationRow
+            row: ExpandableNotificationRow,
         ) {
             inflateAndWait(false /* expectingException */, inflater, contentToInflate, row)
         }
@@ -535,7 +599,7 @@
                 contentToInflate,
                 BindParams(),
                 false /* forceInflate */,
-                callback /* callback */
+                callback, /* callback */
             )
             Assert.assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS))
             exceptionHolder.exception?.let { throw it }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 2340d02..080ac3f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -82,13 +82,14 @@
 import com.android.systemui.statusbar.notification.icon.IconBuilder;
 import com.android.systemui.statusbar.notification.icon.IconManager;
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.ExpandableNotificationRowLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
 import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
 import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
 import com.android.systemui.statusbar.policy.SmartReplyConstants;
@@ -204,6 +205,7 @@
                                 new MockSmartReplyInflater(),
                                 mock(NotifLayoutInflaterFactory.Provider.class),
                                 mock(HeadsUpStyleProvider.class),
+                                mock(PromotedNotificationContentExtractor.class),
                                 mock(NotificationRowContentBinderLogger.class))
                         : new NotificationContentInflater(
                                 mock(NotifRemoteViewCache.class),
@@ -214,6 +216,7 @@
                                 new MockSmartReplyInflater(),
                                 mock(NotifLayoutInflaterFactory.Provider.class),
                                 mock(HeadsUpStyleProvider.class),
+                                mock(PromotedNotificationContentExtractor.class),
                                 mock(NotificationRowContentBinderLogger.class));
         contentBinder.setInflateSynchronously(true);
         mBindStage = new RowContentBindStage(contentBinder,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
index 07935e4..92b8c3a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
@@ -24,8 +24,8 @@
 import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator
 import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.headsup.AvalancheController
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
-import com.android.systemui.statusbar.policy.AvalancheController
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 6425da4..de40abb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -83,7 +83,7 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.ColorUpdateLogger;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -107,7 +107,7 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
 import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController;
 import com.android.systemui.statusbar.policy.ZenModeController;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index b877456..2b7e950 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -27,11 +27,11 @@
 import com.android.systemui.statusbar.notification.emptyshade.ui.view.EmptyShadeView
 import com.android.systemui.statusbar.notification.footer.ui.view.FooterView
 import com.android.systemui.statusbar.notification.footer.ui.view.FooterView.FooterViewState
+import com.android.systemui.statusbar.notification.headsup.AvalancheController
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
 import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
-import com.android.systemui.statusbar.policy.AvalancheController
 import com.google.common.truth.Expect
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
index bf14472..e592e4b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
@@ -42,6 +42,7 @@
 import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
 import com.android.systemui.statusbar.notification.emptyshade.shared.ModesEmptyShadeFix
 import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
 import com.android.systemui.statusbar.policy.data.repository.fakeUserSetupRepository
 import com.android.systemui.statusbar.policy.fakeConfigurationController
@@ -522,21 +523,21 @@
             assertThat(pinnedHeadsUpRows).isEmpty()
 
             // WHEN a row gets pinned
-            rows[0].isPinned.value = true
+            rows[0].pinnedStatus.value = PinnedStatus.PinnedBySystem
             runCurrent()
 
             // THEN it's added to the list
             assertThat(pinnedHeadsUpRows).containsExactly(rows[0])
 
             // WHEN more rows are pinned
-            rows[1].isPinned.value = true
+            rows[1].pinnedStatus.value = PinnedStatus.PinnedBySystem
             runCurrent()
 
             // THEN they are all in the list
             assertThat(pinnedHeadsUpRows).containsExactly(rows[0], rows[1])
 
             // WHEN a row gets unpinned
-            rows[0].isPinned.value = false
+            rows[0].pinnedStatus.value = PinnedStatus.NotPinned
             runCurrent()
 
             // THEN it's removed from the list
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 a940ed4..f48fd3c 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
@@ -838,27 +838,26 @@
         testScope.runTest {
             var notificationCount = 10
             val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
-            val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
+            val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
             advanceTimeBy(50L)
             showLockscreen()
 
             shadeTestUtil.setSplitShade(false)
             configurationRepository.onAnyConfigurationChange()
 
-            assertThat(maxNotifications).isEqualTo(10)
+            assertThat(config?.maxNotifications).isEqualTo(10)
 
             // Also updates when directly requested (as it would from NotificationStackScrollLayout)
             notificationCount = 25
             sharedNotificationContainerInteractor.notificationStackChanged()
             advanceTimeBy(50L)
-            assertThat(maxNotifications).isEqualTo(25)
+            assertThat(config?.maxNotifications).isEqualTo(25)
 
             // Also ensure another collection starts with the same value. As an example, folding
             // then unfolding will restart the coroutine and it must get the last value immediately.
-            val newMaxNotifications by
-                collectLastValue(underTest.getMaxNotifications(calculateSpace))
+            val newConfig by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
             advanceTimeBy(50L)
-            assertThat(newMaxNotifications).isEqualTo(25)
+            assertThat(newConfig?.maxNotifications).isEqualTo(25)
         }
 
     @Test
@@ -866,18 +865,18 @@
         testScope.runTest {
             var notificationCount = 10
             val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
-            val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
+            val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
             advanceTimeBy(50L)
             showLockscreen()
 
             shadeTestUtil.setSplitShade(false)
             configurationRepository.onAnyConfigurationChange()
 
-            assertThat(maxNotifications).isEqualTo(10)
+            assertThat(config?.maxNotifications).isEqualTo(10)
 
             // Shade expanding... still 10
             shadeTestUtil.setLockscreenShadeExpansion(0.5f)
-            assertThat(maxNotifications).isEqualTo(10)
+            assertThat(config?.maxNotifications).isEqualTo(10)
 
             notificationCount = 25
 
@@ -885,20 +884,20 @@
             shadeTestUtil.setLockscreenShadeTracking(true)
 
             // Should still be 10, since the user is interacting
-            assertThat(maxNotifications).isEqualTo(10)
+            assertThat(config?.maxNotifications).isEqualTo(10)
 
             shadeTestUtil.setLockscreenShadeTracking(false)
             shadeTestUtil.setLockscreenShadeExpansion(0f)
 
             // Stopped tracking, show 25
-            assertThat(maxNotifications).isEqualTo(25)
+            assertThat(config?.maxNotifications).isEqualTo(25)
         }
 
     @Test
     fun maxNotificationsOnShade() =
         testScope.runTest {
             val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> 10 }
-            val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
+            val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
             advanceTimeBy(50L)
 
             // Show lockscreen with shade expanded
@@ -908,7 +907,7 @@
             configurationRepository.onAnyConfigurationChange()
 
             // -1 means No Limit
-            assertThat(maxNotifications).isEqualTo(-1)
+            assertThat(config?.maxNotifications).isEqualTo(-1)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index d9e9495..f76f1ce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -57,7 +57,7 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 6441405..ad8b675 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -53,7 +53,7 @@
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index dd03ab3..f9f2cd3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -45,13 +45,14 @@
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor;
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
 import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.policy.Clock;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Assert;
@@ -131,13 +132,13 @@
 
     @Test
     public void testShowinEntryUpdated() {
-        mRow.setPinned(true);
+        mRow.setPinnedStatus(PinnedStatus.PinnedBySystem);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
         when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
         mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
         assertEquals(mRow.getEntry(), mHeadsUpStatusBarView.getShowingEntry());
 
-        mRow.setPinned(false);
+        mRow.setPinnedStatus(PinnedStatus.NotPinned);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
         mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
         assertEquals(null, mHeadsUpStatusBarView.getShowingEntry());
@@ -145,13 +146,13 @@
 
     @Test
     public void testShownUpdated() {
-        mRow.setPinned(true);
+        mRow.setPinnedStatus(PinnedStatus.PinnedBySystem);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
         when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
         mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
         assertTrue(mHeadsUpAppearanceController.isShown());
 
-        mRow.setPinned(false);
+        mRow.setPinnedStatus(PinnedStatus.NotPinned);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
         mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
         Assert.assertFalse(mHeadsUpAppearanceController.isShown());
@@ -160,13 +161,13 @@
     @Test
     @DisableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME)
     public void testHeaderUpdated() {
-        mRow.setPinned(true);
+        mRow.setPinnedStatus(PinnedStatus.PinnedBySystem);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
         when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
         mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
         assertEquals(mRow.getHeaderVisibleAmount(), 0.0f, 0.0f);
 
-        mRow.setPinned(false);
+        mRow.setPinnedStatus(PinnedStatus.NotPinned);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
         mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
         assertEquals(mRow.getHeaderVisibleAmount(), 1.0f, 0.0f);
@@ -176,13 +177,13 @@
     public void testOperatorNameViewUpdated() {
         mHeadsUpAppearanceController.setAnimationsEnabled(false);
 
-        mRow.setPinned(true);
+        mRow.setPinnedStatus(PinnedStatus.PinnedBySystem);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
         when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
         mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
         assertEquals(View.INVISIBLE, mOperatorNameView.getVisibility());
 
-        mRow.setPinned(false);
+        mRow.setPinnedStatus(PinnedStatus.NotPinned);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
         mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
         assertEquals(View.VISIBLE, mOperatorNameView.getVisibility());
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
new file mode 100644
index 0000000..90506a1
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.platform.test.annotations.EnableFlags
+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.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+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)
+@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
+class MultiDisplayAutoHideControllerStoreTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+    private val testScope = kosmos.testScope
+    private val fakeDisplayRepository = kosmos.displayRepository
+
+    // Lazy so that @EnableFlags has time to run before underTest is instantiated.
+    private val underTest by lazy { kosmos.multiDisplayAutoHideControllerStore }
+
+    @Before fun addDisplays() = runBlocking { fakeDisplayRepository.addDisplay(DEFAULT_DISPLAY) }
+
+    @Before
+    fun start() {
+        underTest.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/phone/StatusBarTouchableRegionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerTest.kt
similarity index 97%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerTest.kt
index a008588..d82cb86 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerTest.kt
@@ -41,12 +41,12 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @OptIn(ExperimentalCoroutinesApi::class)
-class StatusBarTouchableRegionManagerTest : SysuiTestCase() {
+class ShadeTouchableRegionManagerTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val sceneRepository = kosmos.sceneContainerRepository
 
-    private val underTest by Lazy { kosmos.statusBarTouchableRegionManager }
+    private val underTest by Lazy { kosmos.shadeTouchableRegionManager }
 
     @Test
     @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 95472cad..41782a1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -73,7 +73,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
index 20b273a..d5651ec 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
@@ -22,21 +22,25 @@
 import android.content.pm.UserInfo
 import android.os.UserHandle
 import android.os.UserManager
+import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.GuestResetOrExitSessionReceiver
 import com.android.systemui.GuestResumeSessionReceiver
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.testKosmos
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.user.domain.model.ShowDialogRequestModel
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.kotlinArgumentCaptor
 import com.android.systemui.util.mockito.whenever
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.TestCoroutineScope
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -48,6 +52,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper
 class GuestUserInteractorTest : SysuiTestCase() {
 
     @Mock private lateinit var manager: UserManager
@@ -64,16 +69,15 @@
 
     private lateinit var underTest: GuestUserInteractor
 
-    private lateinit var scope: TestCoroutineScope
-    private lateinit var repository: FakeUserRepository
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+    private val scope = kosmos.testScope
+    private val repository = FakeUserRepository()
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         whenever(manager.createGuest(any())).thenReturn(GUEST_USER_INFO)
 
-        scope = TestCoroutineScope()
-        repository = FakeUserRepository()
         repository.setUserInfos(ALL_USERS)
 
         underTest = initGuestUserInteractor(context)
@@ -83,8 +87,8 @@
         GuestUserInteractor(
             applicationContext = context,
             applicationScope = scope,
-            mainDispatcher = IMMEDIATE,
-            backgroundDispatcher = IMMEDIATE,
+            mainDispatcher = kosmos.testDispatcher,
+            backgroundDispatcher = kosmos.testDispatcher,
             manager = manager,
             repository = repository,
             deviceProvisionedController = deviceProvisionedController,
@@ -92,7 +96,7 @@
             refreshUsersScheduler =
                 RefreshUsersScheduler(
                     applicationScope = scope,
-                    mainDispatcher = IMMEDIATE,
+                    mainDispatcher = kosmos.testDispatcher,
                     repository = repository,
                 ),
             uiEventLogger = uiEventLogger,
@@ -118,7 +122,7 @@
 
     @Test
     fun onDeviceBootCompleted_allowedToAdd_createGuest() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             setAllowedToAdd()
 
             underTest.onDeviceBootCompleted()
@@ -129,7 +133,7 @@
 
     @Test
     fun onDeviceBootCompleted_awaitProvisioning_andCreateGuest() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             setAllowedToAdd(isAllowed = false)
             underTest.onDeviceBootCompleted()
             val captor =
@@ -145,7 +149,7 @@
 
     @Test
     fun createAndSwitchTo() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             underTest.createAndSwitchTo(
                 showDialog = showDialog,
                 dismissDialog = dismissDialog,
@@ -160,7 +164,7 @@
 
     @Test
     fun createAndSwitchTo_failsToCreate_doesNotSwitchTo() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             whenever(manager.createGuest(any())).thenReturn(null)
 
             underTest.createAndSwitchTo(
@@ -177,7 +181,7 @@
 
     @Test
     fun exit_returnsToTargetUser() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             repository.setSelectedUserInfo(GUEST_USER_INFO)
 
             val targetUserId = NON_GUEST_USER_INFO.id
@@ -197,7 +201,7 @@
 
     @Test
     fun exit_returnsToLastNonGuest() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             val expectedUserId = NON_GUEST_USER_INFO.id
             whenever(manager.getUserInfo(expectedUserId)).thenReturn(NON_GUEST_USER_INFO)
             repository.lastSelectedNonGuestUserId = expectedUserId
@@ -219,7 +223,7 @@
 
     @Test
     fun exit_lastNonGuestWasRemoved_returnsToMainUser() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             val removedUserId = 310
             val mainUserId = 10
             repository.lastSelectedNonGuestUserId = removedUserId
@@ -242,7 +246,7 @@
 
     @Test
     fun exit_guestWasEphemeral_itIsRemoved() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
             repository.setUserInfos(listOf(NON_GUEST_USER_INFO, EPHEMERAL_GUEST_USER_INFO))
             repository.setSelectedUserInfo(EPHEMERAL_GUEST_USER_INFO)
@@ -265,7 +269,7 @@
 
     @Test
     fun exit_forceRemoveGuest_itIsRemoved() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
             repository.setSelectedUserInfo(GUEST_USER_INFO)
             val targetUserId = NON_GUEST_USER_INFO.id
@@ -287,7 +291,7 @@
 
     @Test
     fun exit_selectedDifferentFromGuestUser_doNothing() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
 
             underTest.exit(
@@ -304,7 +308,7 @@
 
     @Test
     fun exit_selectedIsActuallyNotAguestUser_doNothing() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
 
             underTest.exit(
@@ -321,7 +325,7 @@
 
     @Test
     fun remove_returnsToTargetUser() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
             repository.setSelectedUserInfo(GUEST_USER_INFO)
 
@@ -342,7 +346,7 @@
 
     @Test
     fun remove_selectedDifferentFromGuestUser_doNothing() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
             repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
 
@@ -359,7 +363,7 @@
 
     @Test
     fun remove_selectedIsActuallyNotAguestUser_doNothing() =
-        runBlocking(IMMEDIATE) {
+        kosmos.runTest {
             whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
             repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
 
@@ -395,11 +399,7 @@
     companion object {
         private val IMMEDIATE = Dispatchers.Main.immediate
         private val NON_GUEST_USER_INFO =
-            UserInfo(
-                /* id= */ 818,
-                /* name= */ "non_guest",
-                /* flags= */ UserInfo.FLAG_FULL,
-            )
+            UserInfo(/* id= */ 818, /* name= */ "non_guest", /* flags= */ UserInfo.FLAG_FULL)
         private val GUEST_USER_INFO =
             UserInfo(
                 /* id= */ 669,
@@ -416,10 +416,6 @@
                 /* flags= */ UserInfo.FLAG_EPHEMERAL or UserInfo.FLAG_FULL,
                 UserManager.USER_TYPE_FULL_GUEST,
             )
-        private val ALL_USERS =
-            listOf(
-                NON_GUEST_USER_INFO,
-                GUEST_USER_INFO,
-            )
+        private val ALL_USERS = listOf(NON_GUEST_USER_INFO, GUEST_USER_INFO)
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerTest.kt b/packages/SystemUI/multivalentTests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerTest.kt
rename to packages/SystemUI/multivalentTests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerTest.kt
diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp
index 6212e2b..2cd3346 100644
--- a/packages/SystemUI/plugin/Android.bp
+++ b/packages/SystemUI/plugin/Android.bp
@@ -55,6 +55,8 @@
         "SystemUICommon",
         "SystemUILogLib",
         "androidx.annotation_annotation",
+        "androidx.compose.ui_ui",
+        "androidx.compose.runtime_runtime",
     ],
 }
 
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index 074277c..dcb15a7 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -103,6 +103,15 @@
         void onSmartspaceTargetsUpdated(List<? extends Parcelable> targets);
     }
 
+    /**
+     * Sets {@link BcSmartspaceConfigPlugin}.
+     *
+     * TODO: b/259566300 - Remove once isViewPager2Enabled is fully rolled out
+     */
+    default void registerConfigProvider(BcSmartspaceConfigPlugin configProvider) {
+        throw new UnsupportedOperationException("Not implemented by " + getClass());
+    }
+
     /** View to which this plugin can be registered, in order to get updates. */
     interface SmartspaceView {
         void registerDataProvider(BcSmartspaceDataPlugin plugin);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockAnimations.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockAnimations.kt
new file mode 100644
index 0000000..2df14a8
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockAnimations.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+import android.view.View
+import com.android.systemui.plugins.annotations.ProtectedInterface
+
+/** Methods which trigger various clock animations */
+@ProtectedInterface
+interface ClockAnimations {
+    /** Runs an enter animation (if any) */
+    fun enter()
+
+    /** Sets how far into AOD the device currently is. */
+    fun doze(fraction: Float)
+
+    /** Sets how far into the folding animation the device is. */
+    fun fold(fraction: Float)
+
+    /** Runs the battery animation (if any). */
+    fun charge()
+
+    /**
+     * Runs when the clock's position changed during the move animation.
+     *
+     * @param fromLeft the [View.getLeft] position of the clock, before it started moving.
+     * @param direction the direction in which it is moving. A positive number means right, and
+     *   negative means left.
+     * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
+     *   it finished moving.
+     * @deprecated use {@link #onPositionUpdated(float, float)} instead.
+     */
+    fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float)
+
+    /**
+     * Runs when the clock's position changed during the move animation.
+     *
+     * @param distance is the total distance in pixels to offset the glyphs when animation
+     *   completes. Negative distance means we are animating the position towards the center.
+     * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
+     *   it finished moving.
+     */
+    fun onPositionUpdated(distance: Float, fraction: Float)
+
+    /**
+     * Runs when swiping clock picker, swipingFraction: 1.0 -> clock is scaled up in the preview,
+     * 0.0 -> clock is scaled down in the shade; previewRatio is previewSize / screenSize
+     */
+    fun onPickerCarouselSwiping(swipingFraction: Float)
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockConfig.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockConfig.kt
new file mode 100644
index 0000000..d84d890
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockConfig.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+/**
+ * Exposes the rendering capabilities of this clock to SystemUI so that it can be hosted and render
+ * correctly in SystemUI's process. Ideally all clocks could be rendered identically, but in
+ * practice we different clocks require different behavior from SystemUI.
+ */
+data class ClockConfig(
+    val id: ClockId,
+
+    /** Localized name of the clock */
+    val name: String,
+
+    /** Localized accessibility description for the clock */
+    val description: String,
+
+    /** Transition to AOD should move smartspace like large clock instead of small clock */
+    val useAlternateSmartspaceAODTransition: Boolean = false,
+
+    /** Deprecated version of isReactiveToTone; moved to ClockPickerConfig */
+    @Deprecated("TODO(b/352049256): Remove in favor of ClockPickerConfig.isReactiveToTone")
+    val isReactiveToTone: Boolean = true,
+
+    /** True if the clock is large frame clock, which will use weather in compose. */
+    val useCustomClockScene: Boolean = false,
+)
+
+/** Render configuration options for a specific clock face. */
+data class ClockFaceConfig(
+    /** Expected interval between calls to onTimeTick. Can always reduce to PER_MINUTE in AOD. */
+    val tickRate: ClockTickRate = ClockTickRate.PER_MINUTE,
+
+    /** Call to check whether the clock consumes weather data */
+    val hasCustomWeatherDataDisplay: Boolean = false,
+
+    /**
+     * Whether this clock has a custom position update animation. If true, the keyguard will call
+     * `onPositionUpdated` to notify the clock of a position update animation. If false, a default
+     * animation will be used (e.g. a simple translation).
+     */
+    val hasCustomPositionUpdatedAnimation: Boolean = false,
+
+    /** True if the clock is large frame clock, which will use weatherBlueprint in compose. */
+    val useCustomClockScene: Boolean = false,
+)
+
+/** Tick rates for clocks */
+enum class ClockTickRate(val value: Int) {
+    PER_MINUTE(2), // Update the clock once per minute.
+    PER_SECOND(1), // Update the clock once per second.
+    PER_FRAME(0), // Update the clock every second.
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt
new file mode 100644
index 0000000..32fec32
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.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.plugins.clocks
+
+import com.android.systemui.plugins.annotations.ProtectedInterface
+import com.android.systemui.plugins.annotations.SimpleProperty
+import java.io.PrintWriter
+
+/** Interface for controlling an active clock */
+@ProtectedInterface
+interface ClockController {
+    @get:SimpleProperty
+    /** A small version of the clock, appropriate for smaller viewports */
+    val smallClock: ClockFaceController
+
+    @get:SimpleProperty
+    /** A large version of the clock, appropriate when a bigger viewport is available */
+    val largeClock: ClockFaceController
+
+    @get:SimpleProperty
+    /** Determines the way the hosting app should behave when rendering either clock face */
+    val config: ClockConfig
+
+    @get:SimpleProperty
+    /** Events that clocks may need to respond to */
+    val events: ClockEvents
+
+    /** Initializes various rendering parameters. If never called, provides reasonable defaults. */
+    fun initialize(isDarkTheme: Boolean, dozeFraction: Float, foldFraction: Float)
+
+    /** Optional method for dumping debug information */
+    fun dump(pw: PrintWriter)
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt
new file mode 100644
index 0000000..235475f
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+import com.android.systemui.plugins.annotations.ProtectedInterface
+import com.android.systemui.plugins.annotations.ProtectedReturn
+import java.util.Locale
+import java.util.TimeZone
+
+/** Events that should call when various rendering parameters change */
+@ProtectedInterface
+interface ClockEvents {
+    @get:ProtectedReturn("return false;")
+    /** Set to enable or disable swipe interaction */
+    var isReactiveTouchInteractionEnabled: Boolean // TODO(b/364664388): Remove/Rename
+
+    /** Call whenever timezone changes */
+    fun onTimeZoneChanged(timeZone: TimeZone)
+
+    /** Call whenever the text time format changes (12hr vs 24hr) */
+    fun onTimeFormatChanged(is24Hr: Boolean)
+
+    /** Call whenever the locale changes */
+    fun onLocaleChanged(locale: Locale)
+
+    /** Call whenever the weather data should update */
+    fun onWeatherDataChanged(data: WeatherData)
+
+    /** Call with alarm information */
+    fun onAlarmDataChanged(data: AlarmData)
+
+    /** Call with zen/dnd information */
+    fun onZenDataChanged(data: ZenData)
+
+    /** Update reactive axes for this clock */
+    fun onFontAxesChanged(axes: List<ClockFontAxisSetting>)
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceController.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceController.kt
new file mode 100644
index 0000000..8a023f1
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceController.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+import android.view.View
+import com.android.systemui.plugins.annotations.ProtectedInterface
+import com.android.systemui.plugins.annotations.SimpleProperty
+
+/** Interface for a specific clock face version rendered by the clock */
+@ProtectedInterface
+interface ClockFaceController {
+    @get:SimpleProperty
+    @Deprecated("Prefer use of layout")
+    /** View that renders the clock face */
+    val view: View
+
+    @get:SimpleProperty
+    /** Layout specification for this clock */
+    val layout: ClockFaceLayout
+
+    @get:SimpleProperty
+    /** Determines the way the hosting app should behave when rendering this clock face */
+    val config: ClockFaceConfig
+
+    @get:SimpleProperty
+    /** Current theme information the clock is using */
+    val theme: ThemeConfig
+
+    @get:SimpleProperty
+    /** Events specific to this clock face */
+    val events: ClockFaceEvents
+
+    @get:SimpleProperty
+    /** Triggers for various animations */
+    val animations: ClockAnimations
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt
new file mode 100644
index 0000000..029e546
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+import android.graphics.Rect
+import com.android.systemui.plugins.annotations.ProtectedInterface
+
+/** Events that have specific data about the related face */
+@ProtectedInterface
+interface ClockFaceEvents {
+    /** Call every tick to update the rendered time */
+    fun onTimeTick()
+
+    /**
+     * Call whenever the theme or seedColor is updated
+     *
+     * Theme can be specific to the clock face.
+     * - isDarkTheme -> clock should be light
+     * - !isDarkTheme -> clock should be dark
+     */
+    fun onThemeChanged(theme: ThemeConfig)
+
+    /**
+     * Call whenever font settings change. Pass in a target font size in pixels. The specific clock
+     * design is allowed to ignore this target size on a case-by-case basis.
+     */
+    fun onFontSettingChanged(fontSizePx: Float)
+
+    /**
+     * Target region information for the clock face. For small clock, this will match the bounds of
+     * the parent view mostly, but have a target height based on the height of the default clock.
+     * For large clocks, the parent view is the entire device size, but most clocks will want to
+     * render within the centered targetRect to avoid obstructing other elements. The specified
+     * targetRegion is relative to the parent view.
+     */
+    fun onTargetRegionChanged(targetRegion: Rect?)
+
+    /** Called to notify the clock about its display. */
+    fun onSecondaryDisplayChanged(onSecondaryDisplay: Boolean)
+}
+
+/** Contains Theming information for the clock face */
+data class ThemeConfig(
+    /** True if the clock should use dark theme (light text on dark background) */
+    val isDarkTheme: Boolean,
+
+    /**
+     * A clock specific seed color to use when theming, if any was specified by the user. A null
+     * value denotes that we should use the seed color for the current system theme.
+     */
+    val seedColor: Int?,
+)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt
new file mode 100644
index 0000000..fb5ef02
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+import android.content.Context
+import android.util.DisplayMetrics
+import android.view.View
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
+import androidx.constraintlayout.widget.ConstraintSet.END
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
+import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT
+import com.android.internal.policy.SystemBarUtils
+import com.android.systemui.plugins.annotations.GeneratedImport
+import com.android.systemui.plugins.annotations.ProtectedInterface
+import com.android.systemui.plugins.annotations.ProtectedReturn
+
+/** Specifies layout information for the clock face */
+@ProtectedInterface
+@GeneratedImport("java.util.ArrayList")
+@GeneratedImport("android.view.View")
+interface ClockFaceLayout {
+    @get:ProtectedReturn("return new ArrayList<View>();")
+    /** All clock views to add to the root constraint layout before applying constraints. */
+    val views: List<View>
+
+    @ProtectedReturn("return constraints;")
+    /** Custom constraints to apply to Lockscreen ConstraintLayout. */
+    fun applyConstraints(constraints: ConstraintSet): ConstraintSet
+
+    @ProtectedReturn("return constraints;")
+    /** Custom constraints to apply to preview ConstraintLayout. */
+    fun applyPreviewConstraints(
+        clockPreviewConfig: ClockPreviewConfig,
+        constraints: ConstraintSet,
+    ): ConstraintSet
+
+    /** Apply specified AOD BurnIn parameters to this layout */
+    fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel)
+}
+
+/** Data class to contain AOD BurnIn information for correct aod rendering */
+data class AodClockBurnInModel(
+    /** Scale that the clock should render at to mitigate burnin */
+    val scale: Float,
+
+    /** X-Translation for the clock to mitigate burnin */
+    val translationX: Float,
+
+    /** Y-Translation for the clock to mitigate burnin */
+    val translationY: Float,
+)
+
+/** A ClockFaceLayout that applies the default lockscreen layout to a single view */
+class DefaultClockFaceLayout(val view: View) : ClockFaceLayout {
+    override val views = listOf(view)
+
+    override fun applyConstraints(constraints: ConstraintSet): ConstraintSet {
+        if (views.size != 1) {
+            throw IllegalArgumentException(
+                "Should have only one container view when using DefaultClockFaceLayout"
+            )
+        }
+        return constraints
+    }
+
+    override fun applyPreviewConstraints(
+        clockPreviewConfig: ClockPreviewConfig,
+        constraints: ConstraintSet,
+    ): ConstraintSet {
+        return applyDefaultPreviewConstraints(clockPreviewConfig, constraints)
+    }
+
+    override fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel) {
+        // Default clock doesn't need detailed control of view
+    }
+
+    companion object {
+        fun applyDefaultPreviewConstraints(
+            clockPreviewConfig: ClockPreviewConfig,
+            constraints: ConstraintSet,
+        ): ConstraintSet {
+            constraints.apply {
+                val context = clockPreviewConfig.previewContext
+                val lockscreenClockViewLargeId = getId(context, "lockscreen_clock_view_large")
+                constrainWidth(lockscreenClockViewLargeId, WRAP_CONTENT)
+                constrainHeight(lockscreenClockViewLargeId, WRAP_CONTENT)
+                constrainMaxHeight(lockscreenClockViewLargeId, 0)
+
+                val largeClockTopMargin =
+                    SystemBarUtils.getStatusBarHeight(context) +
+                        getDimen(context, "small_clock_padding_top") +
+                        getDimen(context, "keyguard_smartspace_top_offset") +
+                        getDimen(context, "date_weather_view_height") +
+                        getDimen(context, "enhanced_smartspace_height")
+                connect(lockscreenClockViewLargeId, TOP, PARENT_ID, TOP, largeClockTopMargin)
+                connect(lockscreenClockViewLargeId, START, PARENT_ID, START)
+                connect(lockscreenClockViewLargeId, END, PARENT_ID, END)
+
+                // In preview, we'll show UDFPS icon for UDFPS devices
+                // and nothing for non-UDFPS devices,
+                // and we're not planning to add this vide in clockHostView
+                // so we only need position of device entry icon to constrain clock
+                // Copied calculation codes from applyConstraints in DefaultDeviceEntrySection
+                val bottomPaddingPx = getDimen(context, "lock_icon_margin_bottom")
+                val defaultDensity =
+                    DisplayMetrics.DENSITY_DEVICE_STABLE.toFloat() /
+                        DisplayMetrics.DENSITY_DEFAULT.toFloat()
+                val lockIconRadiusPx = (defaultDensity * 36).toInt()
+                val clockBottomMargin = bottomPaddingPx + 2 * lockIconRadiusPx
+
+                connect(lockscreenClockViewLargeId, BOTTOM, PARENT_ID, BOTTOM, clockBottomMargin)
+                val smallClockViewId = getId(context, "lockscreen_clock_view")
+                constrainWidth(smallClockViewId, WRAP_CONTENT)
+                constrainHeight(smallClockViewId, getDimen(context, "small_clock_height"))
+                connect(
+                    smallClockViewId,
+                    START,
+                    PARENT_ID,
+                    START,
+                    getDimen(context, "clock_padding_start") +
+                        getDimen(context, "status_view_margin_horizontal"),
+                )
+                val smallClockTopMargin =
+                    getSmallClockTopPadding(
+                        clockPreviewConfig = clockPreviewConfig,
+                        SystemBarUtils.getStatusBarHeight(context),
+                    )
+                connect(smallClockViewId, TOP, PARENT_ID, TOP, smallClockTopMargin)
+            }
+            return constraints
+        }
+
+        fun getId(context: Context, name: String): Int {
+            val packageName = context.packageName
+            val res = context.packageManager.getResourcesForApplication(packageName)
+            val id = res.getIdentifier(name, "id", packageName)
+            return id
+        }
+
+        fun getDimen(context: Context, name: String): Int {
+            val packageName = context.packageName
+            val res = context.resources
+            val id = res.getIdentifier(name, "dimen", packageName)
+            return if (id == 0) 0 else res.getDimensionPixelSize(id)
+        }
+
+        fun getSmallClockTopPadding(
+            clockPreviewConfig: ClockPreviewConfig,
+            statusBarHeight: Int,
+        ): Int {
+            return if (clockPreviewConfig.isShadeLayoutWide) {
+                getDimen(clockPreviewConfig.previewContext, "keyguard_split_shade_top_margin") -
+                    if (clockPreviewConfig.isSceneContainerFlagEnabled) statusBarHeight else 0
+            } else {
+                getDimen(clockPreviewConfig.previewContext, "keyguard_clock_top_margin") +
+                    if (!clockPreviewConfig.isSceneContainerFlagEnabled) statusBarHeight else 0
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockMessageBuffers.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockMessageBuffers.kt
new file mode 100644
index 0000000..bec589a
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockMessageBuffers.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+import com.android.systemui.log.core.MessageBuffer
+
+/** MessageBuffers for clocks that want to log information to SystemUI dumps */
+data class ClockMessageBuffers(
+    /** Message buffer for general infrastructure */
+    val infraMessageBuffer: MessageBuffer,
+
+    /** Message buffer for small clock rendering */
+    val smallClockMessageBuffer: MessageBuffer,
+
+    /** Message buffer for large clock rendering */
+    val largeClockMessageBuffer: MessageBuffer,
+) {
+    constructor(buffer: MessageBuffer) : this(buffer, buffer, buffer) {}
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt
new file mode 100644
index 0000000..1bc9367
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+import android.graphics.drawable.Drawable
+
+data class ClockPickerConfig
+@JvmOverloads
+constructor(
+    val id: String,
+
+    /** Localized name of the clock */
+    val name: String,
+
+    /** Localized accessibility description for the clock */
+    val description: String,
+
+    /* Static & lightweight thumbnail version of the clock */
+    val thumbnail: Drawable,
+
+    /** True if the clock will react to tone changes in the seed color */
+    val isReactiveToTone: Boolean = true,
+
+    /** Font axes that can be modified on this clock */
+    val axes: List<ClockFontAxis> = listOf(),
+)
+
+/** Represents an Axis that can be modified */
+data class ClockFontAxis(
+    /** Axis key, not user renderable */
+    val key: String,
+
+    /** Intended mode of user interaction */
+    val type: AxisType,
+
+    /** Maximum value the axis supports */
+    val maxValue: Float,
+
+    /** Minimum value the axis supports */
+    val minValue: Float,
+
+    /** Current value the axis is set to */
+    val currentValue: Float,
+
+    /** User-renderable name of the axis */
+    val name: String,
+
+    /** Description of the axis */
+    val description: String,
+) {
+    fun toSetting() = ClockFontAxisSetting(key, currentValue)
+
+    companion object {
+        fun merge(
+            fontAxes: List<ClockFontAxis>,
+            axisSettings: List<ClockFontAxisSetting>,
+        ): List<ClockFontAxis> {
+            val result = mutableListOf<ClockFontAxis>()
+            for (axis in fontAxes) {
+                val setting = axisSettings.firstOrNull { axis.key == it.key }
+                val output = setting?.let { axis.copy(currentValue = it.value) } ?: axis
+                result.add(output)
+            }
+            return result
+        }
+    }
+}
+
+/** Axis user interaction modes */
+enum class AxisType {
+    /** Continuous range between minValue & maxValue. */
+    Float,
+
+    /** Only minValue & maxValue are valid. No intermediate values between them are allowed. */
+    Boolean,
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt
similarity index 72%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt
index 5a04169..544b705 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt
@@ -14,8 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.systemui.plugins.clocks
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+import android.content.Context
+
+data class ClockPreviewConfig(
+    val previewContext: Context,
+    val isShadeLayoutWide: Boolean,
+    val isSceneContainerFlagEnabled: Boolean = false,
+)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
index fb9e96c..7426f06 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
@@ -13,35 +13,11 @@
  */
 package com.android.systemui.plugins.clocks
 
-import android.content.Context
-import android.graphics.Rect
-import android.graphics.drawable.Drawable
-import android.util.DisplayMetrics
-import android.view.View
-import androidx.constraintlayout.widget.ConstraintSet
-import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
-import androidx.constraintlayout.widget.ConstraintSet.END
-import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
-import androidx.constraintlayout.widget.ConstraintSet.START
-import androidx.constraintlayout.widget.ConstraintSet.TOP
-import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT
-import com.android.internal.annotations.Keep
-import com.android.internal.policy.SystemBarUtils
-import com.android.systemui.log.core.MessageBuffer
 import com.android.systemui.plugins.Plugin
 import com.android.systemui.plugins.annotations.GeneratedImport
 import com.android.systemui.plugins.annotations.ProtectedInterface
 import com.android.systemui.plugins.annotations.ProtectedReturn
 import com.android.systemui.plugins.annotations.ProvidesInterface
-import com.android.systemui.plugins.annotations.SimpleProperty
-import java.io.PrintWriter
-import java.util.Locale
-import java.util.TimeZone
-import org.json.JSONArray
-import org.json.JSONObject
-
-/** Identifies a clock design */
-typealias ClockId = String
 
 /** A Plugin which exposes the ClockProvider interface */
 @ProtectedInterface
@@ -74,509 +50,8 @@
     fun getClockPickerConfig(settings: ClockSettings): ClockPickerConfig
 }
 
-/** Interface for controlling an active clock */
-@ProtectedInterface
-interface ClockController {
-    @get:SimpleProperty
-    /** A small version of the clock, appropriate for smaller viewports */
-    val smallClock: ClockFaceController
-
-    @get:SimpleProperty
-    /** A large version of the clock, appropriate when a bigger viewport is available */
-    val largeClock: ClockFaceController
-
-    @get:SimpleProperty
-    /** Determines the way the hosting app should behave when rendering either clock face */
-    val config: ClockConfig
-
-    @get:SimpleProperty
-    /** Events that clocks may need to respond to */
-    val events: ClockEvents
-
-    /** Initializes various rendering parameters. If never called, provides reasonable defaults. */
-    fun initialize(isDarkTheme: Boolean, dozeFraction: Float, foldFraction: Float)
-
-    /** Optional method for dumping debug information */
-    fun dump(pw: PrintWriter)
-}
-
-/** Interface for a specific clock face version rendered by the clock */
-@ProtectedInterface
-interface ClockFaceController {
-    @get:SimpleProperty
-    @Deprecated("Prefer use of layout")
-    /** View that renders the clock face */
-    val view: View
-
-    @get:SimpleProperty
-    /** Layout specification for this clock */
-    val layout: ClockFaceLayout
-
-    @get:SimpleProperty
-    /** Determines the way the hosting app should behave when rendering this clock face */
-    val config: ClockFaceConfig
-
-    @get:SimpleProperty
-    /** Current theme information the clock is using */
-    val theme: ThemeConfig
-
-    @get:SimpleProperty
-    /** Events specific to this clock face */
-    val events: ClockFaceEvents
-
-    @get:SimpleProperty
-    /** Triggers for various animations */
-    val animations: ClockAnimations
-}
-
-/** For clocks that want to report debug information */
-data class ClockMessageBuffers(
-    /** Message buffer for general infra */
-    val infraMessageBuffer: MessageBuffer,
-
-    /** Message buffer for small clock renering */
-    val smallClockMessageBuffer: MessageBuffer,
-
-    /** Message buffer for large clock rendering */
-    val largeClockMessageBuffer: MessageBuffer,
-) {
-    constructor(buffer: MessageBuffer) : this(buffer, buffer, buffer) {}
-}
-
-data class AodClockBurnInModel(val scale: Float, val translationX: Float, val translationY: Float)
-
-/** Specifies layout information for the clock face */
-@ProtectedInterface
-@GeneratedImport("java.util.ArrayList")
-@GeneratedImport("android.view.View")
-interface ClockFaceLayout {
-    @get:ProtectedReturn("return new ArrayList<View>();")
-    /** All clock views to add to the root constraint layout before applying constraints. */
-    val views: List<View>
-
-    @ProtectedReturn("return constraints;")
-    /** Custom constraints to apply to Lockscreen ConstraintLayout. */
-    fun applyConstraints(constraints: ConstraintSet): ConstraintSet
-
-    @ProtectedReturn("return constraints;")
-    /** Custom constraints to apply to preview ConstraintLayout. */
-    fun applyPreviewConstraints(context: Context, constraints: ConstraintSet): ConstraintSet
-
-    fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel)
-}
-
-/** A ClockFaceLayout that applies the default lockscreen layout to a single view */
-class DefaultClockFaceLayout(val view: View) : ClockFaceLayout {
-    // both small and large clock should have a container (RelativeLayout in
-    // SimpleClockFaceController)
-    override val views = listOf(view)
-
-    override fun applyConstraints(constraints: ConstraintSet): ConstraintSet {
-        if (views.size != 1) {
-            throw IllegalArgumentException(
-                "Should have only one container view when using DefaultClockFaceLayout"
-            )
-        }
-        return constraints
-    }
-
-    override fun applyPreviewConstraints(
-        context: Context,
-        constraints: ConstraintSet,
-    ): ConstraintSet {
-        return applyDefaultPreviewConstraints(context, constraints)
-    }
-
-    override fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel) {
-        // Default clock doesn't need detailed control of view
-    }
-
-    companion object {
-        fun applyDefaultPreviewConstraints(
-            context: Context,
-            constraints: ConstraintSet,
-        ): ConstraintSet {
-            constraints.apply {
-                val lockscreenClockViewLargeId = getId(context, "lockscreen_clock_view_large")
-                constrainWidth(lockscreenClockViewLargeId, WRAP_CONTENT)
-                constrainHeight(lockscreenClockViewLargeId, WRAP_CONTENT)
-                constrainMaxHeight(lockscreenClockViewLargeId, 0)
-
-                val largeClockTopMargin =
-                    SystemBarUtils.getStatusBarHeight(context) +
-                        getDimen(context, "small_clock_padding_top") +
-                        getDimen(context, "keyguard_smartspace_top_offset") +
-                        getDimen(context, "date_weather_view_height") +
-                        getDimen(context, "enhanced_smartspace_height")
-                connect(lockscreenClockViewLargeId, TOP, PARENT_ID, TOP, largeClockTopMargin)
-                connect(lockscreenClockViewLargeId, START, PARENT_ID, START)
-                connect(lockscreenClockViewLargeId, END, PARENT_ID, END)
-
-                // In preview, we'll show UDFPS icon for UDFPS devices
-                // and nothing for non-UDFPS devices,
-                // and we're not planning to add this vide in clockHostView
-                // so we only need position of device entry icon to constrain clock
-                // Copied calculation codes from applyConstraints in DefaultDeviceEntrySection
-                val bottomPaddingPx = getDimen(context, "lock_icon_margin_bottom")
-                val defaultDensity =
-                    DisplayMetrics.DENSITY_DEVICE_STABLE.toFloat() /
-                        DisplayMetrics.DENSITY_DEFAULT.toFloat()
-                val lockIconRadiusPx = (defaultDensity * 36).toInt()
-                val clockBottomMargin = bottomPaddingPx + 2 * lockIconRadiusPx
-
-                connect(lockscreenClockViewLargeId, BOTTOM, PARENT_ID, BOTTOM, clockBottomMargin)
-                val smallClockViewId = getId(context, "lockscreen_clock_view")
-                constrainWidth(smallClockViewId, WRAP_CONTENT)
-                constrainHeight(smallClockViewId, getDimen(context, "small_clock_height"))
-                connect(
-                    smallClockViewId,
-                    START,
-                    PARENT_ID,
-                    START,
-                    getDimen(context, "clock_padding_start") +
-                        getDimen(context, "status_view_margin_horizontal"),
-                )
-                val smallClockTopMargin =
-                    getDimen(context, "keyguard_clock_top_margin") +
-                        SystemBarUtils.getStatusBarHeight(context)
-                connect(smallClockViewId, TOP, PARENT_ID, TOP, smallClockTopMargin)
-            }
-            return constraints
-        }
-
-        fun getId(context: Context, name: String): Int {
-            val packageName = context.packageName
-            val res = context.packageManager.getResourcesForApplication(packageName)
-            val id = res.getIdentifier(name, "id", packageName)
-            return id
-        }
-
-        fun getDimen(context: Context, name: String): Int {
-            val packageName = context.packageName
-            val res = context.packageManager.getResourcesForApplication(packageName)
-            val id = res.getIdentifier(name, "dimen", packageName)
-            return if (id == 0) 0 else res.getDimensionPixelSize(id)
-        }
-    }
-}
-
-/** Events that should call when various rendering parameters change */
-@ProtectedInterface
-interface ClockEvents {
-    @get:ProtectedReturn("return false;")
-    /** Set to enable or disable swipe interaction */
-    var isReactiveTouchInteractionEnabled: Boolean // TODO(b/364664388): Remove/Rename
-
-    /** Call whenever timezone changes */
-    fun onTimeZoneChanged(timeZone: TimeZone)
-
-    /** Call whenever the text time format changes (12hr vs 24hr) */
-    fun onTimeFormatChanged(is24Hr: Boolean)
-
-    /** Call whenever the locale changes */
-    fun onLocaleChanged(locale: Locale)
-
-    /** Call whenever the weather data should update */
-    fun onWeatherDataChanged(data: WeatherData)
-
-    /** Call with alarm information */
-    fun onAlarmDataChanged(data: AlarmData)
-
-    /** Call with zen/dnd information */
-    fun onZenDataChanged(data: ZenData)
-
-    /** Update reactive axes for this clock */
-    fun onFontAxesChanged(axes: List<ClockFontAxisSetting>)
-}
-
-/** Axis setting value for a clock */
-data class ClockFontAxisSetting(
-    /** Axis key; matches ClockFontAxis.key */
-    val key: String,
-
-    /** Value to set this axis to */
-    val value: Float,
-) {
-    companion object {
-        private val KEY_AXIS_KEY = "key"
-        private val KEY_AXIS_VALUE = "value"
-
-        fun toJson(setting: ClockFontAxisSetting): JSONObject {
-            return JSONObject().apply {
-                put(KEY_AXIS_KEY, setting.key)
-                put(KEY_AXIS_VALUE, setting.value)
-            }
-        }
-
-        fun toJson(settings: List<ClockFontAxisSetting>): JSONArray {
-            return JSONArray().apply {
-                for (axis in settings) {
-                    put(toJson(axis))
-                }
-            }
-        }
-
-        fun fromJson(jsonObj: JSONObject): ClockFontAxisSetting {
-            return ClockFontAxisSetting(
-                key = jsonObj.getString(KEY_AXIS_KEY),
-                value = jsonObj.getDouble(KEY_AXIS_VALUE).toFloat(),
-            )
-        }
-
-        fun fromJson(jsonArray: JSONArray): List<ClockFontAxisSetting> {
-            val result = mutableListOf<ClockFontAxisSetting>()
-            for (i in 0..jsonArray.length() - 1) {
-                val obj = jsonArray.getJSONObject(i)
-                if (obj == null) continue
-                result.add(fromJson(obj))
-            }
-            return result
-        }
-
-        fun toFVar(settings: List<ClockFontAxisSetting>): String {
-            val sb = StringBuilder()
-            for (axis in settings) {
-                if (sb.length > 0) sb.append(", ")
-                sb.append("'${axis.key}' ${axis.value.toInt()}")
-            }
-            return sb.toString()
-        }
-    }
-}
-
-/** Methods which trigger various clock animations */
-@ProtectedInterface
-interface ClockAnimations {
-    /** Runs an enter animation (if any) */
-    fun enter()
-
-    /** Sets how far into AOD the device currently is. */
-    fun doze(fraction: Float)
-
-    /** Sets how far into the folding animation the device is. */
-    fun fold(fraction: Float)
-
-    /** Runs the battery animation (if any). */
-    fun charge()
-
-    /**
-     * Runs when the clock's position changed during the move animation.
-     *
-     * @param fromLeft the [View.getLeft] position of the clock, before it started moving.
-     * @param direction the direction in which it is moving. A positive number means right, and
-     *   negative means left.
-     * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
-     *   it finished moving.
-     * @deprecated use {@link #onPositionUpdated(float, float)} instead.
-     */
-    fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float)
-
-    /**
-     * Runs when the clock's position changed during the move animation.
-     *
-     * @param distance is the total distance in pixels to offset the glyphs when animation
-     *   completes. Negative distance means we are animating the position towards the center.
-     * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
-     *   it finished moving.
-     */
-    fun onPositionUpdated(distance: Float, fraction: Float)
-
-    /**
-     * Runs when swiping clock picker, swipingFraction: 1.0 -> clock is scaled up in the preview,
-     * 0.0 -> clock is scaled down in the shade; previewRatio is previewSize / screenSize
-     */
-    fun onPickerCarouselSwiping(swipingFraction: Float)
-}
-
-/** Events that have specific data about the related face */
-@ProtectedInterface
-interface ClockFaceEvents {
-    /** Call every time tick */
-    fun onTimeTick()
-
-    /**
-     * Call whenever the theme or seedColor is updated
-     *
-     * Theme can be specific to the clock face.
-     * - isDarkTheme -> clock should be light
-     * - !isDarkTheme -> clock should be dark
-     */
-    fun onThemeChanged(theme: ThemeConfig)
-
-    /**
-     * Call whenever font settings change. Pass in a target font size in pixels. The specific clock
-     * design is allowed to ignore this target size on a case-by-case basis.
-     */
-    fun onFontSettingChanged(fontSizePx: Float)
-
-    /**
-     * Target region information for the clock face. For small clock, this will match the bounds of
-     * the parent view mostly, but have a target height based on the height of the default clock.
-     * For large clocks, the parent view is the entire device size, but most clocks will want to
-     * render within the centered targetRect to avoid obstructing other elements. The specified
-     * targetRegion is relative to the parent view.
-     */
-    fun onTargetRegionChanged(targetRegion: Rect?)
-
-    /** Called to notify the clock about its display. */
-    fun onSecondaryDisplayChanged(onSecondaryDisplay: Boolean)
-}
-
-data class ThemeConfig(val isDarkTheme: Boolean, val seedColor: Int?)
-
-/** Tick rates for clocks */
-enum class ClockTickRate(val value: Int) {
-    PER_MINUTE(2), // Update the clock once per minute.
-    PER_SECOND(1), // Update the clock once per second.
-    PER_FRAME(0), // Update the clock every second.
-}
+/** Identifies a clock design */
+typealias ClockId = String
 
 /** Some data about a clock design */
 data class ClockMetadata(val clockId: ClockId)
-
-data class ClockPickerConfig
-@JvmOverloads
-constructor(
-    val id: String,
-
-    /** Localized name of the clock */
-    val name: String,
-
-    /** Localized accessibility description for the clock */
-    val description: String,
-
-    /* Static & lightweight thumbnail version of the clock */
-    val thumbnail: Drawable,
-
-    /** True if the clock will react to tone changes in the seed color */
-    val isReactiveToTone: Boolean = true,
-
-    /** Font axes that can be modified on this clock */
-    val axes: List<ClockFontAxis> = listOf(),
-)
-
-/** Represents an Axis that can be modified */
-data class ClockFontAxis(
-    /** Axis key, not user renderable */
-    val key: String,
-
-    /** Intended mode of user interaction */
-    val type: AxisType,
-
-    /** Maximum value the axis supports */
-    val maxValue: Float,
-
-    /** Minimum value the axis supports */
-    val minValue: Float,
-
-    /** Current value the axis is set to */
-    val currentValue: Float,
-
-    /** User-renderable name of the axis */
-    val name: String,
-
-    /** Description of the axis */
-    val description: String,
-) {
-    fun toSetting() = ClockFontAxisSetting(key, currentValue)
-
-    companion object {
-        fun merge(
-            fontAxes: List<ClockFontAxis>,
-            axisSettings: List<ClockFontAxisSetting>,
-        ): List<ClockFontAxis> {
-            val result = mutableListOf<ClockFontAxis>()
-            for (axis in fontAxes) {
-                val setting = axisSettings.firstOrNull { axis.key == it.key }
-                val output = setting?.let { axis.copy(currentValue = it.value) } ?: axis
-                result.add(output)
-            }
-            return result
-        }
-    }
-}
-
-/** Axis user interaction modes */
-enum class AxisType {
-    /** Continuous range between minValue & maxValue. */
-    Float,
-
-    /** Only minValue & maxValue are valid. No intermediate values between them are allowed. */
-    Boolean,
-}
-
-/** Render configuration for the full clock. Modifies the way systemUI behaves with this clock. */
-data class ClockConfig(
-    val id: String,
-
-    /** Localized name of the clock */
-    val name: String,
-
-    /** Localized accessibility description for the clock */
-    val description: String,
-
-    /** Transition to AOD should move smartspace like large clock instead of small clock */
-    val useAlternateSmartspaceAODTransition: Boolean = false,
-
-    /** Deprecated version of isReactiveToTone; moved to ClockPickerConfig */
-    @Deprecated("TODO(b/352049256): Remove in favor of ClockPickerConfig.isReactiveToTone")
-    val isReactiveToTone: Boolean = true,
-
-    /** True if the clock is large frame clock, which will use weather in compose. */
-    val useCustomClockScene: Boolean = false,
-)
-
-/** Render configuration options for a clock face. Modifies the way SystemUI behaves. */
-data class ClockFaceConfig(
-    /** Expected interval between calls to onTimeTick. Can always reduce to PER_MINUTE in AOD. */
-    val tickRate: ClockTickRate = ClockTickRate.PER_MINUTE,
-
-    /** Call to check whether the clock consumes weather data */
-    val hasCustomWeatherDataDisplay: Boolean = false,
-
-    /**
-     * Whether this clock has a custom position update animation. If true, the keyguard will call
-     * `onPositionUpdated` to notify the clock of a position update animation. If false, a default
-     * animation will be used (e.g. a simple translation).
-     */
-    val hasCustomPositionUpdatedAnimation: Boolean = false,
-
-    /** True if the clock is large frame clock, which will use weatherBlueprint in compose. */
-    val useCustomClockScene: Boolean = false,
-)
-
-/** Structure for keeping clock-specific settings */
-@Keep
-data class ClockSettings(
-    val clockId: ClockId? = null,
-    val seedColor: Int? = null,
-    val axes: List<ClockFontAxisSetting> = listOf(),
-) {
-    // Exclude metadata from equality checks
-    var metadata: JSONObject = JSONObject()
-
-    companion object {
-        private val KEY_CLOCK_ID = "clockId"
-        private val KEY_SEED_COLOR = "seedColor"
-        private val KEY_METADATA = "metadata"
-        private val KEY_AXIS_LIST = "axes"
-
-        fun toJson(setting: ClockSettings): JSONObject {
-            return JSONObject().apply {
-                put(KEY_CLOCK_ID, setting.clockId)
-                put(KEY_SEED_COLOR, setting.seedColor)
-                put(KEY_METADATA, setting.metadata)
-                put(KEY_AXIS_LIST, ClockFontAxisSetting.toJson(setting.axes))
-            }
-        }
-
-        fun fromJson(json: JSONObject): ClockSettings {
-            val clockId = if (!json.isNull(KEY_CLOCK_ID)) json.getString(KEY_CLOCK_ID) else null
-            val seedColor = if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
-            val axisList = json.optJSONArray(KEY_AXIS_LIST)?.let(ClockFontAxisSetting::fromJson)
-            return ClockSettings(clockId, seedColor, axisList ?: listOf()).apply {
-                metadata = json.optJSONObject(KEY_METADATA) ?: JSONObject()
-            }
-        }
-    }
-}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
new file mode 100644
index 0000000..6128c00
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+import com.android.internal.annotations.Keep
+import org.json.JSONArray
+import org.json.JSONObject
+
+@Keep
+/** Structure for keeping clock-specific settings */
+data class ClockSettings(
+    val clockId: ClockId? = null,
+    val seedColor: Int? = null,
+    val axes: List<ClockFontAxisSetting> = listOf(),
+) {
+    // Exclude metadata from equality checks
+    var metadata: JSONObject = JSONObject()
+
+    companion object {
+        private val KEY_CLOCK_ID = "clockId"
+        private val KEY_SEED_COLOR = "seedColor"
+        private val KEY_METADATA = "metadata"
+        private val KEY_AXIS_LIST = "axes"
+
+        fun toJson(setting: ClockSettings): JSONObject {
+            return JSONObject().apply {
+                put(KEY_CLOCK_ID, setting.clockId)
+                put(KEY_SEED_COLOR, setting.seedColor)
+                put(KEY_METADATA, setting.metadata)
+                put(KEY_AXIS_LIST, ClockFontAxisSetting.toJson(setting.axes))
+            }
+        }
+
+        fun fromJson(json: JSONObject): ClockSettings {
+            val clockId = if (!json.isNull(KEY_CLOCK_ID)) json.getString(KEY_CLOCK_ID) else null
+            val seedColor = if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
+            val axisList = json.optJSONArray(KEY_AXIS_LIST)?.let(ClockFontAxisSetting::fromJson)
+            return ClockSettings(clockId, seedColor, axisList ?: listOf()).apply {
+                metadata = json.optJSONObject(KEY_METADATA) ?: JSONObject()
+            }
+        }
+    }
+}
+
+@Keep
+/** Axis setting value for a clock */
+data class ClockFontAxisSetting(
+    /** Axis key; matches ClockFontAxis.key */
+    val key: String,
+
+    /** Value to set this axis to */
+    val value: Float,
+) {
+    companion object {
+        private val KEY_AXIS_KEY = "key"
+        private val KEY_AXIS_VALUE = "value"
+
+        fun toJson(setting: ClockFontAxisSetting): JSONObject {
+            return JSONObject().apply {
+                put(KEY_AXIS_KEY, setting.key)
+                put(KEY_AXIS_VALUE, setting.value)
+            }
+        }
+
+        fun toJson(settings: List<ClockFontAxisSetting>): JSONArray {
+            return JSONArray().apply {
+                for (axis in settings) {
+                    put(toJson(axis))
+                }
+            }
+        }
+
+        fun fromJson(jsonObj: JSONObject): ClockFontAxisSetting {
+            return ClockFontAxisSetting(
+                key = jsonObj.getString(KEY_AXIS_KEY),
+                value = jsonObj.getDouble(KEY_AXIS_VALUE).toFloat(),
+            )
+        }
+
+        fun fromJson(jsonArray: JSONArray): List<ClockFontAxisSetting> {
+            val result = mutableListOf<ClockFontAxisSetting>()
+            for (i in 0..jsonArray.length() - 1) {
+                val obj = jsonArray.getJSONObject(i)
+                if (obj == null) continue
+                result.add(fromJson(obj))
+            }
+            return result
+        }
+
+        fun toFVar(settings: List<ClockFontAxisSetting>): String {
+            val sb = StringBuilder()
+            for (axis in settings) {
+                if (sb.length > 0) sb.append(", ")
+                sb.append("'${axis.key}' ${axis.value.toInt()}")
+            }
+            return sb.toString()
+        }
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 73626b4..e3cbd66 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -120,6 +120,11 @@
      */
     boolean isListening();
 
+    /**
+     * Return this tile's {@link TileDetailsViewModel} to be used to render the TileDetailsView.
+     */
+    default TileDetailsViewModel getDetailsViewModel() { return null; }
+
     @ProvidesInterface(version = Callback.VERSION)
     interface Callback {
         static final int VERSION = 2;
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/TileDetailsViewModel.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/TileDetailsViewModel.kt
new file mode 100644
index 0000000..eab7d79
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/TileDetailsViewModel.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins.qs
+
+import androidx.compose.runtime.Composable
+
+/**
+ * The base view model class for rendering the Tile's TileDetailsView.
+ */
+abstract class TileDetailsViewModel {
+
+    // The view content of this tile details view.
+    @Composable
+    abstract fun GetContentView()
+
+    // The callback when the settings button is clicked. Currently this is the same as the on tile
+    // long press callback
+    abstract fun clickOnSettingsButton()
+
+    abstract fun getTitle(): String
+
+    abstract fun getSubTitle(): String
+}
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index d069c01..fe9036b 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -65,7 +65,7 @@
     <string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"‏يجب إدخال رقم PIN لأنّك أجريت محاولات كثيرة جدًا."</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">"‏افتح برقم PIN أو البصمة."</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>
     <string name="kg_prompt_after_dpm_lock" msgid="6002804765868345917">"لمزيد من الأمان، تم قفل الجهاز وفقًا لسياسة العمل."</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index 5ae41fe..e7116d6 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -65,7 +65,7 @@
     <string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"Se requiere PIN luego de demasiados intentos"</string>
     <string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"Se requiere contraseña luego de demasiados intentos"</string>
     <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"Se requiere patrón luego de demasiados intentos"</string>
-    <string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"Desbloq. PIN/huella"</string>
+    <string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"Desbloquear con PIN o huella dactilar"</string>
     <string name="kg_unlock_with_password_or_fp" msgid="2251295907826814237">"Desbloq. contraseña/huella"</string>
     <string name="kg_unlock_with_pattern_or_fp" msgid="2391870539909135046">"Desbloq. patrón/huella"</string>
     <string name="kg_prompt_after_dpm_lock" msgid="6002804765868345917">"Dispositivo bloqueado con la política del trabajo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 83a607b..41c3e06 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -42,7 +42,7 @@
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIMa PUKaren bidez desblokeatu behar da."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIMa desblokeatzen…"</string>
     <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"PIN kodearen eremua"</string>
-    <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Gailuko pasahitza"</string>
+    <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Gailuaren pasahitza"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"SIM txartelaren PIN kodearen eremua"</string>
     <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"SIM txartelaren PUK kodearen eremua"</string>
     <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Ezabatu"</string>
diff --git a/packages/SystemUI/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml
index 4a66968..fd4d47b 100644
--- a/packages/SystemUI/res-product/values-or/strings.xml
+++ b/packages/SystemUI/res-product/values-or/strings.xml
@@ -32,7 +32,7 @@
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"ଆପଣ ଫୋନ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଫୋନ୍‌ଟି ରିସେଟ୍ କରିଦିଆଯିବ, ଫଳରେ ଏହାର ସମସ୍ତ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
     <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଭୁଲ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜର ପ୍ରୋଫାଇଲ୍କୁ କାଢ଼ି ଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
     <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"ଆପଣ ଫୋନକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଭୁଲ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜର ପ୍ରୋଫାଇଲକୁ କାଢ଼ି ଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ୟୁଜରଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ୟୁଜରଙ୍କୁ କାଢ଼ି ଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
     <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"ଆପଣ ଫୋନକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ୟୁଜରଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଦ୍ୱାରା ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହେବ।"</string>
     <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"ଆପଣ ଟାବ୍‌ଲେଟ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍‌କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
     <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"ଆପଣ ଫୋନ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍‌କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
diff --git a/packages/SystemUI/res/drawable/ic_widgets.xml b/packages/SystemUI/res/drawable/ic_widgets.xml
new file mode 100644
index 0000000..9e05809
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_widgets.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="?attr/colorControlNormal"
+    android:viewportHeight="960"
+    android:viewportWidth="960">
+    <path
+        android:fillColor="@android:color/black"
+        android:pathData="M666,520L440,294L666,68L892,294L666,520ZM120,440L120,120L440,120L440,440L120,440ZM520,840L520,520L840,520L840,840L520,840ZM120,840L120,520L440,520L440,840L120,840ZM200,360L360,360L360,200L200,200L200,360ZM667,408L780,295L667,182L554,295L667,408ZM600,760L760,760L760,600L600,600L600,760ZM200,760L360,760L360,600L200,600L200,760ZM360,360L360,360L360,360L360,360L360,360ZM554,295L554,295L554,295L554,295L554,295ZM360,600L360,600L360,600L360,600L360,600ZM600,600L600,600L600,600L600,600L600,600Z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/volume_background_top_legacy.xml b/packages/SystemUI/res/drawable/volume_background_top_legacy.xml
index 3cd87fc..58ae150 100644
--- a/packages/SystemUI/res/drawable/volume_background_top_legacy.xml
+++ b/packages/SystemUI/res/drawable/volume_background_top_legacy.xml
@@ -16,7 +16,7 @@
   -->
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <item>
+    <item android:gravity="bottom|end">
         <shape>
             <size android:width="@dimen/volume_dialog_panel_width" />
             <solid android:color="?androidprv:attr/colorSurface" />
diff --git a/packages/SystemUI/res/layout/audio_sharing_dialog.xml b/packages/SystemUI/res/layout/audio_sharing_dialog.xml
index 7534e15..014b7f7 100644
--- a/packages/SystemUI/res/layout/audio_sharing_dialog.xml
+++ b/packages/SystemUI/res/layout/audio_sharing_dialog.xml
@@ -84,7 +84,7 @@
         android:id="@+id/share_audio_button"
         style="@style/SettingsLibActionButton"
         android:textColor="?androidprv:attr/textColorOnAccent"
-        android:background="@drawable/audio_sharing_rounded_bg_ripple"
+        android:background="@drawable/audio_sharing_rounded_bg_ripple_top"
         android:layout_marginBottom="4dp"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
@@ -101,7 +101,7 @@
         android:id="@+id/switch_active_button"
         style="@style/SettingsLibActionButton"
         android:textColor="?androidprv:attr/textColorOnAccent"
-        android:background="@drawable/audio_sharing_rounded_bg_ripple"
+        android:background="@drawable/audio_sharing_rounded_bg_ripple_bottom"
         android:layout_marginBottom="20dp"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/bundle_notification_info.xml b/packages/SystemUI/res/layout/bundle_notification_info.xml
new file mode 100644
index 0000000..8700832
--- /dev/null
+++ b/packages/SystemUI/res/layout/bundle_notification_info.xml
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright 2024, The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<com.android.systemui.statusbar.notification.row.BundleNotificationInfo
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:id="@+id/notification_guts"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:focusable="true"
+    android:clipChildren="false"
+    android:clipToPadding="true"
+    android:orientation="vertical"
+    android:paddingStart="@dimen/notification_shade_content_margin_horizontal">
+
+    <!-- Package Info -->
+    <LinearLayout
+        android:id="@+id/header"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:clipChildren="false"
+        android:paddingTop="@dimen/notification_guts_header_top_padding"
+        android:clipToPadding="true">
+        <ImageView
+            android:id="@+id/pkg_icon"
+            android:layout_width="@dimen/notification_guts_conversation_icon_size"
+            android:layout_height="@dimen/notification_guts_conversation_icon_size"
+            android:layout_centerVertical="true"
+            android:layout_alignParentStart="true"
+            android:layout_marginEnd="15dp" />
+        <LinearLayout
+            android:id="@+id/names"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:orientation="vertical"
+            android:layout_height="wrap_content"
+            android:minHeight="@dimen/notification_guts_conversation_icon_size"
+            android:layout_centerVertical="true"
+            android:gravity="center_vertical"
+            android:layout_alignEnd="@id/pkg_icon"
+            android:layout_toEndOf="@id/pkg_icon">
+            <TextView
+                android:id="@+id/channel_name"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textDirection="locale"
+                style="@style/TextAppearance.NotificationImportanceChannel"/>
+            <TextView
+                android:id="@+id/group_name"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textDirection="locale"
+                android:ellipsize="end"
+                style="@style/TextAppearance.NotificationImportanceChannelGroup"/>
+            <TextView
+                android:id="@+id/pkg_name"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                style="@style/TextAppearance.NotificationImportanceApp"
+                android:ellipsize="end"
+                android:textDirection="locale"
+                android:maxLines="1"/>
+            <TextView
+                android:id="@+id/delegate_name"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                style="@style/TextAppearance.NotificationImportanceHeader"
+                android:layout_marginStart="2dp"
+                android:layout_marginEnd="2dp"
+                android:ellipsize="end"
+                android:textDirection="locale"
+                android:text="@string/notification_delegate_header"
+                android:maxLines="1" />
+
+        </LinearLayout>
+
+        <!-- end aligned fields -->
+        <!-- Optional link to app. Only appears if the channel is not disabled and the app
+asked for it -->
+        <ImageButton
+            android:id="@+id/app_settings"
+            android:layout_width="@dimen/notification_importance_toggle_size"
+            android:layout_height="@dimen/notification_importance_toggle_size"
+            android:layout_centerVertical="true"
+            android:visibility="gone"
+            android:background="@drawable/ripple_drawable"
+            android:contentDescription="@string/notification_app_settings"
+            android:src="@drawable/ic_info"
+            android:layout_toStartOf="@id/info"
+            android:tint="?androidprv:attr/materialColorPrimary"/>
+        <ImageButton
+            android:id="@+id/info"
+            android:layout_width="@dimen/notification_importance_toggle_size"
+            android:layout_height="@dimen/notification_importance_toggle_size"
+            android:layout_centerVertical="true"
+            android:contentDescription="@string/notification_more_settings"
+            android:background="@drawable/ripple_drawable_20dp"
+            android:src="@drawable/ic_settings"
+            android:tint="?androidprv:attr/materialColorPrimary"
+            android:layout_alignParentEnd="true" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/inline_controls"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="@dimen/notification_shade_content_margin_horizontal"
+        android:layout_marginTop="@dimen/notification_guts_option_vertical_padding"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:orientation="vertical">
+
+        <!-- Non configurable app/channel text. appears instead of @+id/interruptiveness_settings-->
+        <TextView
+            android:id="@+id/non_configurable_text"
+            android:text="@string/notification_unblockable_desc"
+            android:visibility="gone"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            style="@*android:style/TextAppearance.DeviceDefault.Notification" />
+
+        <!-- Non configurable app/channel text. appears instead of @+id/interruptiveness_settings-->
+        <TextView
+            android:id="@+id/non_configurable_call_text"
+            android:text="@string/notification_unblockable_call_desc"
+            android:visibility="gone"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            style="@*android:style/TextAppearance.DeviceDefault.Notification" />
+
+        <!-- Non configurable multichannel text. appears instead of @+id/interruptiveness_settings-->
+        <TextView
+            android:id="@+id/non_configurable_multichannel_text"
+            android:text="@string/notification_multichannel_desc"
+            android:visibility="gone"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            style="@*android:style/TextAppearance.DeviceDefault.Notification" />
+
+        <LinearLayout
+            android:id="@+id/interruptiveness_settings"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:orientation="vertical">
+            <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+                android:id="@+id/automatic"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginBottom="@dimen/notification_importance_button_separation"
+                android:padding="@dimen/notification_importance_button_padding"
+                android:clickable="true"
+                android:focusable="true"
+                android:background="@drawable/notification_guts_priority_button_bg"
+                android:orientation="vertical"
+                android:visibility="gone">
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="center"
+                    >
+                    <ImageView
+                        android:id="@+id/automatic_icon"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:src="@drawable/ic_notifications_automatic"
+                        android:background="@android:color/transparent"
+                        android:tint="@color/notification_guts_priority_contents"
+                        android:clickable="false"
+                        android:focusable="false"/>
+                    <TextView
+                        android:id="@+id/automatic_label"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="@dimen/notification_importance_drawable_padding"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:maxLines="1"
+                        android:clickable="false"
+                        android:focusable="false"
+                        android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
+                        android:text="@string/notification_automatic_title"/>
+                </LinearLayout>
+                <TextView
+                    android:id="@+id/automatic_summary"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
+                    android:visibility="gone"
+                    android:text="@string/notification_channel_summary_automatic"
+                    android:clickable="false"
+                    android:focusable="false"
+                    android:ellipsize="end"
+                    android:maxLines="2"
+                    android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
+            </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
+
+            <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+                android:id="@+id/alert"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="@dimen/notification_importance_button_padding"
+                android:clickable="true"
+                android:focusable="true"
+                android:background="@drawable/notification_guts_priority_button_bg"
+                android:orientation="vertical">
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="center"
+                    >
+                    <ImageView
+                        android:id="@+id/alert_icon"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:src="@drawable/ic_notifications_alert"
+                        android:background="@android:color/transparent"
+                        android:tint="@color/notification_guts_priority_contents"
+                        android:clickable="false"
+                        android:focusable="false"/>
+                    <TextView
+                        android:id="@+id/alert_label"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="@dimen/notification_importance_drawable_padding"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:maxLines="1"
+                        android:clickable="false"
+                        android:focusable="false"
+                        android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
+                        android:text="@string/notification_alert_title"/>
+                </LinearLayout>
+                <TextView
+                    android:id="@+id/alert_summary"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
+                    android:visibility="gone"
+                    android:text="@string/notification_channel_summary_default"
+                    android:clickable="false"
+                    android:focusable="false"
+                    android:ellipsize="end"
+                    android:maxLines="2"
+                    android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
+            </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
+
+            <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+                android:id="@+id/silence"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/notification_importance_button_separation"
+                android:padding="@dimen/notification_importance_button_padding"
+                android:clickable="true"
+                android:focusable="true"
+                android:background="@drawable/notification_guts_priority_button_bg"
+                android:orientation="vertical">
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="center"
+                    >
+                    <ImageView
+                        android:id="@+id/silence_icon"
+                        android:src="@drawable/ic_notifications_silence"
+                        android:background="@android:color/transparent"
+                        android:tint="@color/notification_guts_priority_contents"
+                        android:layout_gravity="center"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:clickable="false"
+                        android:focusable="false"/>
+                    <TextView
+                        android:id="@+id/silence_label"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:ellipsize="end"
+                        android:maxLines="1"
+                        android:clickable="false"
+                        android:focusable="false"
+                        android:layout_toEndOf="@id/silence_icon"
+                        android:layout_marginStart="@dimen/notification_importance_drawable_padding"
+                        android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
+                        android:text="@string/notification_silence_title"/>
+                </LinearLayout>
+                <TextView
+                    android:id="@+id/silence_summary"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
+                    android:visibility="gone"
+                    android:text="@string/notification_channel_summary_low"
+                    android:clickable="false"
+                    android:focusable="false"
+                    android:ellipsize="end"
+                    android:maxLines="2"
+                    android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
+            </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
+
+        </LinearLayout>
+
+        <TextView
+            android:id="@+id/notification_guts_bundle_feedback"
+            android:text="@string/notification_guts_bundle_feedback"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="start|center_vertical"
+            android:minWidth="@dimen/notification_guts_bundle_feedback_size"
+            android:minHeight="@dimen/notification_guts_bundle_feedback_size"
+            android:maxWidth="200dp"
+            style="@style/TextAppearance.NotificationInfo.Button"/>
+
+        <RelativeLayout
+            android:id="@+id/bottom_buttons"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:minHeight="60dp"
+            android:gravity="center_vertical"
+            android:paddingStart="4dp"
+            android:paddingEnd="4dp"
+            >
+            <TextView
+                android:id="@+id/turn_off_notifications"
+                android:text="@string/inline_turn_off_notifications"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentStart="true"
+                android:gravity="start|center_vertical"
+                android:minWidth="@dimen/notification_importance_toggle_size"
+                android:minHeight="@dimen/notification_importance_toggle_size"
+                android:maxWidth="200dp"
+                style="@style/TextAppearance.NotificationInfo.Button"/>
+            <TextView
+                android:id="@+id/done"
+                android:text="@string/inline_ok_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:gravity="end|center_vertical"
+                android:minWidth="@dimen/notification_importance_toggle_size"
+                android:minHeight="@dimen/notification_importance_toggle_size"
+                android:maxWidth="125dp"
+                style="@style/TextAppearance.NotificationInfo.Button"/>
+        </RelativeLayout>
+    </LinearLayout>
+</com.android.systemui.statusbar.notification.row.BundleNotificationInfo>
diff --git a/packages/SystemUI/res/layout/custom_trace_settings_dialog.xml b/packages/SystemUI/res/layout/custom_trace_settings_dialog.xml
index 9e84052..17c2f89 100644
--- a/packages/SystemUI/res/layout/custom_trace_settings_dialog.xml
+++ b/packages/SystemUI/res/layout/custom_trace_settings_dialog.xml
@@ -26,6 +26,8 @@
         android:layout_height="wrap_content"
         android:layout_gravity="center"
         android:layout_marginTop="@dimen/qqs_layout_margin_top"
+        android:minHeight="@dimen/min_clickable_item_size"
+        android:minWidth="@dimen/min_clickable_item_size"
         android:textAppearance="@style/TextAppearance.Dialog.Body.Message" />
 
     <TextView
@@ -34,6 +36,8 @@
         android:layout_height="wrap_content"
         android:layout_gravity="center"
         android:layout_marginTop="@dimen/qqs_layout_margin_top"
+        android:minHeight="@dimen/min_clickable_item_size"
+        android:minWidth="@dimen/min_clickable_item_size"
         android:textAppearance="@style/TextAppearance.Dialog.Body.Message" />
 
     <!-- Attach to Bugreport Switch -->
@@ -58,9 +62,9 @@
         <Switch
             android:id="@+id/attach_to_bugreport_switch"
             android:layout_width="wrap_content"
-            android:minHeight="@dimen/screenrecord_option_icon_size"
             android:layout_height="wrap_content"
             android:gravity="end"
+            style="@style/ScreenRecord.Switch"
             android:layout_gravity="fill_vertical"
             android:layout_weight="0" />
     </LinearLayout>
@@ -87,9 +91,9 @@
         <Switch
             android:id="@+id/winscope_switch"
             android:layout_width="wrap_content"
-            android:minHeight="@dimen/screenrecord_option_icon_size"
             android:layout_height="wrap_content"
             android:gravity="end"
+            style="@style/ScreenRecord.Switch"
             android:layout_gravity="fill_vertical"
             android:layout_weight="0" />
     </LinearLayout>
@@ -116,9 +120,9 @@
         <Switch
             android:id="@+id/trace_debuggable_apps_switch"
             android:layout_width="wrap_content"
-            android:minHeight="@dimen/screenrecord_option_icon_size"
             android:layout_height="wrap_content"
             android:gravity="end"
+            style="@style/ScreenRecord.Switch"
             android:layout_gravity="fill_vertical"
             android:layout_weight="0" />
     </LinearLayout>
@@ -145,9 +149,9 @@
         <Switch
             android:id="@+id/long_traces_switch"
             android:layout_width="wrap_content"
-            android:minHeight="@dimen/screenrecord_option_icon_size"
             android:layout_height="wrap_content"
             android:gravity="end"
+            style="@style/ScreenRecord.Switch"
             android:layout_gravity="fill_vertical"
             android:layout_weight="0" />
     </LinearLayout>
diff --git a/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml b/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml
index ff5d9d3..a338e4c 100644
--- a/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml
+++ b/packages/SystemUI/res/layout/notification_2025_hybrid_conversation.xml
@@ -29,16 +29,18 @@
         android:layout_height="@dimen/notification_2025_single_line_face_pile_size"
         android:layout_marginEnd="8dp"
     >
-        <ImageView
+        <com.android.internal.widget.CachingIconView
             android:id="@*android:id/conversation_icon"
             android:layout_width="@dimen/notification_2025_single_line_avatar_size"
             android:layout_height="@dimen/notification_2025_single_line_avatar_size"
             android:layout_gravity="center_vertical|end"
+            android:background="@*android:drawable/notification_icon_circle"
+            android:clipToOutline="true"
         />
 
         <ViewStub
             android:id="@*android:id/conversation_face_pile"
-            android:layout="@*android:layout/conversation_face_pile_layout"
+            android:layout="@*android:layout/notification_2025_conversation_face_pile_layout"
             android:layout_width="@dimen/notification_2025_single_line_face_pile_size"
             android:layout_height="@dimen/notification_2025_single_line_face_pile_size"
             android:layout_gravity="center_vertical|end"
diff --git a/packages/SystemUI/res/layout/record_issue_dialog.xml b/packages/SystemUI/res/layout/record_issue_dialog.xml
index e30ae6e..b2a8c4c 100644
--- a/packages/SystemUI/res/layout/record_issue_dialog.xml
+++ b/packages/SystemUI/res/layout/record_issue_dialog.xml
@@ -38,6 +38,8 @@
         android:drawableEnd="@drawable/arrow_pointing_down"
         android:layout_marginTop="@dimen/qqs_layout_margin_top"
         android:focusable="false"
+        android:minHeight="@dimen/min_clickable_item_size"
+        android:minWidth="@dimen/min_clickable_item_size"
         android:clickable="true" />
 
     <!-- Screen Record Switch -->
@@ -72,10 +74,10 @@
         <Switch
             android:id="@+id/screenrecord_switch"
             android:layout_width="wrap_content"
-            android:minHeight="@dimen/screenrecord_option_icon_size"
             android:layout_height="wrap_content"
             android:gravity="center"
             android:layout_gravity="fill_vertical"
+            style="@style/ScreenRecord.Switch"
             android:layout_weight="0"
             android:contentDescription="@string/quick_settings_screen_record_label" />
     </LinearLayout>
@@ -112,11 +114,11 @@
         <Switch
             android:id="@+id/bugreport_switch"
             android:layout_width="wrap_content"
-            android:minHeight="@dimen/screenrecord_option_icon_size"
             android:layout_height="wrap_content"
             android:gravity="center"
             android:layout_gravity="fill_vertical"
             android:layout_weight="0"
+            style="@style/ScreenRecord.Switch"
             android:contentDescription="@string/qs_record_issue_bug_report" />
     </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 694357d..b8544a6 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -31,10 +31,10 @@
         app:layout_constraintBottom_toBottomOf="@id/volume_dialog_settings"
         app:layout_constraintEnd_toEndOf="@id/volume_dialog_main_slider_container"
         app:layout_constraintStart_toStartOf="@id/volume_dialog_main_slider_container"
-        app:layout_constraintTop_toTopOf="@id/volume_ringer_and_drawer_container" />
+        app:layout_constraintTop_toTopOf="@id/volume_ringer_drawer" />
 
     <include
-        android:id="@id/volume_ringer_and_drawer_container"
+        android:id="@id/volume_ringer_drawer"
         layout="@layout/volume_ringer_drawer"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/volume_dialog_legacy.xml b/packages/SystemUI/res/layout/volume_dialog_legacy.xml
index 9010ab7..d44b6a8 100644
--- a/packages/SystemUI/res/layout/volume_dialog_legacy.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_legacy.xml
@@ -93,9 +93,7 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:background="@drawable/volume_background_bottom"
-                    android:paddingLeft="@dimen/volume_dialog_ringer_rows_padding"
-                    android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding"
-                    android:paddingRight="@dimen/volume_dialog_ringer_rows_padding">
+                    android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding">
                     <com.android.keyguard.AlphaOptimizedImageButton
                         android:id="@+id/settings"
                         android:src="@drawable/horizontal_ellipsis"
diff --git a/packages/SystemUI/res/layout/volume_ringer_button.xml b/packages/SystemUI/res/layout/volume_ringer_button.xml
index dc6780a..38bb783 100644
--- a/packages/SystemUI/res/layout/volume_ringer_button.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_button.xml
@@ -14,6 +14,7 @@
   ~ limitations under the License.
   -->
 <FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" >
 
@@ -25,6 +26,7 @@
         android:layout_marginBottom="@dimen/volume_dialog_components_spacing"
         android:contentDescription="@string/volume_ringer_mode"
         android:gravity="center"
+        android:tint="?androidprv:attr/materialColorOnSurface"
         android:src="@drawable/volume_ringer_item_bg"
         android:background="@drawable/volume_ringer_item_bg"/>
 
diff --git a/packages/SystemUI/res/layout/volume_ringer_drawer.xml b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
index b71c470..d850bbe 100644
--- a/packages/SystemUI/res/layout/volume_ringer_drawer.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
@@ -14,55 +14,18 @@
   ~ limitations under the License.
   -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    android:id="@+id/volume_ringer_and_drawer_container"
-    android:layout_width="wrap_content"
+<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/volume_ringer_drawer"
+    android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:clipChildren="false"
     android:clipToPadding="false"
     android:gravity="center"
-    android:layoutDirection="ltr">
+    android:layoutDirection="ltr"
+    android:orientation="vertical"
+    app:layoutDescription="@xml/volume_dialog_ringer_drawer_motion_scene">
 
-    <!-- Drawer view, invisible by default. -->
-    <FrameLayout
-        android:id="@+id/volume_drawer_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
+    <!-- add ringer buttons here -->
 
-        <!-- View that is animated to a tapped ringer selection, so it appears selected. -->
-        <FrameLayout
-            android:id="@+id/volume_drawer_selection_background"
-            android:layout_width="@dimen/volume_dialog_ringer_drawer_button_size"
-            android:layout_height="@dimen/volume_dialog_ringer_drawer_button_size"
-            android:layout_gravity="bottom|right"
-            android:alpha="0.0"
-            android:background="@drawable/volume_drawer_selection_bg" />
-
-        <LinearLayout
-            android:id="@+id/volume_drawer_options"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-
-            <!-- add ringer buttons here -->
-
-        </LinearLayout>
-
-    </FrameLayout>
-
-    <!-- The current ringer selection. When the drawer is opened, this animates to the corresponding
-         position in the drawer. When the drawer is closed, it animates back. -->
-    <ImageButton
-        android:id="@+id/volume_new_ringer_active_button"
-        android:layout_width="@dimen/volume_dialog_ringer_drawer_button_size"
-        android:layout_height="@dimen/volume_dialog_ringer_drawer_button_size"
-        android:layout_marginBottom="@dimen/volume_dialog_components_spacing"
-        android:background="@drawable/volume_drawer_selection_bg"
-        android:contentDescription="@string/volume_ringer_change"
-        android:gravity="center"
-        android:src="@drawable/ic_volume_media"
-        android:tint="?androidprv:attr/materialColorOnPrimary" />
-
-</FrameLayout>
\ No newline at end of file
+</androidx.constraintlayout.motion.widget.MotionLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 048ddaf..ebee157 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Gehoortoestelle"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Skakel tans aan …"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Kan nie helderheid verstel nie omdat dit\n deur die topapp beheer word"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Outodraai"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Outodraai skerm"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ligging"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nuwe toestel saam te bind"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Kon nie voorafstelling opdateer nie"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorafstelling"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Gekies"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nutsgoed"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Intydse Onderskrifte"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokkeer toestelmikrofoon?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokkeer toestelkamera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblokkeer toestelkamera en mikrofoon?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Geen kennisgewings nie"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Geen nuwe kennisgewings nie"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Kennisgewingdemping is nou aan"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Jou toestelvolume en -waarskuwings word outomaties vir tot 2 minute lank verminder wanneer jy te veel kennisgewings op een slag kry."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Skakel af"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ontsluit om ouer kennisgewings te sien"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skakel oor na app regs of onder terwyl jy verdeelde skerm gebruik"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skakel oor na app links of bo terwyl jy verdeelde skerm gebruik"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Tydens verdeelde skerm: verplaas ’n app van een skerm na ’n ander"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Skuif aktiewe venster tussen skerms"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Invoer"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Skakel oor na volgende taal"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Skakel oor na vorige taal"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gebruik minder as <xliff:g id="LENGTH">%1$d</xliff:g> karakters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Gespreklegstukke"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tik op \'n gesprek om dit by jou tuisskerm te voeg"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Keer die foon om vir hoër resolusie"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Voubare toestel word ontvou"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Voubare toestel word omgekeer"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"gevou"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"oopgevou"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toeganklikheid"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Kortpadsleutels"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pasmaak kortpadsleutels"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Druk sleutel om kortpad toe te wys"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Soekkortpaaie"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen soekresultate nie"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Vou ikoon in"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikoon vir Handeling- of Meta-sleutel"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusikoon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Pasmaak"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klaar"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Sleutelbordinstellings"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Stel kortpad"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Kanselleer"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Druk sleutel"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Sleutelkombinasie is reeds in gebruik. Probeer ’n ander sleutel."</string>
     <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>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index 4afae33..fbeefc8 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Af"</item>
     <item msgid="3028994095749238254">"Aan"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Onbeskikbaar"</item>
+    <item msgid="6419996398343291862">"Af"</item>
+    <item msgid="5908720590832378783">"Aan"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 9d03a91..0351c75 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ግቤት"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"መስሚያ አጋዥ መሣሪያዎች"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"በማብራት ላይ..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ከላይ ባለው መተግበሪያ ቁጥጥር ላይ ስለሆነ\n ብሩህነትን ማስተካከል አልተቻለም"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"በራስ ሰር አሽከርክር"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ማያ ገጽን በራስ-አሽከርክር"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"አካባቢ"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"አዲስ መሣሪያ ለማጣመር ጠቅ ያድርጉ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ቅድመ-ቅምጥን ማዘመን አልተቻለም"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ቅድመ-ቅምጥ"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ተመርጧል"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"መሣሪያዎች"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"የቀጥታ መግለጫ ጽሑፍ"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"ማስታወሻ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"የመሣሪያ ማይክሮፎን እገዳ ይነሳ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"የመሣሪያ ካሜራ እገዳ ይነሳ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"የመሣሪያ ካሜራ እና ማይክሮፎን እገዳ ይነሳ?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ምንም ማሳወቂያ የለም"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ምንም አዲስ ማሳወቂያዎች የሉም"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"የማሳወቂያ ረጋ ማለት አሁን በርቷል"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"በአንድ ጊዜ ብዙ ማሳወቂያዎችን ሲያገኙ የመሣሪያዎ ድምፅ እና ማንቂያዎች እስከ 2 ደቂቃዎች ድረስ በራስ-ሰር ይቀንሳሉ።"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"አጥፋ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"የቆዩ ማሳወቂያዎችን ለማየት ይክፈቱ"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከታች ወዳለ መተግበሪያ ይቀይሩ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከላይ ወዳለ መተግበሪያ ይቀይሩ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"በተከፈለ ማያ ገጽ ወቅት፡- መተግበሪያን ከአንዱ ወደ ሌላው ተካ"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"በማሳያዎች መካከል ንቁ መስኮትን ያንቀሳቅሱ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ግቤት"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ወደ ቀጣዩ ቋንቋ ቀይር"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ወደ ቀዳሚ ቋንቋ ቀይር"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ከ<xliff:g id="LENGTH">%1$d</xliff:g> የሚያንሱ ቁምፊዎችን ይጠቀሙ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"የውይይት ምግብሮች"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"በመነሻ ማያ ገጽዎ ላይ ለማከል አንድ ውይይት መታ ያድርጉ"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ለከፍተኛ ጥራት ስልኩን ይቀይሩ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"መታጠፍ የሚችል መሣሪያ እየተዘረጋ ነው"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"መታጠፍ የሚችል መሣሪያ እየተገለበጠ ነው"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"የታጠፈ"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"የተዘረጋ"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ተደራሽነት"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"የቁልፍ ሰሌዳ አቋራጮች"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"የቁልፍ ሰሌዳ አቋራጮችን ያብጁ"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"አቋራጭ ለመመደብ ቁልፍ ይጫኑ"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"የፍለጋ አቋራጮች"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ምንም የፍለጋ ውጤቶች የሉም"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"መሰብሰቢያ አዶ"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"የእርምጃ ወይም ሜታ ቁልፍ አዶ"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"የመደመር አዶ"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"አብጅ"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ተከናውኗል"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"የቁልፍ ሰሌዳ ቅንብሮች"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"አቋራጭ አቀናብር"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ይቅር"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ቁልፍ ይጫኑ"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"የቁልፍ ጥምረት አስቀድሞ በሥራ ላይ ነው። ሌላ ቁልፍ ይሞክሩ።"</string>
     <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>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index 8601132..b98fe57 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"አጥፋ"</item>
     <item msgid="3028994095749238254">"አብራ"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"አይገኝም"</item>
+    <item msgid="6419996398343291862">"ጠፍቷል"</item>
+    <item msgid="5908720590832378783">"በርቷል"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 062ab78..645d880 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -109,14 +109,14 @@
     <string name="screenrecord_title" msgid="4257171601439507792">"مسجّل الشاشة"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string>
-    <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"هل تريد تسجيل محتوى الشاشة؟"</string>
-    <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"تسجيل محتوى تطبيق واحد"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"تسجيل محتوى الشاشة بالكامل"</string>
+    <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"هل تريد تسجيل الشاشة؟"</string>
+    <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"تسجيل شاشة تطبيق واحد"</string>
+    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"تسجيل الشاشة بكاملها"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"‏تسجيل محتوى الشاشة بالكامل: %s"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"أثناء تسجيل محتوى الشاشة بالكامل، يتم تسجيل كل المحتوى المعروض على شاشتك. لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"أثناء تسجيل محتوى تطبيق، يتم تسجيل أي محتوى يتم عرضه أو تشغيله في ذلك التطبيق. لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
-    <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"تسجيل محتوى الشاشة"</string>
-    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"اختيار تطبيق لتسجيل محتواه"</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"سيتم تسجيل كل المحتوى المعروض أو المشغَّل على شاشة التطبيق، لذا يُرجى توخي الحذر بشأن المعلومات الظاهرة، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور والمقاطع الصوتية والفيديوهات."</string>
+    <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"تسجيل الشاشة"</string>
+    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"يُرجى اختيار تطبيق لتسجيل شاشته"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"تسجيل الصوت"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"صوت الجهاز"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"الصوت من جهازك، مثلاً الموسيقى والمكالمات ونغمات الرنين"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"الإدخال"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"سماعات الأذن الطبية"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"جارٍ التفعيل…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"لا يمكن ضبط مستوى السطوع لأنّ\n التطبيق الأول يتحكّم فيه"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"التدوير التلقائي"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"التدوير التلقائي للشاشة"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"الموقع الجغرافي"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"انقر لإقران جهاز جديد"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"تعذَّر تعديل الإعداد المسبق"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"الإعدادات المسبقة"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"تمّ اختياره"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"الأدوات"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"النسخ النصي التلقائي"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"ملاحظات"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"هل تريد إزالة حظر ميكروفون الجهاز؟"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"هل تريد إزالة حظر كاميرا الجهاز؟"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"هل تريد إزالة حظر الكاميرا والميكروفون؟"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"غير مفعَّل"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"لم يتم ضبط الوضع"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"الإدارة في الإعدادات"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{ما مِن أوضاع مفعَّلة}=1{الوضع \"{mode}\" مفعَّل}two{وضعان مفعَّلان}few{‫# أوضاع مفعَّلة}many{‫# وضعًا مفعَّلاً}other{‫# وضع مفعَّل}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{ما مِن أوضاع مفعَّلة}=1{‫\"{mode}\" مفعَّل}two{وضعان مفعَّلان}few{‫# أوضاع مفعَّلة}many{‫# وضعًا مفعَّلاً}other{‫# وضع مفعَّل}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"لن يتم إزعاجك بالأصوات والاهتزاز، باستثناء المُنبِّهات والتذكيرات والأحداث والمتصلين الذين تحددهم. وسيظل بإمكانك سماع أي عناصر أخرى تختار تشغيلها، بما في ذلك الموسيقى والفيديوهات والألعاب."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"لن يتم إزعاجك بالأصوات والاهتزاز، باستثناء المُنبِّهات. وسيظل بإمكانك سماع أي عناصر أخرى تختار تشغيلها، بما في ذلك الموسيقى والفيديوهات والألعاب."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"تخصيص"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"التبديل إلى التطبيق على اليسار أو الأسفل أثناء استخدام \"تقسيم الشاشة\""</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"التبديل إلى التطبيق على اليمين أو الأعلى أثناء استخدام \"تقسيم الشاشة\""</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"استبدال تطبيق بآخر في وضع \"تقسيم الشاشة\""</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"نقل نافذة نشطة بين شاشات العرض"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"الإدخال"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"التبديل إلى اللغة التالية"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"التبديل إلى اللغة السابقة"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"يجب استخدام أقل من <xliff:g id="LENGTH">%1$d</xliff:g> حرف."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"التطبيقات المصغّرة للمحادثات"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"انقر على محادثة لإضافتها إلى \"الشاشة الرئيسية\""</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"للحصول على درجة دقة أعلى، اقلِب الهاتف."</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"جهاز قابل للطي يجري فتحه"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"جهاز قابل للطي يجري قلبه"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"مطوي"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"غير مطوي"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"‫%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"تسهيل الاستخدام"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"اختصارات لوحة المفاتيح"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"تخصيص اختصارات لوحة المفاتيح"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"اضغط على مفتاح لتخصيص الاختصار"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"البحث في الاختصارات"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ما مِن نتائج بحث"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"رمز التصغير"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"‏رمز مفتاح الإجراء (مفتاح Meta)"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"رمز علامة الجمع (+)"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"تخصيص"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"تم"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"إعدادات لوحة المفاتيح"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ضبط الاختصار"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"إلغاء"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"اضغط على مفتاح"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"يتم حاليًا استخدام مجموعة المفاتيح هذه. يُرجى تجربة مفتاح آخر."</string>
     <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>
@@ -1459,11 +1455,11 @@
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"عرض التطبيقات المستخدَمة مؤخرًا"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"مرِّر سريعًا للأعلى مع الاستمرار باستخدام 3 أصابع على لوحة اللمس"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"أحسنت."</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"لقد أكملْت الدليل التوجيهي على إيماءة \"عرض التطبيقات المستخدَمة مؤخرًا\"."</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"لقد أكملْت التدريب على إيماءة عرض التطبيقات المستخدَمة مؤخرًا."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"عرض جميع التطبيقات"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"اضغط على مفتاح الإجراء في لوحة المفاتيح"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"أحسنت!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"لقد أكملْت الدليل التوجيهي عن إيماءة \"عرض جميع التطبيقات\""</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"لقد أكملْت التدريب على إيماءة عرض جميع التطبيقات"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"الإضاءة الخلفية للوحة المفاتيح"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏مستوى الإضاءة: %1$d من %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"إدارة المنزل آليًّا"</string>
diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
index f985e2f..0be4367 100644
--- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"غير مفعَّلة"</item>
     <item msgid="3028994095749238254">"مفعَّلة"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"غير متوفِّرة"</item>
+    <item msgid="6419996398343291862">"متوقّفة"</item>
+    <item msgid="5908720590832378783">"مفعّلة"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 7b3f0bb..e14f4cc 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ইনপুট"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"শ্ৰৱণ যন্ত্ৰ"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"অন কৰি থকা হৈছে…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"উজ্জ্বলতা মিলাব নোৱাৰি কাৰণ সেয়া\n শীৰ্ষৰ এপটোৱে নিয়ন্ত্ৰণ কৰি আছে"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"স্বয়ং-ঘূৰ্ণন"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"অৱস্থান"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"নতুন ডিভাইচ পেয়াৰ কৰিবলৈ ক্লিক কৰক"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"প্ৰিছেট আপডে’ট কৰিব পৰা নগ’ল"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্ৰিছেট"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বাছনি কৰা হৈছে"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"সঁজুলি"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ কেপশ্বন"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"টোকা"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইচৰ মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইচৰ কেমেৰা অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ডিভাইচৰ কেমেৰা আৰু মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"এতিয়াই আৰম্ভ কৰক"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"কোনো জাননী নাই"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"কোনো নতুন জাননী নাই"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"জাননী কুলডাউন কৰা সুবিধাটো এতিয়া অন কৰা হৈছে"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"আপুনি একেলগে বহুতো জাননী পালে আপোনাৰ ডিভাইচটোৰ ভলিউম আৰু সতৰ্কবাৰ্তা স্বয়ংক্ৰিয়ভাৱে ২ মিনিটলৈকে কমোৱা হয়।"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"অফ কৰক"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুৰণি জাননী চবলৈ আনলক কৰক"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত সোঁফালে অথবা তলত থকা এপলৈ সলনি কৰক"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত বাওঁফালে অথবা ওপৰত থকা এপলৈ সলনি কৰক"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"বিভাজিত স্ক্ৰীনৰ ব্যৱহাৰ কৰাৰ সময়ত: কোনো এপ্ এখন স্ক্ৰীনৰ পৰা আনখনলৈ নিয়ক"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ডিছপ্লে’সমূহৰ মাজত সক্রিয় হৈ থকা ৱিণ্ড’ সলনা সলনিকৈ ব্যৱহাৰ কৰক"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ইনপুট"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"পৰৱৰ্তী ভাষাটোলৈ সলনি কৰক"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"পূৰ্বৰ ভাষালৈ সলনি কৰক"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> টাতকৈ কম বৰ্ণ ব্যৱহাৰ কৰক"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"বাৰ্তালাপ ৱিজেট"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"আপোনাৰ গৃহ স্ক্ৰীনত কোনো বাৰ্তালাপ যোগ দিবলৈ সেইটোত টিপক"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"অধিক ৰিজ’লিউশ্বনৰ বাবে, ফ’নটো লুটিয়াই দিয়ক"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"জপাব পৰা ডিভাইচৰ জাপ খুলি থকা হৈছে"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"জপাব পৰা ডিভাইচৰ ওলোটাই থকা হৈছে"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ফ’ল্ড কৰা"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"আনফ’ল্ড কৰা"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"সাধ্য সুবিধা"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"কীব’ৰ্ডৰ শ্বৰ্টকাট"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীব’ৰ্ডৰ শ্বৰ্টকাট কাষ্টমাইজ কৰক"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"শ্বৰ্টকাটৰ ভূমিকা অৰ্পণ কৰিবলৈ কী টিপক"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সন্ধানৰ শ্বৰ্টকাট"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"সন্ধানৰ কোনো ফলাফল নাই"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"সংকোচন কৰাৰ চিহ্ন"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"কাৰ্য বা মেটা কীৰ চিহ্ন"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"যোগ চিনৰ চিহ্ন"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"কাষ্টমাইজ কৰক"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"হ’ল"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"কীব’ৰ্ডৰ ছেটিং"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"শ্বৰ্টকাট ছেট কৰক"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"বাতিল কৰক"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"কী টিপক"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"কীৰ মিশ্ৰণ ইতিমধ্যে ব্যৱহাৰ হৈ আছে। অন্য এটা কী ব্যৱহাৰ কৰি চাওক।"</string>
     <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>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index 3ec2f5c..da237e5 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"অফ আছে"</item>
     <item msgid="3028994095749238254">"অন আছে"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"উপলব্ধ নহয়"</item>
+    <item msgid="6419996398343291862">"অফ আছে"</item>
+    <item msgid="5908720590832378783">"অন আছে"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 1c84a59..9016870 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Giriş"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Eşitmə aparatları"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktiv edilir..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Yuxarıdakı tətbiq tərəfindən idarə olunduğu üçün\n parlaqlığı tənzimləmək mümkün deyil"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avtodönüş"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranın avtomatik dönməsi"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Məkan"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz birləşdirmək üçün klikləyin"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncəllənmədi"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçilib"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alətlər"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qeyd"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonu blokdan çıxarılsın?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerası blokdan çıxarılsın?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Cihaz kamerası və mikrofonu blokdan çıxarılsın?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Heç bir bildiriş yoxdur"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildiriş yoxdur"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Bildiriş gözləmə müddəti artıq aktivdir"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Eyni anda çox bildiriş aldıqda cihazın səs və xəbərdarlıqları avtomatik 2 dəqiqəyə qədər azalır."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiv edin"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Köhnə bildirişləri görmək üçün kilidi açın"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran istifadə edərkən sağda və ya aşağıda tətbiqə keçin"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran istifadə edərkən solda və ya yuxarıda tətbiqə keçin"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran rejimində: tətbiqi birindən digərinə dəyişin"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktiv pəncərəni displeylər arasında hərəkət etdirin"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Daxiletmə"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Növbəti dilə keçin"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Əvvəlki dilə keçin"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Maksimum <xliff:g id="LENGTH">%1$d</xliff:g> simvol istifadə edin"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Söhbət vidcetləri"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Əsas ekranınıza əlavə etmək üçün söhbətə toxunun"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Daha yüksək ayırdetmə dəqiqliyi üçün telefonu çevirin"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Qatlana bilən cihaz açılır"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Qatlana bilən cihaz fırladılır"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"qatlanmış"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"açıq"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Xüsusi imkanlar"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatura qısayolları"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatura qısayollarını fərdiləşdirin"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Qısayol təyin etmək üçün düyməni basın"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Axtarış qısayolları"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Axtarış nəticəsi yoxdur"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"İkonanı yığcamlaşdırın"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Əməliyyat və ya Meta düyməsi ikonası"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Üstəgəl ikonası"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Fərdiləşdirin"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hazırdır"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatura ayarları"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Qısayol ayarlayın"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Ləğv edin"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Düyməni basın"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Düymə kombinasiyası artıq istifadə olunur. Başqa düyməni sınayın."</string>
     <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>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index 4eea105..0203fb0 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Deaktiv"</item>
     <item msgid="3028994095749238254">"Aktiv"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Əlçatan deyil"</item>
+    <item msgid="6419996398343291862">"Deaktiv"</item>
+    <item msgid="5908720590832378783">"Aktiv"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index f260f53..d2636c0 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Unos"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušni aparati"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključuje se..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ne možete da prilagodite osvetljenost jer je\n kontroliše aplikacija u vrhu"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatska rotacija"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili nov uređaj"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadatih podešavanja nije uspelo"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unapred određena podešavanja"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izabrano"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatke"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titl uživo"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Beleška"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite da odblokirate mikrofon uređaja?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite da odblokirate kameru uređaja?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite da odblokirate kameru i mikrofon uređaja?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pređi u aplikaciju zdesna ili ispod dok je podeljen ekran"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju sleva ili iznad dok koristite podeljeni ekran"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"U režimu podeljenog ekrana: zamena jedne aplikacije drugom"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Premesti aktivan prozor na sledeći ekran"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Pređi na sledeći jezik"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Pređi na prethodni jezik"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Koristite manji broj znakova od <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za konverzaciju"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite konverzaciju da biste je dodali na početni ekran"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za veću rezoluciju obrnite telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Uređaj na preklop se otvara"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Uređaj na preklop se obrće"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zatvoreno"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otvoreno"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tasterske prečice"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite tasterske prečice"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite taster da biste dodelili prečicu"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pretražite prečice"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretrage"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za skupljanje"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tastera za radnju ili meta tastera"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona znaka plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotovo"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Podešavanja tastature"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Podesi prečicu"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite taster"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacija tastera se već koristi. Probajte sa drugim tasterom."</string>
     <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>
@@ -1450,7 +1446,7 @@
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotovo"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Prevucite ulevo ili udesno sa tri prsta na tačpedu"</string>
-    <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Svaka čast!"</string>
+    <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Super!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Dovršili ste pokret za povratak."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Idi na početni ekran"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Prevucite nagore sa tri prsta na tačpedu"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index 3f8841a..2401e4a 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Isključeno"</item>
     <item msgid="3028994095749238254">"Uključeno"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Nedostupno"</item>
+    <item msgid="6419996398343291862">"Isključeno"</item>
+    <item msgid="5908720590832378783">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index a303c11..388950c 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Увод"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слыхавыя апараты"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Уключэнне…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Не ўдаецца адрэгуляваць яркасць, бо яна\nкантралюецца асноўнай праграмай"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аўтапаварот"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аўтаматычны паварот экрана"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Месцазнаходжанне"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Націсніце, каб спалучыць новую прыладу"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не ўдалося абнавіць набор налад"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор налад"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрана"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменты"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Аўтаматычныя субцітры"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нататка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблакіраваць мікрафон прылады?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблакіраваць камеру прылады?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Разблакіраваць камеру і мікрафон прылады?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пераключыцца на праграму справа або ўнізе на падзеленым экране"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пераключыцца на праграму злева або ўверсе на падзеленым экране"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"У рэжыме падзеленага экрана замяніць адну праграму на іншую"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Перамясціць актыўнае акно паміж дысплэямі"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Увод"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Пераключыцца на наступную мову"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Пераключыцца на папярэднюю мову"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Колькасць сімвалаў павінна быць меншай за <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Віджэты размовы"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Націсніце на размову, каб дадаць яе на галоўны экран"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Каб зрабіць фота з больш высокай раздзяляльнасцю, павярніце тэлефон"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складная прылада ў раскладзеным выглядзе"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перавернутая складная прылада"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"складзена"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"раскладзена"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Спецыяльныя магчымасці"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Спалучэнні клавіш"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Наладзіць спалучэнні клавіш"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Націсніце клавішу, каб прызначыць спалучэнне клавіш"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пошук спалучэнняў клавіш"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма вынікаў пошуку"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Згарнуць\""</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Значок клавішы дзеяння (мета-клавішы)"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Значок плюса"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Наладзіць"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Гатова"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Налады клавіятуры"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Наладзіць спалучэнне клавіш"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Скасаваць"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Націсніце клавішу"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Гэта спалучэнне клавіш ужо выкарыстоўваецца. Паспрабуйце іншую клавішу."</string>
     <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>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index 8560286..2dc7057 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Выключана"</item>
     <item msgid="3028994095749238254">"Уключана"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Недаступна"</item>
+    <item msgid="6419996398343291862">"Выключана"</item>
+    <item msgid="5908720590832378783">"Уключана"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index a127515..2d68f91 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Вход"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слухови апарати"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Включва се..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Яркостта не може да се коригира, защото се контролира\n от приложението на екрана"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Авт. ориентация"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично завъртане на екрана"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Местоположение"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за сдвояване на ново устройство"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Предварително зададените настройки не бяха актуализирани"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Предварително зададено"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменти"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Надписи на живо"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Бележка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се отблокира ли микрофонът на устройството?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се отблокира ли камерата на устройството?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Да се отблокират ли камерата и микрофонът на устройството?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Превключване към приложението вдясно/отдолу в режима на разделен екран"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Превключване към приложението вляво/отгоре в режима на разделен екран"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"При разделен екран: замяна на дадено приложение с друго"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Преместване на активния прозорец между екраните"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Въвеждане"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Превключване към следващия език"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Превключване към предишния език"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Използвайте по-малко от <xliff:g id="LENGTH">%1$d</xliff:g> знака"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Приспособления за разговор"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Докоснете разговор, за да го добавите към началния си екран"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"За по-висока разделителна способност обърнете телефона"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Разгъване на сгъваемо устройство"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Обръщане на сгъваемо устройство"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворено"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворено"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Клавишни комбинации"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Персонализиране на клавишните комбинации"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Натиснете клавиш, за да зададете клавишна комбинация"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Търсете клавишни комбинации"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма резултати от търсенето"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за свиване"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Икона на клавиша за действия или клавиша Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Икона на плюс"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Персонализиране"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Настройки на клавиатурата"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Задаване на клавишна комбинация"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Отказ"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Натиснете клавиш"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Клавишната комбинация вече се използва. Опитайте с друг клавиш."</string>
     <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>
@@ -1449,7 +1445,7 @@
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Преглед на скорошните приложения"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
-    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Прекарайте три пръста наляво или надясно по сензорния панел"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Плъзнете три пръста наляво или надясно по сензорния панел"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Чудесно!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Изпълнихте жеста за връщане назад."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Към началния екран"</string>
@@ -1457,7 +1453,7 @@
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Отлично!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Изпълнихте жеста за преминаване към началния екран"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Преглед на скорошните приложения"</string>
-    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Прекарайте три пръста нагоре по сензорния панел и задръжте"</string>
+    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Плъзнете три пръста нагоре по сензорния панел и задръжте"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Отлично!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Изпълнихте жеста за преглед на скорошните приложения."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Преглед на всички приложения"</string>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index 9b808de..cc632db7 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Изкл."</item>
     <item msgid="3028994095749238254">"Вкл."</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Не е налице"</item>
+    <item msgid="6419996398343291862">"Изкл."</item>
+    <item msgid="5908720590832378783">"Вкл."</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index ae810a6..4281ea1 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ইনপুট"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"হিয়ারিং এড"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"চালু করা হচ্ছে…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"উজ্জ্বলতা টপ অ্যাপ নিয়ন্ত্রণ করায়\n এটিকে অ্যাডজাস্ট করা যাচ্ছে না"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"নিজে থেকে ঘুরবে"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"অটো-রোটেট স্ক্রিন"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"লোকেশন"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"নতুন ডিভাইস পেয়ার করতে ক্লিক করুন"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"প্রিসেট আপডেট করা যায়নি"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্রিসেট"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বেছে নেওয়া হয়েছে"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"টুল"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ ক্যাপশন"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"মনে রাখবেন"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইসের মাইক্রোফোন আনব্লক করতে চান?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইসের ক্যামেরা আনব্লক করতে চান?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ডিভাইসের ক্যামেরা এবং মাইক্রোফোন আনব্লক করতে চান?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"এখন শুরু করুন"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"কোনও বিজ্ঞপ্তি নেই"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"নতুন কোনও বিজ্ঞপ্তি নেই"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"নোটিফিকেশন কুলডাউন এখন চালু আছে"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"আপনি একসঙ্গে খুব বেশি বিজ্ঞপ্তি পেলে আপনার ডিভাইসের ভলিউম এবং সতর্কবার্তা সর্বাধিক ২ মিনিটের জন্য অটোমেটিক কমে যায়।"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"বন্ধ করুন"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুরনো বিজ্ঞপ্তি দেখতে আনলক করুন"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"স্প্লিট স্ক্রিন ব্যবহার করার সময় ডানদিকের বা নিচের অ্যাপে পাল্টে নিন"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"স্প্লিট স্ক্রিন ব্যবহার করার সময় বাঁদিকের বা উপরের অ্যাপে পাল্টে নিন"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"\'স্প্লিট স্ক্রিন\' থাকাকালীন: একটি অ্যাপ থেকে অন্যটিতে পাল্টান"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ডিসপ্লের মধ্যে একটি থেকে অপরটিতে অ্যাক্টিভ উইন্ডোটি সরান"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ইনপুট"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"পরবর্তী ভাষায় পাল্টান"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"আগের ভাষায় পাল্টান"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>টির চেয়ে কম অক্ষর ব্যবহার করুন"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"কথোপকথন উইজেট"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"কোনও কথোপথন আপনার হোম স্ক্রিনে যোগ করার জন্য এতে ট্যাপ করুন"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"আরও বেশি রেজোলিউশনের জন্য, ফোন ফ্লিপ করুন"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ফোল্ড করা যায় এমন ডিভাইস খোলা হচ্ছে"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ফোল্ড করা যায় এমন ডিভাইস উল্টানো হচ্ছে"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ফোল্ড করা রয়েছে"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ফোল্ড করা নেই"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"অ্যাক্সেসিবিলিটি"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"কীবোর্ড শর্টকাট"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীবোর্ড শর্টকাট কাস্টমাইজ করুন"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"শর্টকাট অ্যাসাইন করতে কী প্রেস করুন"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"শর্টকাট সার্চ করুন"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"কোনও সার্চ ফলাফল নেই"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"আইকন আড়াল করুন"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"অ্যাকশন বা মেটা কী আইকন"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"প্লাস আইকন"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"কাস্টমাইজ করুন"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"হয়ে গেছে"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"কীবোর্ড সেটিংস"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"শর্টকাট সেট করুন"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"বাতিল করুন"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"কী প্রেস করুন"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"কী কম্বিনেশন আগে থেকে ব্যবহার হচ্ছে। অন্য কী ব্যবহার করে দেখুন।"</string>
     <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>
diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
index dd5b406..e213928 100644
--- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"বন্ধ আছে"</item>
     <item msgid="3028994095749238254">"চালু আছে"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"উপলভ্য নেই"</item>
+    <item msgid="6419996398343291862">"বন্ধ আছে"</item>
+    <item msgid="5908720590832378783">"চালু আছে"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index df562ef..9d9bf7f 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -113,8 +113,8 @@
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimaj jednu aplikaciju"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimaj cijeli ekran"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snimi cijeli ekran: %s"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate cijeli ekran, snimat će se sve što se prikazuje na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snimat će se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate cijeli ekran, snimat će se sve što se prikazuje na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snimat će se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimaj ekran"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Odaberite aplikaciju koju želite snimati"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Snimanje zvuka"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ulaz"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušni aparati"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključivanje…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nije moguće podesiti osvijetljenost\n jer njome upravlja aplikacija pri vrhu"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatsko rotiranje"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da uparite novi uređaj"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadane postavke nije uspjelo"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Zadana postavka"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Bilješka"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokirati mikrofon uređaja?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokirati kameru uređaja?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblokirati kameru i mikrofon uređaja?"</string>
@@ -555,21 +555,21 @@
     <string name="screen_share_permission_dialog_option_entire_screen" msgid="4493174362775038997">"Dijeli cijeli ekran"</string>
     <!-- no translation found for media_projection_entry_app_permission_dialog_option_text_entire_screen (5100078808078139706) -->
     <skip />
-    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Kada dijelite cijeli ekran, sve što je na ekranu će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada dijelite aplikaciju, sve što se prikazuje ili reproducira u toj aplikaciji će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Kada dijelite cijeli ekran, sve što je na ekranu će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada dijelite aplikaciju, sve što se prikazuje ili reproducira u toj aplikaciji će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Dijeli ekran"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućila tu opciju"</string>
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Odaberite aplikaciju koju želite dijeliti"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Emitirati ekran?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emitiraj jednu aplikaciju"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Emitiraj cijeli ekran"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Kada emitirate cijeli ekran, vidljivo je sve što je na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Kada emitirate aplikaciju, vidljivo je sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Kada emitirate cijeli ekran, vidljivo je sve što je na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Kada emitirate aplikaciju, vidljivo je sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Emitiraj ekran"</string>
     <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Odaberite aplikaciju koju želite emitirati"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Pokrenuti dijeljenje?"</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kada dijelite, snimate ili emitirate, Android ima pristup svemu što je vidljivo na ekranu ili što se reproducira na uređaju. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Kada dijelite, snimate ili emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kada dijelite, snimate ili emitirate, Android ima pristup svemu što je vidljivo na ekranu ili što se reproducira na uređaju. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Kada dijelite, snimate ili emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Pokreni"</string>
     <string name="media_projection_entry_generic_permission_dialog_continue_single_app" msgid="5920814988611877051">"Naprijed"</string>
     <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Dijeljenje se pauzira kada promijenite aplikaciju"</string>
@@ -593,7 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nema obavještenja"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obavještenja"</string>
-    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Stišavanje obavijesti sada je uključeno"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Stišavanje obavještenja je sada uključeno"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Jačina zvuka uređaja i obavještenja se automatski stišavaju do 2 minute kada odjednom dobijete previše obavještenja."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte da vidite starija obavještenja"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prelazak u aplikaciju desno ili ispod uz podijeljeni ekran"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju lijevo ili iznad dok koristite podijeljeni ekran"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Za vrijeme podijeljenog ekrana: zamjena jedne aplikacije drugom"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Premještanje aktivnog prozora između ekrana"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Prebacivanje na sljedeći jezik"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Prebacivanje na prethodni jezik"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Koristite manje od <xliff:g id="LENGTH">%1$d</xliff:g> znak(ov)a"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti razgovora"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite razgovor da ga dodate na početni ekran"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu rezoluciju obrnite telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Sklopivi uređaj se rasklapa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Sklopivi uređaj se obrće"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"sklopljeno"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otklopljeno"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Prečice tastature"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite prečice na tastaturi"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite tipku da dodijelite prečicu"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečica pretraživanja"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sužavanja"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tipke radnji ili meta tipka"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona znaka plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagođavanje"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotovo"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tastature"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavi prečicu"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ta se kombinacija tipki već koristi. Pokušajte s drugom tipkom."</string>
     <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>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index 3f8841a..2401e4a 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Isključeno"</item>
     <item msgid="3028994095749238254">"Uključeno"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Nedostupno"</item>
+    <item msgid="6419996398343291862">"Isključeno"</item>
+    <item msgid="5908720590832378783">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 0ecd8c0..0be3d80 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audiòfons"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"S\'està activant…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"No es pot ajustar la brillantor perquè\n està controlada per l\'aplicació superior"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Gira automàticament"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Gira la pantalla automàticament"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicació"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fes clic per vincular un dispositiu nou"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"No s\'ha pogut actualitzar el valor predefinit"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Valors predefinits"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionat"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eines"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítols instantanis"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vols desbloquejar el micròfon del dispositiu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vols desbloquejar la càmera del dispositiu?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vols desbloquejar la càmera i el micròfon del dispositiu?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"Desactivat"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"No definit"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gestiona a la configuració"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hi ha cap mode actiu}=1{{mode} està actiu}many{Hi ha # de modes actius}other{Hi ha # modes actius}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Cap mode actiu}=1{{mode} està actiu}many{# de modes actius}other{# modes actius}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes, recordatoris, esdeveniments i trucades de les persones que especifiquis. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalitza"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No hi ha cap notificació"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"No hi ha cap notificació nova"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"La moderació de notificacions està activada"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"El volum i les alertes del dispositiu es redueixen automàticament durant 2 minuts com a màxim quan reps massa notificacions alhora."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactiva"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueja per veure notif. anteriors"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Canvia a l\'aplicació de la dreta o de sota amb la pantalla dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Canvia a l\'aplicació de l\'esquerra o de dalt amb la pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Durant el mode de pantalla dividida: substitueix una app per una altra"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mou la finestra activa entre pantalles"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Canvia a l\'idioma següent"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Caniva a l\'idioma anterior"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Utilitza menys de <xliff:g id="LENGTH">%1$d</xliff:g> caràcters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Toca una conversa per afegir-la a la teva pantalla d\'inici"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Per a una resolució més alta, gira el telèfon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositiu plegable desplegant-se"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositiu plegable girant"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegat"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegat"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilitat"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tecles de drecera"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalitza les tecles de drecera"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Prem la tecla per assignar la drecera"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Dreceres de cerca"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hi ha cap resultat de la cerca"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Replega la icona"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icona de la tecla d\'acció o Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icona del signe més"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalitza"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Fet"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuració del teclat"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configura la drecera"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel·la"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prem una tecla"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"La combinació de tecles ja s\'està utilitzant. Prova-ho amb una altra tecla."</string>
     <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>
@@ -1458,7 +1453,7 @@
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Ben fet!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Has completat el gest per anar a la pantalla d\'inici"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Mostra les aplicacions recents"</string>
-    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Llisca cap amunt amb tres dits i mantén premut al ratolí tàctil"</string>
+    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Llisca cap amunt amb tres dits i mantén-los premuts al ratolí tàctil"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Ben fet!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Has completat el gest per veure les aplicacions recents."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Mostra totes les aplicacions"</string>
@@ -1482,7 +1477,7 @@
     <string name="home_edu_notification_title" msgid="6097902076909654045">"Utilitza el ratolí tàctil per anar a la pantalla d\'inici"</string>
     <string name="home_edu_notification_content" msgid="6631697734535766588">"Llisca tres dits cap amunt. Toca per aprendre més gestos."</string>
     <string name="overview_edu_notification_title" msgid="1265824157319562406">"Utilitza el ratolí tàctil per veure les aplicacions recents"</string>
-    <string name="overview_edu_notification_content" msgid="3578204677648432500">"Llisca cap amunt amb tres dits i mantén premut. Toca per aprendre més gestos."</string>
+    <string name="overview_edu_notification_content" msgid="3578204677648432500">"Llisca cap amunt amb tres dits i mantén-los premut. Toca per aprendre més gestos."</string>
     <string name="all_apps_edu_notification_title" msgid="372262997265569063">"Utilitza el teclat per veure totes les aplicacions"</string>
     <string name="all_apps_edu_notification_content" msgid="3255070575694025585">"Prem la tecla d\'acció en qualsevol moment. Toca per aprendre més gestos."</string>
     <string name="accessibility_deprecate_extra_dim_dialog_title" msgid="910988771011857460">"L\'atenuació extra ara forma part del control lliscant de brillantor"</string>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index ea1a576..94d5545 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Desactivat"</item>
     <item msgid="3028994095749238254">"Activat"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"No disponible"</item>
+    <item msgid="6419996398343291862">"Desactivat"</item>
+    <item msgid="5908720590832378783">"Activat"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 3f00ce4..1bbef7b 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vstup"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Naslouchátka"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Zapínání…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Jas nelze upravit, protože ho\n řídí hlavní aplikace"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. otáčení"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otáčení obrazovky"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zařízení"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Předvolbu nelze aktualizovat"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Předvolba"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybráno"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okamžité titulky"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokovat mikrofon zařízení?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokovat fotoaparát zařízení?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokovat fotoaparát a mikrofon zařízení?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Žádná oznámení"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Žádná nová oznámení"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Oznámení jsou teď zeslabená"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Když máte moc oznámení najednou, až na dvě minuty se sníží hlasitost zařízení a oznámení se omezí."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnout"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Starší oznámení se zobrazí po odemknutí"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Přepnout na aplikaci vpravo nebo dole v režimu rozdělené obrazovky"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Přepnout na aplikaci vlevo nebo nahoře v režimu rozdělené obrazovky"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"V režimu rozdělené obrazovky: nahradit jednu aplikaci druhou"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Přesunout aktivní okno mezi obrazovkami"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vstup"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Přepnout na další jazyk"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Přepnout na předchozí jazyk"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Použijte méně než <xliff:g id="LENGTH">%1$d</xliff:g> znaků"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgety konverzací"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Klepnutím na konverzaci ji přidáte na plochu"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Otočte telefon, abyste dosáhli vyššího rozlišení"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozkládání rozkládacího zařízení"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Otáčení rozkládacího zařízení"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"složené"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"rozložené"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Přístupnost"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové zkratky"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Přizpůsobení klávesových zkratek"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Nastavte zkratku stisknutím klávesy"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Vyhledat zkratky"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žádné výsledky hledání"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sbalení"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona klávesy Akce nebo Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona Plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Přizpůsobit"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hotovo"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavení klávesnice"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastavit zkratku"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Zrušit"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Stiskněte klávesu"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinace kláves se už používá. Použijte jinou klávesu."</string>
     <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>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index abfe50d..a02ed76 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Vypnuto"</item>
     <item msgid="3028994095749238254">"Zapnuto"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Není k dispozici"</item>
+    <item msgid="6419996398343291862">"Vypnuto"</item>
+    <item msgid="5908720590832378783">"Zapnuto"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 9229b18..b2e17a9 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Høreapparater"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktiverer…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Lysstyrken kan ikke justeres, fordi den\n styres af den øverste app"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Roter automatisk"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Roter skærmen automatisk"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokation"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik for at parre en ny enhed"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Forindstillingen kunne ikke opdateres"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forindstilling"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Værktøjer"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstning"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du fjerne blokeringen af enhedens mikrofon?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du fjerne blokeringen af enhedens kamera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vil du fjerne blokeringen af enhedens kamera og mikrofon?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ingen notifikationer"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye notifikationer"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Dæmpning af notifikationer er nu aktiveret"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Enheden skruer automatisk ned for lydstyrken og minimerer underretninger på skærmen i op til 2 minutter, når du får for mange notifikationer på én gang."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiver"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås op for at se ældre notifikationer"</string>
@@ -700,7 +699,7 @@
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Rumlig lyd"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Fra"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fast"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Register. af hoved­bevægelser"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hovedregistrering"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tryk for at ændre ringetilstand"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ringetilstand"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"slå lyden fra"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skift til en app til højre eller nedenfor, når du bruger opdelt skærm"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skift til en app til venstre eller ovenfor, når du bruger opdelt skærm"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ved opdelt skærm: Udskift én app med en anden"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Flyt det aktive vindue fra skærm til skærm"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Skift til næste sprog"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Skift til forrige sprog"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Angiv færre end <xliff:g id="LENGTH">%1$d</xliff:g> tegn"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Samtalewidgets"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tryk på en samtale for at føje den til din startskærm"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Vend telefonen for at få højere opløsning"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldbar enhed foldes ud"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldbar enhed vendes om"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"foldet"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"foldet ud"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hjælpefunktioner"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tastaturgenveje"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpas tastaturgenveje"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tryk på en tast for at tildele genvejen"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Genveje til søgning"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Der er ingen søgeresultater"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon for Skjul"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon for handlingstast eller metatast"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusikon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tilpas"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Udfør"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastaturindstillinger"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Konfigurer genvej"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuller"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tryk på en tast"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tastekombinationen er allerede i brug. Prøv en anden tast."</string>
     <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>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index 9009eed..8b536a2 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Fra"</item>
     <item msgid="3028994095749238254">"Til"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Ikke tilgængelig"</item>
+    <item msgid="6419996398343291862">"Fra"</item>
+    <item msgid="5908720590832378783">"Til"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index e8dcae9..5f7128e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Eingabe"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hörgerät"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Wird aktiviert…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Die Helligkeit kann nicht angepasst werden, weil sie\n von der obersten App gesteuert wird"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. drehen"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Bildschirm automatisch drehen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Standort"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicken, um neues Gerät zu koppeln"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Voreinstellung konnte nicht aktualisiert werden"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voreinstellung"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ausgewählt"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatische Untertitel"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notiz"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Blockierung des Gerätemikrofons aufheben?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Blockierung der Gerätekamera aufheben?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Blockierung von Gerätekamera und Gerätemikrofon aufheben?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Keine Benachrichtigungen"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Keine neuen Benachrichtigungen"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"„Benachrichtigungen reduzieren” ist jetzt aktiviert"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Wenn du zu viele Benachrichtigungen auf einmal erhältst, wird die Lautstärke automatisch bis zu 2 min lang verringert und Benachrichtigungen werden minimiert."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktivieren"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Für ältere Benachrichtigungen entsperren"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Im Splitscreen-Modus zu einer App rechts oder unten wechseln"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Im Splitscreen-Modus zu einer App links oder oben wechseln"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Im Splitscreen: eine App durch eine andere ersetzen"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktives Fenster auf anderes Display verschieben"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Eingabe"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Zur nächsten Sprache wechseln"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Zur vorherigen Sprache wechseln"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Maximal <xliff:g id="LENGTH">%1$d</xliff:g> Zeichen möglich"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Unterhaltungs-Widgets"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tippe auf eine Unterhaltung, um sie deinem Startbildschirm hinzuzufügen"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Für höhere Auflösung Smartphone umdrehen"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Faltbares Gerät wird geöffnet"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Faltbares Gerät wird umgeklappt"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zugeklappt"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aufgeklappt"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Bedienungshilfen"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tastenkürzel"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tastenkombinationen anpassen"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Drücke eine Taste, um eine Tastenkombination festzulegen"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tastenkürzel suchen"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Keine Suchergebnisse"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Symbol „Minimieren“"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Symbol für Aktions- oder Meta-Taste"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plussymbol"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Anpassen"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Fertig"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastatureinstellungen"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tastenkombination festlegen"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Abbrechen"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Taste drücken"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Diese Tastenkombination wird bereits verwendet. Versuche es mit einer anderen Taste."</string>
     <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>
@@ -1452,7 +1447,7 @@
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zurück"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Wische mit drei Fingern auf dem Touchpad nach links oder rechts"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Sehr gut!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Du hast den Schritt für die „Zurück“-Geste abgeschlossen."</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Du hast das Tutorial für die „Zurück“-Touch-Geste abgeschlossen."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Startbildschirm"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Wische an einer beliebigen Stelle auf dem Touchpad mit drei Fingern nach oben"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Gut gemacht!"</string>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index e7f5b57..bb39b4e 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Aus"</item>
     <item msgid="3028994095749238254">"An"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Nicht verfügbar"</item>
+    <item msgid="6419996398343291862">"Aus"</item>
+    <item msgid="5908720590832378783">"An"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index cf9addd..fd8e37a 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Είσοδος"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Βοηθήματα ακοής"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ενεργοποίηση…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Δεν είναι δυνατή η προσαρμογή της φωτεινότητας, επειδή\n ελέγχεται από την εφαρμογή στην κορυφή"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Αυτόματη περιστροφή"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Αυτόματη περιστροφή οθόνης"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Τοποθεσία"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Κάντε κλικ για σύζευξη νέας συσκευής"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Δεν ήταν δυνατή η ενημέρωση της προεπιλογής"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Προεπιλογή"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Έχει επιλεγεί"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Εργαλεία"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ζωντανοί υπότιτλοι"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Σημείωση"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Κατάργηση αποκλεισμού μικροφώνου συσκευής;"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Κατάργηση αποκλεισμού κάμερας συσκευής;"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Κατάργηση αποκλεισμού κάμερας και μικροφώνου συσκευής;"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Εναλλαγή στην εφαρμογή δεξιά ή κάτω κατά τη χρήση διαχωρισμού οθόνης"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Εναλλαγή σε εφαρμογή αριστερά ή επάνω κατά τη χρήση διαχωρισμού οθόνης"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Κατά τον διαχωρισμό οθόνης: αντικατάσταση μιας εφαρμογής με άλλη"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Μετακίνηση ενεργού παραθύρου μεταξύ οθονών"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Είσοδος"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Εναλλαγή στην επόμενη γλώσσα"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Εναλλαγή στην προηγούμενη γλώσσα"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Χρησιμοποιήστε λιγότερους από <xliff:g id="LENGTH">%1$d</xliff:g> χαρακτήρες"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Γραφικά στοιχεία συνομιλίας"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Πατήστε μια συνομιλία για να την προσθέσετε στην αρχική οθόνη"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Για υψηλότερη ανάλυση, αναστρέψτε το τηλέφωνο"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Αναδιπλούμενη συσκευή που ξεδιπλώνει"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Αναδιπλούμενη συσκευή που διπλώνει"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"διπλωμένη"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ξεδιπλωμένη"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Προσβασιμότητα"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Συντομεύσεις πληκτρολογίου"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Προσαρμογή συντομεύσεων πληκτρολογίου"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Πατήστε το πλήκτρο για εκχώρηση της συντόμευσης"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Συντομεύσεις αναζήτησης"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Κανένα αποτέλεσμα αναζήτησης"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Εικονίδιο σύμπτυξης"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Εικονίδιο πλήκτρου ενέργειας ή Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Εικονίδιο συν"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Προσαρμογή"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Τέλος"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ρυθμίσεις πληκτρολογίου"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ορισμός συντόμευσης"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Ακύρωση"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Πατήστε ένα πλήκτρο"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ο συνδυασμός πλήκτρων χρησιμοποιείται ήδη. Δοκιμάστε άλλο πλήκτρο."</string>
     <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>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index 1276fb4..ec2a930 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Ανενεργή"</item>
     <item msgid="3028994095749238254">"Ενεργή"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Μη διαθέσιμο"</item>
+    <item msgid="6419996398343291862">"Ανενεργό"</item>
+    <item msgid="5908720590832378783">"Ενεργό"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 6665959..4280ff2 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -113,8 +113,8 @@
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Choose app to record"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hearing aids"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Can\'t adjust brightness because it\'s being\n controlled by the top app"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Move active window between displays"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Action or Meta key icon"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus icon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customise"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
     <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>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</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>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index c0bbabe..1b60921 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Off"</item>
     <item msgid="3028994095749238254">"On"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Unavailable"</item>
+    <item msgid="6419996398343291862">"Off"</item>
+    <item msgid="5908720590832378783">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 9a3beda..3b009a1 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -414,6 +414,8 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
@@ -1218,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your Home screen"</string>
@@ -1353,6 +1357,7 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+    <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Front screen turned on"</string>
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 6665959..4280ff2 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -113,8 +113,8 @@
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Choose app to record"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hearing aids"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Can\'t adjust brightness because it\'s being\n controlled by the top app"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Move active window between displays"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Action or Meta key icon"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus icon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customise"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
     <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>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</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>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index c0bbabe..1b60921 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Off"</item>
     <item msgid="3028994095749238254">"On"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Unavailable"</item>
+    <item msgid="6419996398343291862">"Off"</item>
+    <item msgid="5908720590832378783">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 6665959..4280ff2 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -113,8 +113,8 @@
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Choose app to record"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hearing aids"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Can\'t adjust brightness because it\'s being\n controlled by the top app"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Move active window between displays"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Action or Meta key icon"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus icon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customise"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
     <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>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</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>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index c0bbabe..1b60921 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Off"</item>
     <item msgid="3028994095749238254">"On"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Unavailable"</item>
+    <item msgid="6419996398343291862">"Off"</item>
+    <item msgid="5908720590832378783">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3dc3058..ad403b1 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -114,7 +114,7 @@
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabar toda la pantalla"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grabar toda la pantalla: %s"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabes toda la pantalla, se grabará todo lo que se muestre en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabes una app, se registrará todo lo que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabes una app, se grabará todo lo que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabar pantalla"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Elige una app para grabar"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Grabar audio"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audífonos"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"La app superior controla el brillo,\npor lo que no se puede ajustar"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar la pantalla automáticamente"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para vincular un dispositivo nuevo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"No se pudo actualizar el ajuste predeterminado"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ajuste predeterminado"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Herramientas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitulado instantáneo"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Quieres desbloquear el micrófono del dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Quieres desbloquear la cámara del dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Quieres desbloquear la cámara y el micrófono del dispositivo?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"Desactivado"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"Sin establecer"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Administrar en configuración"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hay modos activos}=1{{mode} está activo}many{# de modos están activos}other{# modos están activos}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hay modos activos}=1{{mode} activo}many{# de modos activos}other{# modos activos}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas de los emisores que especifiques. Podrás escuchar el contenido que reproduzcas, como música, videos y juegos."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas. Podrás escuchar el contenido que reproduzcas, como música, videos y juegos."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ubicar la app a la derecha o abajo cuando usas la pantalla dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ubicar la app a la izquierda o arriba cuando usas la pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Durante pantalla dividida: Reemplaza una app con otra"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover la ventana activa de una pantalla a otra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar al próximo idioma"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Cambiar al idioma anterior"</string>
@@ -1007,7 +1006,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desactivado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"No interrumpir desactivado"</string>
-    <string name="dnd_is_on" msgid="7009368176361546279">"No interrumpir está activado"</string>
+    <string name="dnd_is_on" msgid="7009368176361546279">"No interrumpir activado"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Se activó el modo No interrumpir con una regla automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Se activó el modo No interrumpir con una app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Se activó el modo No interrumpir con una app o regla automática."</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Usa menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Presiona una conversación para agregarla a tu pantalla principal"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para obtener una resolución más alta, gira el teléfono"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable siendo desplegado"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable siendo girado"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegado"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegado"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personaliza las combinaciones de teclas"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Presiona la tecla para asignar el acceso directo"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Buscar combinaciones de teclas"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"La búsqueda no arrojó resultados"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícono de contraer"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícono tecla meta o de acción"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ícono de signo más"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Listo"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuración del teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Establecer combinación de teclas"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Presiona una tecla"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"La combinación de teclas ya está en uso. Prueba con otra."</string>
     <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>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
index dec68da..1c587d6 100644
--- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Desactivados"</item>
     <item msgid="3028994095749238254">"Activados"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"No disponible"</item>
+    <item msgid="6419996398343291862">"Desactivado"</item>
+    <item msgid="5908720590832378783">"Activado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 4660d98..50de6d2 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audífonos"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"No se puede ajustar el brillo porque la aplicación superior lo está\n controlando"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar pantalla automáticamente"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para emparejar un nuevo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"No se ha podido actualizar el preajuste"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preajuste"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Herramientas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos automáticos"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Desbloquear el micrófono del dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Desbloquear la cámara del dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Desbloquear la cámara y el micrófono del dispositivo?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"Desactivado"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"Sin definir"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gestionar en los ajustes"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hay modos activos}=1{{mode} está activo}many{Hay # modos activos}other{Hay # modos activos}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hay modos activos}=1{{mode} activo}many{Hay # modos activos}other{Hay # modos activos}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas que especifiques. Seguirás escuchando el contenido que quieras reproducir, como música, vídeos y juegos."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas. Seguirás escuchando el contenido que quieras reproducir, como música, vídeos y juegos."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Bajar volumen de notificaciones ahora está activado"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"El volumen y las alertas de tu dispositivo se reducen durante hasta 2 minutos si recibes muchas notificaciones a la vez."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
@@ -716,7 +715,7 @@
     <string name="volume_panel_hint_muted" msgid="1124844870181285320">"silenciado"</string>
     <string name="volume_panel_hint_vibrate" msgid="4136223145435914132">"vibrar"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"Reproduciendo <xliff:g id="LABEL">%s</xliff:g> en"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Se reproducirá en"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"El audio se reproducirá en"</string>
     <string name="media_output_title_ongoing_call" msgid="208426888064112006">"Llamando desde"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Configurador de UI del sistema"</string>
     <string name="status_bar" msgid="4357390266055077437">"Barra de estado"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Cambiar a la aplicación de la derecha o de abajo en pantalla dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Cambiar a la app de la izquierda o de arriba en pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Con pantalla dividida: reemplazar una aplicación por otra"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover ventana activa de una pantalla a otra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar a siguiente idioma"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Cambiar a idioma anterior"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Usa menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Toca una conversación para añadirla a la pantalla de inicio"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para una mayor resolución, gira el teléfono"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable desplegándose"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable mostrado desde varios ángulos"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegado"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegado"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar las combinaciones de teclas"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pulsa una tecla para asignar una combinación de teclas"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atajos de búsqueda"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hay resultados de búsqueda"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icono de contraer"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icono de la tecla de acción o de la tecla Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icono de más"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hecho"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ajustes del teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Establecer combinación de teclas"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pulsa una tecla"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"La combinación de teclas ya se está usando. Prueba con otra tecla."</string>
     <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>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index e872c26..5c4f36a 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Desactivados"</item>
     <item msgid="3028994095749238254">"Activado"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"No disponible"</item>
+    <item msgid="6419996398343291862">"Desactivado"</item>
+    <item msgid="5908720590832378783">"Activado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f2a92f2..9c0d56d 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -115,8 +115,8 @@
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Kogu ekraanikuva salvestamine: %s"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kui salvestate kogu ekraani, salvestatakse kõik ekraanil kuvatud andmed. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kui salvestate rakendust, salvestatakse kõik, mida selles rakenduses näidatakse või esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
-    <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekraanikuva jäädvustamine"</string>
-    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Vali salvestamiseks rakendus"</string>
+    <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Salvesta ekraanikuva"</string>
+    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Valige salvestamiseks rakendus"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Salvesta heli"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Seadme heli"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Seadmest pärinev heli, nt muusika, kõned ja helinad"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Sisend"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Kuuldeaparaadid"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Sisselülitamine …"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Heledust ei saa reguleerida, kuna seda\n juhib ülemine rakendus"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. pööramine"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Kuva automaatne pööramine"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Asukoht"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Uue seadme sidumiseks klõpsake"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Eelseadistust ei saanud värskendada"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Eelseadistus"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valitud"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tööriistad"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Reaalajas subtiitrid"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Märkus"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kas tühistada seadme mikrofoni blokeerimine?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kas tühistada seadme kaamera blokeerimine?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kas tühistada seadme kaamera ja mikrofoni blokeerimine?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Märguandeid pole"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Uusi märguandeid ei ole"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Märguannete summutamine on nüüd sisse lülitatud"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Kui saate korraga liiga palju märguandeid, vähendab seade automaatselt helitugevust ja minimeerib märguanded kuni kaheks minutiks."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Lülita välja"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vanemate märguannete nägemiseks avage"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Paremale või alumisele rakendusele lülitamine jagatud ekraani ajal"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Vasakule või ülemisele rakendusele lülitamine jagatud ekraani ajal"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ekraanikuva jagamise ajal: ühe rakenduse asendamine teisega"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktiivse akna teisaldamine ekraanide vahel"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Sisend"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Järgmisele keelele lülitamine"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Eelmisele keelele lülitamine"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Kasutage vähem kui <xliff:g id="LENGTH">%1$d</xliff:g> tähemärki"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Vestlusvidinad"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Puudutage vestlust, et lisada see oma avakuvale"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Suurema eraldusvõime saavutamiseks pöörake telefon ümber"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Volditava seadme lahtivoltimine"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Volditava seadme ümberpööramine"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kokku volditud"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"lahti volditud"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,35 +1418,28 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Juurdepääsetavus"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatuuri otseteed"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatuuri otseteede kohandamine"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Otsetee lisamiseks vajutage klahvi"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Otsige otseteid"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Otsingutulemused puuduvad"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ahendamisikoon"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Toiming või metaklahv"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pluss-ikoon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Kohandamine"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Valmis"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatuuri seaded"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Määrake otsetee"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Tühista"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Vajutage klahvi"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Klahvikombinatsioon juba kasutusel. Proovige mõnda muud klahvi."</string>
     <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>
     <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Õppige puuteplaadi liigutusi"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Navigeerige klaviatuuri ja puuteplaadi abil"</string>
-    <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Õppige puuteplaadi liigutusi, klaviatuuri otseteid ja palju muud"</string>
+    <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Õppige puuteplaadi liigutusi, klaviatuuri otseteid ja palju muud."</string>
     <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Mine tagasi"</string>
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Avakuvale"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Hiljutiste rakenduste vaatamine"</string>
@@ -1460,7 +1455,7 @@
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Hiljutiste rakenduste vaatamine"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Pühkige üles ja hoidke kolme sõrme puuteplaadil"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Väga hea!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Lõpetasite hiljutiste rakenduste vaatamise liigutuse."</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Tegite hiljutiste rakenduste vaatamise liigutuse."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Kõigi rakenduste kuvamine"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Vajutage klaviatuuril toiminguklahvi"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hästi tehtud!"</string>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index 3af8dea..f995128 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Välja lülitatud"</item>
     <item msgid="3028994095749238254">"Sisse lülitatud"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Pole saadaval"</item>
+    <item msgid="6419996398343291862">"Väljas"</item>
+    <item msgid="5908720590832378783">"Sees"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index daca2a3..a971d1c 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pantaila osoa grabatzen ari zarenean, pantailan agertzen den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Aplikazio bat grabatzen ari zarenean, aplikazio horretan agertzen den edo bertan erreproduzitzen ari den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabatu pantaila"</string>
-    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Aukeratu zer aplikazio grabatu nahi duzun"</string>
+    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Aukeratu zein aplikazio grabatu nahi duzun"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Grabatu audioa"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Gailuaren audioa"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Gailuko soinuak; adibidez, musika, deiak eta tonuak"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Sarrera"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audifonoak"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktibatzen…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ezin da doitu argitasuna,\ngaineko aplikazioak kontrolatzen duelako"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Biratze automatikoa"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Biratu pantaila automatikoki"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Kokapena"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Egin klik beste gailu bat parekatzeko"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ezin izan da eguneratu aurrezarpena"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Aurrezarpena"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Hautatuta"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tresnak"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Istanteko azpitituluak"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Oharra"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Gailuaren mikrofonoa desblokeatu nahi duzu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Gailuaren kamera desblokeatu nahi duzu?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Gailuaren kamera eta mikrofonoa desblokeatu nahi dituzu?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ez dago jakinarazpenik"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Ez dago jakinarazpen berririk"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Orain, jakinarazpenak arintzeko ezarpena aktibatuta dago"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Aldi berean jakinarazpen gehiegi jasotzen badituzu, gailuaren bolumena eta alertak automatikoki murriztuko dira 2 minutuz (gehienez)."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desaktibatu"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Jakinarazpen zaharragoak ikusteko, desblokeatu"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Aldatu eskuineko edo beheko aplikaziora pantaila zatitua erabiltzean"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Aldatu ezkerreko edo goiko aplikaziora pantaila zatitua erabiltzean"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Pantaila zatituan zaudela, ordeztu aplikazio bat beste batekin"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Eraman leiho aktiboa pantaila batetik bestera"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Sarrera"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Aldatu hurrengo hizkuntzara"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Aldatu aurreko hizkuntzara"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Erabili <xliff:g id="LENGTH">%1$d</xliff:g> karaktere baino gutxiago"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Elkarrizketa-widgetak"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Sakatu elkarrizketa bat orri nagusian gehitzeko"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Irauli telefonoa bereizmen handiago a lortzeko"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Gailu tolesgarria zabaltzen"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Gailu tolesgarria biratzen"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"tolestuta"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"tolestu gabe"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erabilerraztasuna"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Lasterbideak"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pertsonalizatu lasterbideak"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Sakatu tekla lasterbidea esleitzeko"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Bilatu lasterbideak"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ez dago bilaketa-emaitzarik"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tolesteko ikonoa"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ekintzaren edo Meta teklaren ikonoa"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus-ikonoa"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Pertsonalizatu"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Eginda"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Teklatuaren ezarpenak"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ezarri lasterbidea"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Utzi"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Sakatu tekla"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tekla-konbinazio hori erabili da dagoeneko. Probatu beste tekla bat."</string>
     <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>
diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
index 8ada72a..5d4672f 100644
--- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Desaktibatuta"</item>
     <item msgid="3028994095749238254">"Aktibatuta"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Ez dago erabilgarri"</item>
+    <item msgid="6419996398343291862">"Desaktibatuta"</item>
+    <item msgid="5908720590832378783">"Aktibatuta"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 4f2c89e..bf7ccf0 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ورودی"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"سمعک"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"روشن کردن…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"نمی‌توان روشنایی را تنظیم کرد زیرا\n برنامه بالایی آن را کنترل می‌کند"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"چرخش خودکار"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"چرخش خودکار صفحه‌نمایش"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"مکان"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"برای جفت کردن دستگاه جدید، کلیک کنید"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"پیش‌تنظیم به‌روزرسانی نشد"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"پیش‌تنظیم"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"انتخاب‌شده"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ابزارها"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"زیرنویس زنده ناشنوایان"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"یادداشت"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"میکروفون دستگاه لغو انسداد شود؟"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"دوربین دستگاه لغو انسداد شود؟"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"دوربین و میکروفون دستگاه لغو انسداد شود؟"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"رفتن به برنامه سمت راست یا پایین درحین استفاده از صفحهٔ دونیمه"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"رفتن به برنامه سمت چپ یا بالا درحین استفاده از صفحهٔ دونیمه"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"درحین صفحهٔ دونیمه: برنامه‌ای را با دیگری جابه‌جا می‌کند"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"جابه‌جا کردن پنجره فعال بین نمایشگرها"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ورودی"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"رفتن به زبان بعدی"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"رفتن به زبان قبلی"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"از کمتر از <xliff:g id="LENGTH">%1$d</xliff:g> نویسه استفاده کنید"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"ابزارک‌های مکالمه"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"روی مکالمه‌ای تک‌ضرب بزنید تا به «صفحه اصلی» اضافه شود"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"برای وضوح بیشتر، تلفن را بچرخانید"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"دستگاه تاشو درحال باز شدن"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"دستگاه تاشو درحال چرخش به اطراف"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"تاشده"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"تانشده"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترس‌پذیری"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"میان‌برهای صفحه‌کلید"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"سفارشی‌سازی کردن میان‌برهای صفحه‌کلید"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"برای اختصاص دادن میان‌بر، کلید را فشار دهید"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"جستجوی میان‌برها"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"نتیجه‌ای برای جستجو پیدا نشد"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"نماد جمع کردن"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"نماد کلید کنش یا متا"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"نماد جمع"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"سفارشی‌سازی کردن"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"تمام"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"تنظیمات صفحه‌کلید"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"تنظیم میان‌بر"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"لغو"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"کلید را فشار دهید"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ترکیب کلید ازقبل درحال استفاده است. کلید دیگری را امتحان کنید."</string>
     <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>
@@ -1446,7 +1442,7 @@
     <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"آشنایی با اشاره‌های صفحه لمسی، میان‌برهای صفحه‌کلید، و موارد دیگر"</string>
     <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"برگشتن"</string>
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"رفتن به صفحه اصلی"</string>
-    <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"مشاهده کردن برنامه‌های اخیر"</string>
+    <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"مشاهده برنامه‌های اخیر"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"تمام"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"برگشتن"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"با سه انگشت روی صفحه لمسی تند به چپ یا راست بکشید."</string>
@@ -1456,14 +1452,14 @@
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"با سه انگشت روی صفحه لمسی تند به بالا بکشید"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"عالی است!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"اشاره رفتن به صفحه اصلی را تکمیل کردید"</string>
-    <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"مشاهده کردن برنامه‌های اخیر"</string>
+    <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"مشاهده برنامه‌های اخیر"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"با سه انگشت روی صفحه لمسی تند به بالا بکشید و نگه دارید"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"عالی است!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"اشاره مشاهده برنامه‌های اخیر را انجام دادید"</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"اشاره «مشاهده برنامه‌های اخیر» را تمام کردید"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"مشاهده همه برنامه‌ها"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"دکمه کنش را روی صفحه لمسی فشار دهید"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"عالی بود!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"اشاره مشاهده همه برنامه‌ها را انجام دادید"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"اشاره «مشاهده همه برنامه‌ها» را تمام کردید"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"نور پس‌زمینه صفحه‌کلید"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏سطح %1$d از %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"کنترل خانه هوشمند"</string>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index b7f4830..1f9d6c6 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"خاموش"</item>
     <item msgid="3028994095749238254">"روشن"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"دردسترس نیست"</item>
+    <item msgid="6419996398343291862">"خاموش"</item>
+    <item msgid="5908720590832378783">"روشن"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 581f0ea..89ed95f 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Syöttölaite"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Kuulolaitteet"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Otetaan käyttöön…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Kirkkautta ei voi säätää, koska \n ensisijainen sovellus ohjaa sitä"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automaattinen kääntö"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Käännä näyttöä automaattisesti."</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Sijainti"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Muodosta uusi laitepari klikkaamalla"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Esiasetusta ei voitu muuttaa"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Esiasetus"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valittu"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Työkalut"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstitys"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Muistiinpano"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kumotaanko laitteen mikrofonin esto?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kumotaanko laitteen kameran esto?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kumotaanko laitteen kameran ja mikrofonin esto?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ei ilmoituksia"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Ei uusia ilmoituksia"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Ilmoitusten vaimennus on nyt päällä"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Äänenvoimakkuus ja ilmoitukset vaimennetaan enintään 2 minuutiksi, kun saat paljon ilmoituksia."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Laita pois päältä"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Avaa lukitus niin näet ilmoituksia"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Vaihda sovellukseen oikealla tai alapuolella jaetussa näytössä"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Vaihda sovellukseen vasemmalla tai yläpuolella jaetussa näytössä"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Jaetun näytön aikana: korvaa sovellus toisella"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Siirrä aktiivinen ikkuna näytöltä toiselle"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Syöttötapa"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Vaihda seuraavaan kieleen"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Vaihda aiempaan kieleen"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Käytä alle <xliff:g id="LENGTH">%1$d</xliff:g> merkkiä"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Keskusteluwidgetit"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Lisää keskustelu aloitusnäytölle napauttamalla sitä"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Resoluutio on parempi, kun käännät puhelimen"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Taitettava laite taitetaan"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Taitettava laite käännetään ympäri"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"taitettu"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"taittamaton"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Saavutettavuus"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Pikanäppäimet"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pikanäppäimien muokkaaminen"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Määritä pikanäppäin painamalla näppäintä"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pikahaut"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ei hakutuloksia"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tiivistyskuvake"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Toiminto- tai Meta-näppäinkuvake"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pluskuvake"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Muokkaa"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Valmis"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Näppäimistön asetukset"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Valitse pikanäppäin"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Peru"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Paina näppäintä"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Näppäinyhdistelmä on jo käytössä. Kokeile toista näppäintä."</string>
     <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>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index e323b8a..96750ef 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Pois päältä"</item>
     <item msgid="3028994095749238254">"Päällä"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Ei saatavilla"</item>
+    <item msgid="6419996398343291862">"Pois päältä"</item>
+    <item msgid="5908720590832378783">"Päällä"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index bae9471..708d8b9 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrée"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Prothèses auditives"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activation en cours…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Impossible de régler la luminosité, car elle est\n contrôlée par l\'appli principale"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation auto"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquez ici pour associer un nouvel appareil"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour le préréglage"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le microphone de l\'appareil?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer l\'appareil photo de l\'appareil?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le microphone?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'Écran divisé"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passer à l\'appli à gauche ou au-dessus avec l\'Écran divisé"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une appli par une autre"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Déplacer la fenêtre active d\'un écran à l\'autre"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrée"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Passer à la langue précédente"</string>
@@ -1202,7 +1201,7 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Haut-parleurs et écrans"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Appareils suggérés"</string>
-    <string name="media_input_group_title" msgid="2057057473860783021">"Entrer"</string>
+    <string name="media_input_group_title" msgid="2057057473860783021">"Entrée"</string>
     <string name="media_output_group_title" msgid="6789001895863332576">"Sortie"</string>
     <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Arrêtez votre session partagée pour déplacer des contenus multimédias vers un autre appareil"</string>
     <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Arrêter"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Utilisez moins de <xliff:g id="LENGTH">%1$d</xliff:g> caractères"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversation"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Touchez une conversation pour l\'ajouter à votre écran d\'accueil"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pour une meilleure résolution, retournez le téléphone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable en cours de dépliage"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable en train d\'être retourné"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plié"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"déplié"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis-clavier"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis-clavier"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Appuyez sur la touche pour attribuer un raccourci"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Rechercher des raccourcis"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icône de la touche Action ou Méta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icône Plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personnaliser"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Terminé"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Paramètres du clavier"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Définir un raccourci"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuler"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Appuyez sur la touche"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinaison de touches déjà utilisée. Essayez une autre touche."</string>
     <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>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index 0bbacd0..782c055 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Désactivé"</item>
     <item msgid="3028994095749238254">"Activé"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Non accessible"</item>
+    <item msgid="6419996398343291862">"Désactivée"</item>
+    <item msgid="5908720590832378783">"Activée"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 2006ea6..41bd910 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -113,7 +113,7 @@
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Enregistrer une appli"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Enregistrer tout l\'écran"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Enregistrer tout l\'écran : %s"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'y affiche est enregistré. Faites donc attention aux éléments tels que les mots de passe, les détails du mode de paiement, les messages, les photos, et les contenus audio et vidéo."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'y affiche est enregistré. Faites donc attention aux éléments tels que les mots de passe, les détails de mode de paiement, les messages, les photos, et les contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Lorsque vous enregistrez une appli, tout ce qui est affiché ou lu dans celle-ci est enregistré. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Enregistrer l\'écran"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Choisir l\'appli à enregistrer"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrée"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Appareils auditifs"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activation…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Impossible d\'ajuster la luminosité, car celle-ci\n est contrôlée par l\'appli principale"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation auto"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquer pour associer un nouvel appareil"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour les préréglages"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le micro de l\'appareil ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer la caméra de l\'appareil ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le micro de l\'appareil ?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"La limitation des notifications est maintenant activée"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Les alertes et le volume de l\'appareil sont réduits automatiquement pendant 2 minutes maximum quand vous recevez trop de notifications à la fois."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverrouiller pour voir anciennes notifications"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'écran partagé"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passez à l\'appli à gauche ou au-dessus avec l\'écran partagé"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode écran partagé : Remplacer une appli par une autre"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Déplacer la fenêtre active d\'un écran à l\'autre"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Saisie"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Revenir à la langue précédente"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Utilisez moins de <xliff:g id="LENGTH">%1$d</xliff:g> caractères"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversation"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Appuyez sur une conversation pour l\'ajouter à votre écran d\'accueil"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pour une résolution plus élevée, retournez le téléphone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable qui est déplié"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable qui est retourné"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plié"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"déplié"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,33 +1418,26 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis clavier"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis clavier"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Appuyez sur une touche pour attribuer un raccourci"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Rechercher des raccourcis"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icône de touche d\'action ou de méta-touche"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icône Plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personnaliser"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"OK"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Paramètres du clavier"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Définir un raccourci"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuler"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Appuyez sur la touche"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinaison de touches déjà utilisée. Essayez une autre touche."</string>
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide du 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>
-    <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Découvrir les gestes au pavé tactile"</string>
+    <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Découvrez les gestes au pavé tactile"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Naviguer à l\'aide de votre clavier et de votre pavé tactile"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Découvrir les gestes au pavé tactile, les raccourcis clavier et plus encore"</string>
     <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Retour"</string>
@@ -1452,7 +1447,7 @@
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Balayez vers la gauche ou la droite avec trois doigts sur le pavé tactile"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bravo !"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Vous avez appris le geste pour revenir en arrière."</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Vous avez appris le geste pour revenir en arrière"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Retour à l\'accueil"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Balayez vers le haut avec trois doigts sur le pavé tactile"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bravo !"</string>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index d0853f4..ffceb0d 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Désactivé"</item>
     <item msgid="3028994095749238254">"Activé"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Indisponible"</item>
+    <item msgid="6419996398343291862">"Désactivé"</item>
+    <item msgid="5908720590832378783">"Activé"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index ebc19bd..3983606 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audiófonos"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Non se pode axustar o brillo\n porque o controla a aplicación principal"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Xirar automaticamente"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Xirar pantalla automaticamente"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localización"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic para vincular un novo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Non se puido actualizar a configuración predeterminada"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Configuración predeterminada"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Elemento seleccionado"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos instantáneos"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Queres desbloquear o micrófono do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Queres desbloquear a cámara do dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Queres desbloquear a cámara e o micrófono do dispositivo?"</string>
@@ -578,7 +578,7 @@
     <string name="media_projection_task_switcher_notification_channel" msgid="7613206306777814253">"Cambio de aplicación"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"O teu administrador de TI bloqueou esta aplicación"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A política do dispositivo desactivou a opción de capturar a pantalla"</string>
-    <string name="clear_all_notifications_text" msgid="348312370303046130">"Eliminar todo"</string>
+    <string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Xestionar"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
     <string name="notification_settings_button_description" msgid="2441994740884163889">"Configuración de notificacións"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Non hai notificacións"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Non hai notificacións novas"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Agora a opción Amainar notificacións está activada"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Ao recibir moitas notificacións, o volume e as alertas redúcense automaticamente ata dous minutos."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver máis notificacións"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Cambiar á aplicación da dereita ou de abaixo coa pantalla dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Cambiar á aplicación da esquerda ou de arriba coa pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"En modo de pantalla dividida: Substituír unha aplicación por outra"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover ventá activa entre pantallas"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar ao seguinte idioma"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Cambiar ao idioma anterior"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Utiliza menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Toca unha conversa para engadila á pantalla de inicio"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Dálle a volta ao teléfono para gozar dunha maior resolución"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pregable abríndose"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pregable xirando"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"dispositivo pregado"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"dispositivo despregado"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidade"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Atallos de teclado"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar os atallos de teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Preme a tecla para asignar o atallo"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Busca atallos"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Non hai resultados de busca"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona de contraer"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icona da tecla Meta ou de acción"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icona do signo máis"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Feito"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuración do teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Definir atallo"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Preme unha tecla"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Xa se está usando esta combinación de teclas. Proba con outra."</string>
     <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>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index 18ad3df..7889983 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Desactivados"</item>
     <item msgid="3028994095749238254">"Activados"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Non dispoñible"</item>
+    <item msgid="6419996398343291862">"Opción desactivada"</item>
+    <item msgid="5908720590832378783">"Opción activada"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index d5e7ca4..8901269 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ઇનપુટ"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"સાંભળવામાં મદદ આપતા યંત્રો"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ચાલુ કરી રહ્યાં છીએ…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"બ્રાઇટનેસ ગોઠવી શકતા નથી કારણ કે તે\n લોકપ્રિય ઍપ દ્વારા નિયંત્રિત કરવામાં આવી રહી છે"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ઑટો રોટેટ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ઑટો રોટેટ સ્ક્રીન"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"લોકેશન"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"નવા ડિવાઇસ સાથે જોડાણ કરવા માટે ક્લિક કરો"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"પ્રીસેટ અપડેટ કરી શક્યા નથી"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"પ્રીસેટ"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"પસંદ કરી છે"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ટૂલ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"લાઇવ કૅપ્શન"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"નોંધ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ડિવાઇસના માઇક્રોફોનને અનબ્લૉક કરીએ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ડિવાઇસના કૅમેરાને અનબ્લૉક કરીએ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ડિવાઇસના કૅમેરા અને માઇક્રોફોનને અનબ્લૉક કરીએ?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે જમણી બાજુ કે નીચેની ઍપ પર સ્વિચ કરો"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે ડાબી બાજુની કે ઉપરની ઍપ પર સ્વિચ કરો"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"વિભાજિત સ્ક્રીન દરમિયાન: એક ઍપને બીજી ઍપમાં બદલો"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"સક્રિય વિન્ડોને ડિસ્પ્લેની વચ્ચે ખસેડો"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ઇનપુટ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"આગલી ભાષા પર સ્વિચ કરો"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"પાછલી ભાષા પર સ્વિચ કરો"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> કરતાં ઓછા અક્ષરનો ઉપયોગ કરો"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"વાતચીતના વિજેટ"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"તમારી હોમ સ્ક્રીનમાં વાતચીત ઉમેરવા માટે તેના પર ટૅપ કરો"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"વધુ રિઝોલ્યુશન માટે, ફોનને ફ્લિપ કરો"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ અનફોલ્ડ કરવામાં આવી રહ્યું છે"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ ફ્લિપ કરવામાં આવી રહ્યું છે"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ફોલ્ડ કરેલું"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"અનફોલ્ડ કરેલું"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ઍક્સેસિબિલિટી"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"કીબોર્ડ શૉર્ટકટ"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"કીબોર્ડ શૉર્ટકટને કસ્ટમાઇઝ કરો"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"શૉર્ટકટ સોંપવા માટે દી દબાવો"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"શૉર્ટકટ શોધો"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"કોઈ શોધ પરિણામો નથી"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\'નાનું કરો\'નું આઇકન"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ઍક્શન અથવા મેટા કીનું આઇકન"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"પ્લસનું આઇકન"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"કસ્ટમાઇઝ કરો"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"થઈ ગયું"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"કીબોર્ડના સેટિંગ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"શૉર્ટકટ સેટ કરો"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"રદ કરો"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"કી દબાવો"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"કી સંયોજન પેહલેથી ઉપયોગમાં છે. અન્ય કી અજમાવી જુઓ."</string>
     <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>
@@ -1459,11 +1455,11 @@
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"તાજેતરની ઍપ જુઓ"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"તમારા ટચપૅડ પર ત્રણ આંગળીઓનો ઉપયોગ કરીને ઉપર સ્વાઇપ કરો અને દબાવી રાખો"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ખૂબ સરસ કામ!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"તમે \"તાજેતરની ઍપ જુઓ\" સંકેત પૂર્ણ કર્યો."</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"તમે \'તાજેતરની ઍપ જુઓ\' સંકેત પૂર્ણ કર્યો."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"બધી ઍપ જુઓ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"તમારા કીબોર્ડ પરની ઍક્શન કી દબાવો"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"વાહ!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"તમે \"બધી ઍપ જુઓ\" સંકેત પૂર્ણ કર્યો"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"તમે \'બધી ઍપ જુઓ\' સંકેત પૂર્ણ કર્યો"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"કીબોર્ડની બૅકલાઇટ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dમાંથી %1$d લેવલ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ઘરેલું સાધનોના નિયંત્રણો"</string>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index e620232..8c8d5f6 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"બંધ છે"</item>
     <item msgid="3028994095749238254">"ચાલુ છે"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"અનુપલબ્ધ"</item>
+    <item msgid="6419996398343291862">"બંધ"</item>
+    <item msgid="5908720590832378783">"ચાલુ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index cad756d..241e2e6 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -109,12 +109,12 @@
     <string name="screenrecord_title" msgid="4257171601439507792">"स्क्रीन रिकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
-    <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"क्या आपको स्क्रीन रिकॉर्ड करनी है?"</string>
-    <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक ऐप्लिकेशन की रिकॉर्डिंग करें"</string>
+    <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"क्या आपको स्क्रीन को रिकॉर्ड करना है?"</string>
+    <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक ऐप्लिकेशन रिकॉर्ड करें"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूरी स्क्रीन रिकॉर्ड करें"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"पूरी स्क्रीन रिकॉर्ड करें: %s"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"पूरी स्क्रीन रिकॉर्ड करते समय, स्क्रीन पर दिखने वाली हर चीज़ रिकॉर्ड की जाती है. इसलिए पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज,  डिवाइस पर चल रहे ऑडियो और वीडियो, और फ़ोटो जैसी चीज़ों को लेकर सावधानी बरतें."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"किसी ऐप्लिकेशन को रिकॉर्ड करने के दौरान, उस पर दिख रहा कॉन्टेंट या चल रहा मीडिया दूसरी स्क्रीन पर भी रिकॉर्ड होता है. इसलिए, रिकॉर्ड करते समय पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, ऑडियो, और वीडियो को लेकर सावधानी बरतें."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"किसी ऐप्लिकेशन को रिकॉर्ड करने के दौरान, उस पर दिख रहा कॉन्टेंट या चल रहा मीडिया भी रिकॉर्ड होता है. इसलिए, रिकॉर्ड करते समय पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, ऑडियो, और वीडियो को लेकर सावधानी बरतें."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रिकॉर्ड करें"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"रिकॉर्ड करने के लिए ऐप्लिकेशन चुनें"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"ऑडियो रिकॉर्ड करें"</string>
@@ -125,7 +125,7 @@
     <string name="screenrecord_continue" msgid="4055347133700593164">"शुरू करें"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"स्क्रीन को रिकॉर्ड किया जा रहा है"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"स्क्रीन और ऑडियो, दोनों रिकॉर्ड हो रहे हैं"</string>
-    <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्क्रीन को कहां-कहां छुआ गया, यह दिखाएं"</string>
+    <string name="screenrecord_taps_label" msgid="1595690528298857649">"दिखाएं कि स्क्रीन पर कहां-कहां टच किया जा रहा है"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"रोकें"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"शेयर करें"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रीन रिकॉर्डिंग सेव की गई"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"कान की मशीनें"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ब्लूटूथ चालू हो रहा है…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"स्क्रीन की रोशनी को एडजस्ट नहीं किया जा सकता, क्योंकि\n इसे टॉप ऐप्लिकेशन कंट्रोल कर रहा है"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रीन का अपने-आप दिशा बदलना (ऑटो-रोटेट)"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"जगह की जानकारी"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नया डिवाइस जोड़ने के लिए क्लिक करें"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट नहीं किया जा सका"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चुना गया"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव कैप्शन"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"क्या आपको माइक्रोफ़ोन का ऐक्सेस अनब्लॉक करना है?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"क्या आपको कैमरे का ऐक्सेस अनब्लॉक करना है?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"क्या आप डिवाइस का कैमरा और माइक्रोफ़ोन अनब्लॉक करना चाहते हैं?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"बंद है"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"सेट नहीं है"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"सेटिंग में जाकर मैनेज करें"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{कोई मोड चालू नहीं है}=1{{mode} चालू है}one{# मोड चालू है}other{# मोड चालू हैं}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{कोई मोड चालू नहीं है}=1{{mode} मोड चालू है}one{# मोड चालू है}other{# मोड चालू हैं}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"आपको अलार्म, रिमाइंडर, इवेंट और चुनिंदा कॉल करने वालों के अलावा किसी और तरह से (आवाज़ करके और थरथरा कर ) परेशान नहीं किया जाएगा. आप फिर भी संगीत, वीडियो और गेम सहित अपना चुना हुआ सब कुछ सुन सकते हैं."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"आपको अलार्म छोड़कर दूसरी आवाज़ों और कंपनों से परेशान नहीं किया जाएगा. आपको अब भी संगीत, वीडियो और गेम सहित वह सब कुछ सुनाई देगा जो आपने चलाने के लिए चुना है."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"अपनी पसंद के मुताबिक बनाएं"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"अभी शुरू करें"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"कोई सूचना नहीं है"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"कोई नई सूचना नहीं है"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"लगातार सूचनाएं आने पर आवाज़ कम करने की सेटिंग चालू है"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"एक साथ कई सूचनाएं मिलने पर, डिवाइस में सूचनाओं से होने वाली आवाज़ और सूचनाएं, दो मिनट के लिए अपने-आप कम हो जाएंगी."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"बंद करें"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"पुरानी सूचाएं देखने के लिए अनलॉक करें"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन पर, दाईं ओर या नीचे के ऐप पर स्विच करने के लिए"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन पर, बाईं ओर या ऊपर के ऐप पर स्विच करने के लिए"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीन के दौरान: एक ऐप्लिकेशन को दूसरे ऐप्लिकेशन से बदलें"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ऐक्टिव विंडो को एक से दूसरे डिसप्ले पर स्विच करें"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"इनपुट"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"अगली भाषा पर स्विच करने के लिए"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"पिछली भाषा पर स्विच करने के लिए"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> वर्ण से कम इस्तेमाल करें"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"बातचीत वाला विजेट"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"किसी बातचीत को होम स्क्रीन पर जोड़ने के लिए, उस बातचीत पर टैप करें"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"बेहतर रिज़ॉल्यूशन वाली फ़ोटो खींचने के लिए, फ़ोन को फ़्लिप करें"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फ़ोल्ड किया जा सकने वाला डिवाइस अनफ़ोल्ड किया जा रहा है"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फ़ोल्ड किया जा सकने वाला डिवाइस पलटा जा रहा है"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"डिवाइस फ़ोल्ड किया गया"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"डिवाइस अनफ़ोल्ड किया गया"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,55 +1418,48 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट को पसंद के मुताबिक बनाएं"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"शॉर्टकट असाइन करने के लिए बटन दबाएं"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शॉर्टकट खोजें"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"खोज का कोई नतीजा नहीं मिला"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"छोटा करने का आइकॉन"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ऐक्शन या मेटा बटन का आइकॉन"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"प्लस का आइकॉन"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"पसंद के मुताबिक बनाएं"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"हो गया"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"कीबोर्ड सेटिंग"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"शॉर्टकट सेट करें"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द करें"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"बटन दबाएं"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"बटन का यह कॉम्बिनेशन पहले से इस्तेमाल किया जा रहा है. कोई दूसरा कॉम्बिनेशन आज़माएं."</string>
     <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>
     <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"टचपैड से जुड़े जेस्चर के बारे में जानें"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"कीबोर्ड और टचपैड का इस्तेमाल करके नेविगेट करें"</string>
-    <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"टचपैड पर हाथ के जेस्चर, कीबोर्ड शॉर्टकट वगैरह के बारे में जानें"</string>
+    <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"टचपैड से जुड़े जेस्चर, कीबोर्ड शॉर्टकट वगैरह के बारे में जानें"</string>
     <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"वापस जाएं"</string>
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"होम स्क्रीन पर जाएं"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखें"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"हो गया"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"वापस जाएं"</string>
-    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"अपने टचपैड पर तीन उंगलियों का इस्तेमाल करके, बाईं या दाईं ओर स्वाइप करें"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"अपने टचपैड पर तीन उंगलियों से बाईं या दाईं ओर स्वाइप करें"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"बढ़िया!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"अब आपने जान लिया है कि हाथ का जेस्चर इस्तेमाल करके, पिछली स्क्रीन पर वापस कैसे जाएं."</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"अब आपको हाथ के जेस्चर का इस्तेमाल करके, पिछली स्क्रीन पर वापस जाने का तरीका पता चल गया है."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"होम स्क्रीन पर जाएं"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"अपने टचपैड पर तीन उंगलियों से ऊपर की ओर स्वाइप करें"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"बहुत बढ़िया!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"अब आपको हाथ के जेस्चर का इस्तेमाल करके होम स्क्रीन पर जाने का तरीका पता चल गया है"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखें"</string>
-    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"अपने टचपैड पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और फिर होल्ड करें"</string>
+    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"अपने टचपैड पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और दबाकर रखें"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"बहुत बढ़िया!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"आपने हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखने के लिए, हाथ के जेस्चर के बारे में जान लिया है."</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"अब आपको हाथ के जेस्चर का इस्तेमाल करके, हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखने का तरीका पता चल गया है."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"सभी ऐप्लिकेशन देखें"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"अपने कीबोर्ड पर ऐक्शन बटन दबाएं"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"बहुत खूब!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"अब आपको इस बारे में जानकारी है कि सभी ऐप्लिकेशन देखने के लिए, हाथ के जेस्चर का इस्तेमाल कैसे किया जाता है"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"अब आपको हाथ के जेस्चर का इस्तेमाल करके, सभी ऐप्लिकेशन देखने का तरीका पता चल गया है"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड की बैकलाइट"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d में से %1$d लेवल"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index 6aa9078..69a4e4d 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"बंद हैं"</item>
     <item msgid="3028994095749238254">"चालू हैं"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"उपलब्ध नहीं है"</item>
+    <item msgid="6419996398343291862">"बंद है"</item>
+    <item msgid="5908720590832378783">"चालू है"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 3a01d94..a17964992 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Unos"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušna pomagala"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključivanje…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Svjetlina se ne može prilagoditi jer njome\n upravlja aplikacija pri vrhu"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatsko zakretanje"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko zakretanje zaslona"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili novi uređaj"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje unaprijed definiranih postavki nije uspjelo"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unaprijed definirana postavka"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Napomena"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite li deblokirati mikrofon uređaja?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite li deblokirati kameru uređaja?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite li deblokirati kameru i mikrofon uređaja?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prelazak na aplikaciju zdesna ili ispod uz podijeljeni zaslon"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prelazak na aplikaciju slijeva ili iznad uz podijeljeni zaslon"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijekom podijeljenog zaslona: zamijeni aplikaciju drugom"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Premještanje aktivnog prozora između zaslona"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Prelazak na sljedeći jezik"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Prelazak na prethodni jezik"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Upotrijebite manje od ovoliko znakova: <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgeti razgovora"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite razgovor da biste ga dodali na početni zaslon"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu razlučivost okrenite telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rasklopljen sklopivi uređaj"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Okretanje sklopivog uređaja sa svih strana"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zatvoreno"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otvoreno"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tipkovni prečaci"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodba tipkovnih prečaca"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite tipku da biste dodijelili prečac"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečaci za pretraživanje"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za sažimanje"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tipke za radnju odnosno meta tipka"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona plusa"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotovo"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tipkovnice"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavite prečac"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Odustani"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacija tipki već se upotrebljava. Pokušajte s drugom tipkom."</string>
     <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>
@@ -1451,25 +1447,25 @@
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Natrag"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Prijeđite ulijevo ili udesno trima prstima na dodirnoj podlozi"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Odlično!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Izvršili ste pokret za povratak."</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Napravili ste pokret za povratak."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Na početnu stranicu"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Prijeđite prema gore trima prstima na dodirnoj podlozi"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Sjajno!"</string>
-    <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Izvršili ste pokret za otvaranje početnog zaslona"</string>
+    <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Napravili ste pokret za otvaranje početnog zaslona"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Pregled nedavnih aplikacija"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Prijeđite prema gore trima prstima na dodirnoj podlozi i zadržite pritisak"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Sjajno!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Izvršili ste pokret za prikaz nedavno korištenih aplikacija."</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Napravili ste pokret za prikaz nedavno korištenih aplikacija."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Prikaži sve aplikacije"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipku za radnju na tipkovnici"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Izvrsno!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Izvršili ste pokret za prikaz svih aplikacija"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Napravili ste pokret za prikaz svih aplikacija"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tipkovnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Razina %1$d od %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Upravljanje uređajima"</string>
     <string name="home_controls_dream_description" msgid="4644150952104035789">"Brzo upravljajte uređajima putem čuvara zaslona"</string>
     <string name="volume_undo_action" msgid="5815519725211877114">"Poništi"</string>
-    <string name="back_edu_toast_content" msgid="4530314597378982956">"Za povratak prijeđite ulijevo ili udesno trima prstima na dodirnoj podlozi"</string>
+    <string name="back_edu_toast_content" msgid="4530314597378982956">"Za povratak trima prstima prijeđite ulijevo ili udesno na dodirnoj podlozi"</string>
     <string name="home_edu_toast_content" msgid="3381071147871955415">"Da biste se vratili na početni zaslon, prijeđite prema gore trima prstima na dodirnoj podlozi."</string>
     <string name="overview_edu_toast_content" msgid="5797030644017804518">"Za prikaz nedavnih aplikacija prijeđite prema gore trima prstima i zadržite pritisak na dodirnoj podlozi"</string>
     <string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Za prikaz svojih svih aplikacija pritisnite tipku za radnju na tipkovnici"</string>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index 3f8841a..2401e4a 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Isključeno"</item>
     <item msgid="3028994095749238254">"Uključeno"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Nedostupno"</item>
+    <item msgid="6419996398343291862">"Isključeno"</item>
+    <item msgid="5908720590832378783">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c9e20f8..4b5b916 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Bevitel"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hallókészülék"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Bekapcsolás…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nem lehet módosítani a fényerőt, mert a felső alkalmazás\n vezérli"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatikus elforgatás"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatikus képernyőforgatás"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Tartózkodási hely"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kattintson új eszköz párosításához"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nem sikerült frissíteni a beállításkészletet"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Beállításkészlet"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Kiválasztva"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eszközök"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Élő feliratozás"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Megjegyzés"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Feloldja az eszköz mikrofonjának letiltását?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Feloldja az eszköz kamerájának letiltását?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Feloldja az eszköz kamerájának és mikrofonjának letiltását?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"Ki"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"Nincs beállítva"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"A Beállítások között kezelheti"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nincs aktív mód}=1{A(z) {mode} aktív}other{# mód aktív}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nincs aktív mód}=1{{mode} aktív}other{# mód aktív}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"Az Ön által meghatározott ébresztéseken, emlékeztetőkön, eseményeken és hívókon kívül nem fogja Önt más hang vagy rezgés megzavarni. Továbbra is lesz hangjuk azoknak a tartalmaknak, amelyeket Ön elindít, például zenék, videók és játékok."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"Az ébresztéseken kívül nem fogja Önt más hang és rezgés megzavarni. Továbbra is lesz hangjuk azoknak a tartalmaknak, amelyeket Ön elindít, például zenék, videók és játékok."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Személyre szabás"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nincs értesítés"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nincsenek új értesítések"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Az értesítések befagyasztása mostantól be van kapcsolva"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Az eszköz hangerejét és értesítéseit a rendszer automatikusan legfeljebb két percig csökkenti, ha egyszerre túl sok értesítést kap."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Igen"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"A régebbiek feloldás után láthatók"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Váltás a jobb oldalt, illetve lent lévő appra osztott képernyő esetén"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Váltás a bal oldalt, illetve fent lévő appra osztott képernyő esetén"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Osztott képernyőn: az egyik alkalmazás lecserélése egy másikra"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktív ablak áthelyezése egyik kijelzőről a másikra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Bevitel"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Váltás a következő nyelvre"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Váltás az előző nyelvre"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Legfeljebb <xliff:g id="LENGTH">%1$d</xliff:g> karaktert használhat"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Beszélgetési modulok"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Koppintson a kívánt beszélgetésre a kezdőképernyőre való felvételhez"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"A nagyobb felbontás érdekében fordítsa meg a telefont"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Összehajtható eszköz kihajtása"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Összehajtható eszköz körbeforgatása"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"összehajtva"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kihajtva"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kisegítő lehetőségek"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Billentyűparancsok"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"A billentyűparancsok személyre szabása"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Nyomja meg a billentyűt a parancsikon hozzárendeléséhez"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Billentyűparancsok keresése"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nincsenek keresési találatok"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Összecsukás ikon"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Művelet vagy Meta billentyű ikonja"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pluszikon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Személyre szabás"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Kész"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Billentyűzetbeállítások"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Billentyűparancs beállítása"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Mégse"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Nyomja le a billentyűt"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"A billentyűkombináció már használatban van. Próbálkozzon másik kulccsal."</string>
     <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>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index 76b3410..8911fe9 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Ki"</item>
     <item msgid="3028994095749238254">"Be"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Nem áll rendelkezésre"</item>
+    <item msgid="6419996398343291862">"Ki"</item>
+    <item msgid="5908720590832378783">"Be"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 1d46bc2..a062098 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Երբ դուք տեսագրում եք ամբողջ էկրանը, էկրանին ցուցադրվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Երբ դուք որևէ հավելված եք տեսագրում, հավելվածում ցուցադրվող կամ նվագարկվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Տեսագրել էկրանը"</string>
-    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Հավելվածի ընտրություն՝ տեսագրելու համար"</string>
+    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Հավելված ընտրեք՝ տեսագրելու համար"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Ձայնագրել"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Սարքի ձայները"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Ձեր սարքի ձայները, օրինակ՝ երաժշտությունը, զանգերն ու զանգերանգները"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Մուտքագրում"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Լսողական սարք"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Միացում…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Հնարավոր չէ կարգավորել պայծառությունը, քանի որ այն\n կառավարվում է գլխավոր հավելվածի կողմից"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ինքնապտտում"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ավտոմատ պտտել էկրանը"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Տեղորոշում"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Սեղմեք՝ նոր սարք զուգակցելու համար"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Չհաջողվեց թարմացնել կարգավորումների հավաքածուն"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Կարգավորումների հավաքածու"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ընտրված է"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Գործիքներ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Կենդանի ենթագրեր"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Նշում"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Արգելահանե՞լ սարքի խոսափողը"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Արգելահանե՞լ սարքի տեսախցիկը"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Արգելահանե՞լ սարքի տեսախցիկը և խոսափողը"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"Անջատված է"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"Կարգավորված չէ"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Կառավարել կարգավորումներում"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Ակտիվ ռեժիմներ չկան}=1{{mode} ռեժիմ ակտիվ է}one{# ռեժիմ ակտիվ է}other{# ռեժիմ ակտիվ է}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Ակտիվ ռեժիմ չկա}=1{{mode} ռեժիմն ակտիվ է}one{# ռեժիմ ակտիվ է}other{# ռեժիմ ակտիվ է}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"Ձայները և թրթռոցները չեն անհանգստացնի ձեզ, բացի ձեր կողմից նշված զարթուցիչները, հիշեցումները, միջոցառումների ծանուցումները և զանգերը։ Դուք կլսեք ձեր ընտրածի նվագարկումը, այդ թվում՝ երաժշտություն, տեսանյութեր և խաղեր:"</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"Ձայները և թրթռոցները, բացի զարթուցիչներից, չեն անհանգստացնի ձեզ: Դուք կլսեք ձեր ընտրածի նվագարկումը, այդ թվում՝ երաժշտություն, տեսանյութեր և խաղեր:"</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Հարմարեցնել"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Անցեք աջ կողմի կամ ներքևի հավելվածին տրոհված էկրանի միջոցով"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Անցեք աջ կողմի կամ վերևի հավելվածին տրոհված էկրանի միջոցով"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Տրոհված էկրանի ռեժիմում մեկ հավելվածը փոխարինել մյուսով"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Տեղափոխել ակտիվ պատուհանը էկրանների միջև"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ներածում"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Անցնել հաջորդ լեզվին"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Անցնել նախորդ լեզվին"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Օգտագործեք մինչև <xliff:g id="LENGTH">%1$d</xliff:g> նիշ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Զրույցի վիջեթներ"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Հպեք զրույցին՝ այն հիմնական էկրանին ավելացնելու համար"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ավելի մեծ լուծաչափի համար շրջեք հեռախոսը"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ծալովի սարք՝ բացված վիճակում"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Ծալովի սարք՝ շրջված վիճակում"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ծալված"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"բացված"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Հատուկ գործառույթներ"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Ստեղնային դյուրանցումներ"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Կարգավորեք ստեղնային դյուրանցումներ"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Սեղմեք որևէ ստեղն՝ դյուրանցում նշանակելու համար"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Դյուրանցումների որոնում"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Որոնման արդյունքներ չկան"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ծալել պատկերակը"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Գործողության կամ Meta ստեղնի պատկերակ"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Պլյուս պատկերակ"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Կարգավորել"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Պատրաստ է"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ստեղնաշարի կարգավորումներ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ստեղծել դյուրանցում"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Չեղարկել"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Սեղմեք որևէ ստեղն"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ստեղների համակցությունն արդեն օգտագործվում է։ Ընտրեք այլ ստեղն։"</string>
     <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>
@@ -1458,7 +1454,7 @@
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Դիտել վերջին հավելվածները"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Երեք մատով սահեցրեք վերև և սեղմած պահեք հպահարթակին"</string>
-    <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Կեցցե՛ք։"</string>
+    <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Կեցցե՛ք"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Դուք կատարեցիք վերջին օգտագործված հավելվածների դիտման ժեստը։"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ինչպես դիտել բոլոր հավելվածները"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Սեղմեք գործողության ստեղնը ստեղնաշարի վրա"</string>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index ce930c3..f2b09e0 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Անջատված է"</item>
     <item msgid="3028994095749238254">"Միացված է"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Հասանելի չէ"</item>
+    <item msgid="6419996398343291862">"Անջատված է"</item>
+    <item msgid="5908720590832378783">"Միացված է"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 1535314..cf9b093 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Alat bantu dengar"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Mengaktifkan…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Tidak dapat menyesuaikan kecerahan karena sedang\n dikontrol oleh aplikasi atas"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Putar Otomatis"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Putar layar otomatis"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menyambungkan perangkat baru"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat memperbarui preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alat"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Teks Otomatis"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Catatan"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Berhenti memblokir mikrofon perangkat?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Berhenti memblokir kamera perangkat?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Berhenti memblokir kamera dan mikrofon perangkat?"</string>
@@ -565,7 +565,7 @@
     <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Transmisikan seluruh layar"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"JIka Anda mentransmisikan seluruh layar, semua hal yang ada di layar Anda akan terlihat. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Jika Anda mentransmisikan aplikasi, semua hal yang ditampilkan atau diputar di aplikasi tersebut akan terlihat. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
-    <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Layar Cast"</string>
+    <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Transmisikan layar"</string>
     <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Pilih aplikasi yang akan ditransmisikan"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Mulai berbagi?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Jika Anda membagikan, merekam, atau mentransmisikan, Android akan memiliki akses ke semua hal yang ditampilkan di layar atau yang diputar di perangkat Anda. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Tidak ada notifikasi"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Tidak ada notifikasi baru"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Pengurangan suara dan getaran notifikasi kini aktif"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Saat Anda menerima terlalu banyak notifikasi sekaligus, volume dan getaran perangkat akan otomatis dikurangi hingga selama 2 menit."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Nonaktifkan"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Buka kunci untuk melihat notifikasi lama"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Beralih ke aplikasi di bagian kanan atau bawah saat menggunakan layar terpisah"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Beralih ke aplikasi di bagian kiri atau atas saat menggunakan layar terpisah"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Dalam layar terpisah: ganti salah satu aplikasi dengan yang lain"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Memindahkan jendela aktif dari satu layar ke layar lainnya"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Beralih ke bahasa berikutnya"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Beralih ke bahasa sebelumnya"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gunakan kurang dari <xliff:g id="LENGTH">%1$d</xliff:g> karakter"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widget Percakapan"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Ketuk percakapan untuk menambahkannya ke Layar utama"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Untuk resolusi lebih tinggi, balik ponsel"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Perangkat foldable sedang dibentangkan"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Perangkat foldable sedang dibalik"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ditutup"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"dibuka"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,30 +1418,23 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aksesibilitas"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan keyboard"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Menyesuaikan pintasan keyboard"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tekan tombol untuk menetapkan pintasan"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Telusuri pintasan"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tidak ada hasil penelusuran"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon ciutkan"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon tombol Tindakan atau Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikon plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sesuaikan"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Selesai"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Setelan Keyboard"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
-    <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Menavigasi menggunakan keyboard"</string>
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Setel pintasan"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Batal"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tekan tombol"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinasi tombol sudah digunakan. Coba tombol lain."</string>
+    <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Menggunakan keyboard untuk navigasi"</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>
     <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Pelajari gestur touchpad"</string>
@@ -1451,8 +1446,8 @@
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Selesai"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Geser ke kiri atau kanan menggunakan tiga jari di touchpad"</string>
-    <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bagus!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah menyelesaikan gestur kembali."</string>
+    <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Sip!"</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah menyelesaikan gestur untuk kembali."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Buka layar utama"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Geser ke atas dengan tiga jari di touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bagus!"</string>
@@ -1463,7 +1458,7 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Anda telah menyelesaikan gestur untuk melihat aplikasi terbaru."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Lihat semua aplikasi"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan tombol tindakan di keyboard"</string>
-    <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bagus!"</string>
+    <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Oke!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Anda telah menyelesaikan gestur untuk melihat semua aplikasi"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Lampu latar keyboard"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tingkat %1$d dari %2$d"</string>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index 5570edb..7462ff6 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Nonaktif"</item>
     <item msgid="3028994095749238254">"Aktif"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Tidak tersedia"</item>
+    <item msgid="6419996398343291862">"Nonaktif"</item>
+    <item msgid="5908720590832378783">"Aktif"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index edead8f..fe32aba 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -113,10 +113,10 @@
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Taka upp eitt forrit"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Taka upp allan skjáinn"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Taka upp allan skjáinn: %s"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Þegar þú tekur upp allan skjáinn verður allt sem er sýnilegt á skjánum tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Þegar þú tekur upp forrit verður allt sem er sýnilegt eða spilað í forritinu tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Þegar þú tekur upp allan skjáinn verður allt sem er sýnilegt á skjánum tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Þegar þú tekur upp forrit verður allt sem er sýnilegt eða spilað í forritinu tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Taka upp skjá"</string>
-    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Velja forrit til að taka upp"</string>
+    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Veldu forrit til að taka upp"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Taka upp hljóð"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Hljóð tækis"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Hljóð úr tækinu á borð við tónlist, símtöl og hringitóna"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Inntak"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Heyrnartæki"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Kveikir…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ekki er hægt að breyta birtustiginu vegna þess að \n efsta forritið stjórnar því"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Sjálfvirkur snúningur"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Snúa skjá sjálfkrafa"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Staðsetning"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Smelltu til að para nýtt tæki"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tókst ekki að uppfæra forstillingu"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forstilling"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valið"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verkfæri"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Skjátextar í rauntíma"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Glósa"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Opna fyrir hljóðnema tækisins?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Opna fyrir myndavél tækisins?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Opna fyrir myndavél og hljóðnema tækisins?"</string>
@@ -555,8 +555,8 @@
     <string name="screen_share_permission_dialog_option_entire_screen" msgid="4493174362775038997">"Deila öllum skjánum"</string>
     <!-- no translation found for media_projection_entry_app_permission_dialog_option_text_entire_screen (5100078808078139706) -->
     <skip />
-    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Þegar þú deilir öllum skjánum verður allt á skjánum sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Þegar þú deilir forriti er allt sem sést eða er spilað í því forriti sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Þegar þú deilir öllum skjánum verður allt á skjánum sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Þegar þú deilir forriti er allt sem sést eða er spilað í því forriti sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deila skjá"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> slökkti á þessum valkosti"</string>
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Velja forrit til að deila"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skiptu í forrit til hægri eða fyrir neðan þegar skjáskipting er notuð"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skiptu í forrit til vinstri eða fyrir ofan þegar skjáskipting er notuð"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Í skjáskiptingu: Skipta forriti út fyrir annað forrit"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Færa virkan glugga á milli skjáa"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Innsláttur"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Skipta yfir í næsta tungumál"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Skipta yfir í fyrra tungumál"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Notaðu færri en <xliff:g id="LENGTH">%1$d</xliff:g> stafi"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Samtalsgræjur"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Ýttu á samtal til að bæta því á heimaskjáinn"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Snúðu símanum til að fá betri upplausn"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Samanbrjótanlegt tæki opnað"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Samanbrjótanlegu tæki snúið við"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"samanbrotið"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"opið"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aðgengi"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Flýtilyklar"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sérsníddu flýtilykla"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Ýttu á lykil til að stilla flýtileið"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Leita að flýtileiðum"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Engar leitarniðurstöður"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Minnka tákn"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Tákn lýsilykils (aðgerðarlykils)"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plústákn"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sérsníða"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Lokið"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Stillingar lyklaborðs"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Stilltu flýtileið"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Hætta við"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Ýttu á lykil"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Lyklasamsetning er þegar í notkun. Prófaðu annan lykil."</string>
     <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>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index 893ab6c..df3bcf9 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Slökkt"</item>
     <item msgid="3028994095749238254">"Kveikt"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Ekki í boði"</item>
+    <item msgid="6419996398343291862">"Slökkt"</item>
+    <item msgid="5908720590832378783">"Kveikt"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index d7a279b..a66ea91 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ingresso"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Apparecchi acustici"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Attivazione…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Impossibile regolare la luminosità perché è\n controllata dall\'app in primo piano"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotazione automatica"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotazione automatica dello schermo"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Posizione"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic per accoppiare un nuovo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossibile aggiornare preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selezionato"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Strumenti"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sottotitoli in tempo reale"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vuoi sbloccare il microfono del dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vuoi sbloccare la fotocamera del dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vuoi sbloccare la fotocamera e il microfono del dispositivo?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nessuna notifica"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nessuna nuova notifica"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"L\'attenuazione delle notifiche è ora attiva"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volume e avvisi vengono ridotti automaticamente per un massimo di 2 minuti quando ricevi troppe notifiche contemporaneamente."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Disattiva"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Sblocca per vedere le notifiche meno recenti"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passa all\'app a destra o sotto mentre usi lo schermo diviso"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passa all\'app a sinistra o sopra mentre usi lo schermo diviso"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Con lo schermo diviso: sostituisci un\'app con un\'altra"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Sposta la finestra attiva tra gli schermi"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Inserimento"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passa alla lingua successiva"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Passa alla lingua precedente"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Usa meno di <xliff:g id="LENGTH">%1$d</xliff:g> caratteri"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widget di conversazione"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tocca una conversazione per aggiungerla alla schermata Home"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Gira il telefono per una maggiore risoluzione"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pieghevole che viene aperto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pieghevole che viene capovolto"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"Piegato"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"Non piegato"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilità"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Scorciatoie da tastiera"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizza scorciatoie da tastiera"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Premi un tasto per assegnare una scorciatoia"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Scorciatoie per la ricerca"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nessun risultato di ricerca"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona Comprimi"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icona tasto Azione o Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icona Più"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizza"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Fine"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Impostazioni tastiera"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Imposta scorciatoia"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annulla"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Premi un tasto"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinazione di tasti già in uso. Prova con un altro tasto."</string>
     <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>
@@ -1455,11 +1450,11 @@
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Hai completato il gesto Indietro."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Vai alla schermata Home"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Scorri in alto con tre dita sul touchpad"</string>
-    <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Ottimo lavoro."</string>
+    <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Ottimo lavoro!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Hai completato il gesto Vai alla schermata Home"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Visualizza app recenti"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Scorri verso l\'alto e tieni premuto con tre dita sul touchpad"</string>
-    <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Ottimo lavoro."</string>
+    <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Ottimo lavoro!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Hai completato il gesto Visualizza app recenti."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Visualizza tutte le app"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Premi il tasto azione sulla tastiera"</string>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index 784a309..9d26859 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Disattivi"</item>
     <item msgid="3028994095749238254">"Attivi"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Non disponibile"</item>
+    <item msgid="6419996398343291862">"Off"</item>
+    <item msgid="5908720590832378783">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 9064d3d..7b4245e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"קלט"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"מכשירי שמיעה"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ההפעלה מתבצעת…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"לא ניתן להתאים את הבהירות כי היא\n נשלטת על ידי האפליקציה העליונה"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"סיבוב אוטומטי"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"סיבוב אוטומטי של המסך"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"מיקום"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"צריך ללחוץ כדי להתאים מכשיר חדש"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"לא ניתן לעדכן את ההגדרה הקבועה מראש"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"הגדרה קבועה מראש"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"נבחר"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"כלים"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"כתוביות מיידיות"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"פתק"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"לבטל את חסימת המיקרופון של המכשיר?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"לבטל את חסימת המצלמה של המכשיר?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"לבטל את חסימת המצלמה והמיקרופון של המכשיר?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"אין התראות"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"אין התראות חדשות"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"הפוגת ההתראות מופעלת"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"עוצמת הקול וההתראות במכשיר מופחתות אוטומטית למשך עד 2 דקות כשמתקבלות יותר מדי התראות בבת אחת."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"השבתה"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"יש לבטל את הנעילה כדי לראות התראות ישנות"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"מעבר לאפליקציה משמאל או למטה בזמן שימוש במסך מפוצל"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"מעבר לאפליקציה מימין או למעלה בזמן שימוש במסך מפוצל"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"כשהמסך מפוצל: החלפה בין אפליקציה אחת לאחרת"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"העברת החלון הפעיל בין מסכים"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"קלט"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"מעבר לשפה הבאה"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"מעבר לשפה הקודמת"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"אפשר להזין עד <xliff:g id="LENGTH">%1$d</xliff:g> תווים"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"‏מספר Build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"‏מספר ה-Build הועתק ללוח."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"ווידג\'טים של שיחות"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"יש להקיש על שיחה כדי להוסיף אותה למסך הבית"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"כדי לצלם תמונה ברזולוציה גבוהה יותר, כדאי להפוך את הטלפון"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"מכשיר מתקפל עובר למצב לא מקופל"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"מכשיר מתקפל עובר למצב מהופך"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"מצב מקופל"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"מצב לא מקופל"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"‏%1$s‏ / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"נגישות"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"מקשי קיצור"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"התאמה אישית של מקשי הקיצור"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"יש ללחוץ על מקש כדי להקצות מקש קיצור"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"קיצורי דרך לחיפוש"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"אין תוצאות חיפוש"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"סמל הכיווץ"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"סמל מקש הפעולה (\"מטא\")"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"סמל הפלוס"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"התאמה אישית"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"סיום"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"הגדרות המקלדת"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"הגדרה של מקש קיצור"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ביטול"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"יש ללחוץ על מקש"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"שילוב המקשים הזה כבר בשימוש. אפשר לנסות מקש אחר."</string>
     <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>
@@ -1452,19 +1447,19 @@
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"חזרה"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"מחליקים שמאלה או ימינה עם שלוש אצבעות על לוח המגע"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"איזה יופי!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"השלמת את התנועה \'הקודם\'."</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"סיימת לתרגל את התנועה \'הקודם\'."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"מעבר למסך הבית"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"מחליקים כלפי מעלה עם שלוש אצבעות על לוח המגע"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"מעולה!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"סיימת לתרגל את תנועת החזרה למסך הבית"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"הצגת האפליקציות האחרונות"</string>
-    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"מחליקים למעלה ולוחצים לחיצה ארוכה עם שלוש אצבעות על לוח המגע"</string>
+    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"מחליקים למעלה עם שלוש אצבעות על לוח המגע ומשאירים אותן במגע עם הלוח"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"מעולה!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"השלמת את התנועה להצגת האפליקציות האחרונות."</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"סיימת לתרגל את התנועה להצגת האפליקציות האחרונות."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"צפייה בכל האפליקציות"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"צריך להקיש על מקש הפעולה במקלדת"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"כל הכבוד!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"השלמת את התנועה להצגת כל האפליקציות"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"סיימת לתרגל את התנועה להצגת כל האפליקציות"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"התאורה האחורית במקלדת"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏רמה %1$d מתוך %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"שליטה במכשירים"</string>
diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
index e2ba375..d6b9bc8 100644
--- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"מצב מושבת"</item>
     <item msgid="3028994095749238254">"מצב פעיל"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"לא זמין"</item>
+    <item msgid="6419996398343291862">"מושבת"</item>
+    <item msgid="5908720590832378783">"מופעל"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index a23dac8..c4fd62b 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"入力"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"補聴器"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ON にしています…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"明るさはトップ アプリによって\n制御されているため、調整できません"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動回転"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"画面を自動回転します"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"位置情報"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"クリックすると、新しいデバイスをペア設定できます"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"プリセットを更新できませんでした"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"プリセット"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"選択中"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ツール"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"自動字幕起こし"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"注"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"デバイスのマイクのブロックを解除しますか?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"デバイスのカメラのブロックを解除しますか?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"デバイスのカメラとマイクのブロックを解除しますか?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"分割画面の使用時に右側または下部のアプリに切り替える"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"分割画面の使用時に左側または上部のアプリに切り替える"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"分割画面中: アプリを順に置換する"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"アクティブなウィンドウをディスプレイ間で移動する"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"入力"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"次の言語に切り替える"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"前の言語に切り替える"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"使用できる文字数は <xliff:g id="LENGTH">%1$d</xliff:g> 文字未満です"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"空の会話"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"会話ウィジェット"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"会話をタップするとホーム画面に追加されます"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"高解像度で撮るにはスマートフォンを裏返してください"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"折りたたみ式デバイスが広げられている"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"折りたたみ式デバイスがひっくり返されている"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"折りたたんだ状態"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"広げた状態"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ユーザー補助"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"キーボード ショートカット"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"キーボード ショートカットをカスタマイズする"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ショートカットを割り当てるキーを押してください"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"検索ショートカット"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"検索結果がありません"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"閉じるアイコン"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"アクションキーまたはメタキーのアイコン"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"プラスアイコン"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"カスタマイズ"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完了"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"キーボードの設定"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ショートカットの設定"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"キャンセル"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"キーを押してください"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"このキーの組み合わせはすでに使用されています。別のキーを試してください。"</string>
     <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>
@@ -1449,21 +1445,21 @@
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"最近使ったアプリを表示する"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"完了"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"戻る"</string>
-    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"タッチパッドを 3 本の指で左右にスワイプします"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"タッチパッドを 3 本の指で左または右にスワイプします"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"その調子です!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"「戻る」操作を学習しました。"</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"「戻る」ジェスチャーを学習しました。"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"ホームに移動"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"タッチパッドを 3 本の指で上にスワイプします"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"よくできました!"</string>
-    <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"「ホームに移動」操作を学習しました"</string>
+    <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"「ホームに移動」ジェスチャーを学習しました"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"最近使ったアプリを表示する"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"タッチパッドを 3 本の指で上にスワイプして長押しします"</string>
-    <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"よくできました"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"「最近使ったアプリを表示する」操作を学習しました。"</string>
+    <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"よくできました!"</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"「最近使ったアプリを表示する」ジェスチャーを学習しました。"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"すべてのアプリを表示"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"キーボードのアクションキーを押します"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"完了です!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"「すべてのアプリを表示する」操作を学習しました"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"「すべてのアプリを表示する」ジェスチャーを学習しました"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"キーボード バックライト"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"レベル %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ホーム コントロール"</string>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index 683a4e8..81c10e7 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"OFF"</item>
     <item msgid="3028994095749238254">"ON"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"使用不可"</item>
+    <item msgid="6419996398343291862">"OFF"</item>
+    <item msgid="5908720590832378783">"ON"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index d0ff842..7cb3c8a 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"შეყვანა"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"სმენის მოწყობილობები"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ირთვება…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"სიკაშკაშის კორექტირება ვერ ხერხდება, რადგან ის\n იმართება გახსნილი აპის მიერ"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ავტოროტაცია"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ეკრანის ავტომატური შეტრიალება"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"მდებარეობა"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"დააწკაპუნეთ ახალი მოწყობილობის დასაწყვილებლად"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"წინასწარ დაყენებული პარამეტრების განახლება ვერ მოხერხდა"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"წინასწარ დაყენებული"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"არჩეულია"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ხელსაწყოები"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ავტოსუბტიტრები"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"ჩანიშვნა"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"გსურთ მოწყობილობის მიკროფონის განბლოკვა?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"გსურთ მოწყობილობის კამერის განბლოკვა?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"გსურთ მოწყობილობის კამერის და მიკროფონის განბლოკვა?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ეკრანის გაყოფის გამოყენებისას აპზე მარჯვნივ ან ქვემოთ გადართვა"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ეკრანის გაყოფის გამოყენებისას აპზე მარცხნივ ან ზემოთ გადართვა"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ეკრანის გაყოფის დროს: ერთი აპის მეორით ჩანაცვლება"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"აქტიური ფანჯრის გადატანა ეკრანებს შორის"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"შეყვანა"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"შემდეგ ენაზე გადართვა"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"წინა ენაზე გადართვა"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"გამოიყენეთ <xliff:g id="LENGTH">%1$d</xliff:g>-ზე ნაკლები სიმბოლო"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"საუბრის ვიჯეტები"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"შეეხეთ საუბარს მის თქვენს მთავარ ეკრანზე დასამატებლად"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"მაღალი გარჩევადობისთვის ამოაბრუნეთ ტელეფონი"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"დასაკეცი მოწყობილობა იხსნება"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"დასაკეცი მოწყობილობა ტრიალებს"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"დაკეცილი"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"გაშლილი"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"მისაწვდომობა"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"კლავიატურის მალსახმობები"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"კლავიატურის მალსახმობების მორგება"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"მალსახმობის მინიჭებისთვის დააჭირეთ კლავიშს"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ძიების მალსახმობები"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ძიების შედეგები არ არის"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ხატულის ჩაკეცვა"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"მოქმედების ან მეტა კლავიშის ხატულა"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"პლუსის ხატულა"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"მორგება"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"მზადაა"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"კლავიატურის პარამეტრები"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"მალსახმობის დაყენება"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"გაუქმება"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"დააჭირეთ კლავიშს"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"კლავიშების კომბინაცია უკვე გამოიყენება. ცადეთ სხვა კლავიში."</string>
     <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>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index 7c13eb5..6e62ed4e 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"გამორთულია"</item>
     <item msgid="3028994095749238254">"ჩართულია"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"მიუწვდომელია"</item>
+    <item msgid="6419996398343291862">"გამორთული"</item>
+    <item msgid="5908720590832378783">"ჩართული"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 94f8711..4122eee 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Кіріс"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Есту аппараттары"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Қосылып жатыр…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Жарықтықты реттеу мүмкін емес, себебі ол\n жетекші қолданба арқылы басқарылады."</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматты түрде бұру"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматты айналатын экран"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Локация"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Жаңа құрылғыны жұптау үшін басыңыз."</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Параметрлер жинағын жаңарту мүмкін болмады."</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Параметрлер жинағы"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Таңдалды"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Құралдар"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ескертпе"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Құрылғы микрофонын блоктан шығару керек пе?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Құрылғы камерасын блоктан шығару керек пе?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Құрылғы камерасы мен микрофонын блоктан шығару керек пе?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Хабарландырулар жоқ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңа хабарландырулар жоқ"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Хабарландыру дыбысын азайту параметрі енді қосулы"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Бір уақытта тым көп хабарландыру келсе, дыбыс деңгейі автоматты түрде азайтылып, хабарландырулар 2 минутқа кідіртіледі."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өшіру"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ескі хабарландырулар үшін құлыпты ашыңыз"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Бөлінген экранда оң не төмен жақтағы қолданбаға ауысу"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Бөлінген экранда сол не жоғары жақтағы қолданбаға ауысу"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлу кезінде: бір қолданбаны басқасымен алмастыру"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Дисплейлер арасында қосулы терезені ауыстыру"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Енгізу"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Келесі тілге ауысу"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Алдыңғы тілге ауысу"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Ең көбі <xliff:g id="LENGTH">%1$d</xliff:g> таңба пайдаланыңыз."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Әңгіме виджеттері"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Негізгі экранға қосқыңыз келетін әңгімені түртіңіз."</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Жоғары ажыратымдылық үшін телефонды айналдырыңыз."</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Бүктемелі құрылғы ашылып жатыр."</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Бүктемелі құрылғы аударылып жатыр."</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"жабық"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ашық"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Пернелер тіркесімін бейімдеу"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Жылдам пәрменді тағайындау үшін пернені басыңыз."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Іздеу жылдам пәрмендері"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Іздеу нәтижелері жоқ."</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жию белгішесі"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Әрекет немесе Meta пернесінің белгішесі"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Қосу белгішесі"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Бейімдеу"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Дайын"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Пернетақта параметрлері"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Жылдам пәрменді орнату"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Бас тарту"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Пернені басыңыз"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Бұл пернелер тіркесімі қазір қолданыста. Басқа пернені таңдаңыз."</string>
     <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>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index 2b4c1ac..66deff6 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Өшірулі"</item>
     <item msgid="3028994095749238254">"Қосулы"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Қолжетімді емес"</item>
+    <item msgid="6419996398343291862">"Өшірулі"</item>
+    <item msgid="5908720590832378783">"Қосулы"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 2b17818..f9ec58f 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"បញ្ចូល"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ឧបករណ៍ជំនួយការស្ដាប់"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"កំពុង​បើក..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"មិនអាចកែតម្រូវកម្រិតពន្លឺបានទេ ដោយសារវាកំពុងស្ថិតក្រោម\nការគ្រប់គ្រងរបស់កម្មវិធីខាងលើគេ"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"បង្វិល​ស្វ័យ​ប្រវត្តិ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"បង្វិលអេក្រង់ស្វ័យប្រវត្តិ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ទី​តាំង​"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ចុច ដើម្បីផ្គូផ្គងឧបករណ៍ថ្មី"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"មិនអាច​ប្ដូរ​ការកំណត់ជាមុន​បានទេ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"កំណត់ជាមុន"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"បានជ្រើសរើស"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ឧបករណ៍"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"អក្សររត់ក្នុងពេលជាក់ស្ដែង"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"កំណត់ចំណាំ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ឈប់ទប់ស្កាត់​មីក្រូហ្វូន​របស់ឧបករណ៍ឬ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ឈប់ទប់ស្កាត់​កាមេរ៉ា​របស់ឧបករណ៍ឬ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ឈប់ទប់ស្កាត់​កាមេរ៉ា និងមីក្រូហ្វូន​របស់ឧបករណ៍ឬ?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ប្ដូរទៅកម្មវិធីនៅខាងស្ដាំ ឬខាងក្រោម ពេលកំពុងប្រើមុខងារ​បំបែកអេក្រង់"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ប្ដូរទៅកម្មវិធីនៅខាងឆ្វេង ឬខាងលើ ពេលកំពុងប្រើមុខងារ​បំបែកអេក្រង់"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ក្នុងអំឡុងពេលប្រើមុខងារបំបែកអេក្រង់៖ ជំនួសកម្មវិធីពីមួយទៅមួយទៀត"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ផ្លាស់ទីវិនដូដែលសកម្មរវាងផ្ទាំងអេក្រង់"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"បញ្ចូល"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ប្ដូរទៅភាសាបន្ទាប់"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ប្ដូរទៅភាសាមុន"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ប្រើតិចជាង <xliff:g id="LENGTH">%1$d</xliff:g> តួអក្សរ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខ​កំណែបង្កើត"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខ​កំណែបង្កើតទៅឃ្លីបបត។"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"ធាតុ​ក្រាហ្វិកនៃការសន្ទនា"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"ចុចការសន្ទនា ដើម្បីបញ្ចូលវាទៅក្នុងអេក្រង់ដើមរបស់អ្នក"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"សម្រាប់កម្រិតគុណភាពកាន់តែខ្ពស់ សូមត្រឡប់ទូរសព្ទ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"បត់"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"លា"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ភាពងាយស្រួល"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"ផ្លូវកាត់​ក្ដារ​ចុច"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ប្ដូរ​ផ្លូវកាត់​ក្ដារ​ចុចតាម​បំណង"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ចុចគ្រាប់ចុច ដើម្បីកំណត់ផ្លូវ​កាត់"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ស្វែងរកផ្លូវ​កាត់"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"គ្មាន​លទ្ធផល​ស្វែងរក​ទេ"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"រូបតំណាង \"បង្រួម\""</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"រូបគ្រាប់ចុចសកម្មភាព ឬមេតា"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"រូបសញ្ញាបូក"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ប្ដូរ​តាម​បំណង"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"រួចរាល់"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ការកំណត់​ក្ដារចុច"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"កំណត់ផ្លូវ​កាត់"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"បោះបង់"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ចុចគ្រាប់ចុច"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"កំពុងប្រើបន្សំគ្រាប់ចុចស្រាប់ហើយ។ សាកល្បងប្រើគ្រាប់ចុចផ្សេង។"</string>
     <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>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index 3c15fd3..71b12ca 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"បិទ"</item>
     <item msgid="3028994095749238254">"បើក"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"មិនអាចប្រើបាន"</item>
+    <item msgid="6419996398343291862">"បិទ"</item>
+    <item msgid="5908720590832378783">"បើក"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index b74a053..f315570 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -270,7 +270,7 @@
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು."</string>
     <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು ಮತ್ತು ಅಧಿಸೂಚನೆಯ ಪರದೆ."</string>
     <string name="accessibility_desc_lock_screen" msgid="409034672704273634">"ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string>
-    <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ಕೆಲಸದ ಲಾಕ್ ಪರದೆ"</string>
+    <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ಕೆಲಸದ ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ಮುಚ್ಚಿ"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ಸಂಪೂರ್ಣ ನಿಶ್ಯಬ್ಧ"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ಅಲಾರಮ್‌ಗಳು ಮಾತ್ರ"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ಇನ್‌ಪುಟ್"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ಶ್ರವಣ ಸಾಧನಗಳು"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ಆನ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ಬ್ರೈಟ್‌ನೆಸ್ ಅನ್ನು ಅಡ್ಜಸ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ,\n ಏಕೆಂದರೆ ಅದನ್ನು ಟಾಪ್ ಆ್ಯಪ್ ನಿಯಂತ್ರಿಸುತ್ತಿದೆ"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ಸ್ವಯಂ-ತಿರುಗುವಿಕೆ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ಪರದೆಯನ್ನು ಸ್ವಯಂ-ತಿರುಗಿಸಿ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ಸ್ಥಳ"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ಪ್ರಿಸೆಟ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ಪ್ರಿಸೆಟ್‌"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ಟೂಲ್‌ಗಳು"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ಲೈವ್ ಕ್ಯಾಪ್ಶನ್"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"ಟಿಪ್ಪಣಿ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ಸಾಧನದ ಮೈಕ್ರೋಫೋನ್ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆಯಬೇಕೆ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ಸಾಧನದ ಕ್ಯಾಮರಾ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆಯಬೇಕೆ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ಸಾಧನದ ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ಅನ್‍ಬ್ಲಾಕ್ ಮಾಡಬೇಕೇ?"</string>
@@ -560,8 +560,8 @@
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ಸ್ಕ್ರೀನ್‌ ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಈ ಆಯ್ಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದೆ"</string>
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ಹಂಚಿಕೊಳ್ಳಲು ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
-    <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಕ್ಯಾಸ್ಟ್ ಮಾಡಬೇಕೆ?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ಒಂದು ಆ್ಯಪ್ ಅನ್ನು ಕ್ಯಾಸ್ಟ್ ಮಾಡಿ"</string>
+    <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಕಾಸ್ಟ್ ಮಾಡಬೇಕೆ?"</string>
+    <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ಒಂದು ಆ್ಯಪ್ ಅನ್ನು ಕಾಸ್ಟ್ ಮಾಡಿ"</string>
     <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>
@@ -868,11 +868,10 @@
     <string name="system_multitasking_rhs" msgid="8714224917276297810">"ಬಲಭಾಗದಲ್ಲಿ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಮೂಲಕ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಬಳಸಿ"</string>
     <string name="system_multitasking_lhs" msgid="8402954791206308783">"ಎಡಭಾಗದಲ್ಲಿ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಮೂಲಕ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಬಳಸಿ"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್‌ನಿಂದ ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ಗೆ ಬದಲಿಸಿ"</string>
-    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ಪರದೆ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಬಲಭಾಗ ಅಥವಾ ಕೆಳಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
-    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ಪರದೆ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಎಡಭಾಗ ಅಥವಾ ಮೇಲ್ಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಬಲಭಾಗ ಅಥವಾ ಕೆಳಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಎಡಭಾಗ ಅಥವಾ ಮೇಲ್ಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸುವ ಸಮಯದಲ್ಲಿ: ಒಂದು ಆ್ಯಪ್‌ನಿಂದ ಮತ್ತೊಂದು ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ಸಕ್ರಿಯ ವಿಂಡೋವನ್ನು ಡಿಸ್‌ಪ್ಲೇಗಳ ನಡುವೆ ಸರಿಸಿ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ಇನ್‌ಪುಟ್"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ಮುಂದಿನ ಭಾಷೆಗೆ ಬದಲಿಸಿ"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ಹಿಂದಿನ ಭಾಷೆಗೆ ಬದಲಿಸಿ"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> ಕ್ಕಿಂತ ಕಡಿಮೆ ಅಕ್ಷರಗಳನ್ನು ಬಳಸಿ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"ಸಂಭಾಷಣೆ ವಿಜೆಟ್‌ಗಳು"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"ಸಂಭಾಷಣೆಯನ್ನು ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಸೇರಿಸಲು ಅದನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ಅಧಿಕ ರೆಸಲ್ಯೂಷನ್‌ಗಾಗಿ, ಫೋನ್ ಅನ್ನು ಫ್ಲಿಪ್ ಮಾಡಿ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಸುತ್ತಲೂ ತಿರುಗಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ಫೋಲ್ಡ್ ಮಾಡಿರುವುದು"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಿರುವುದು"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,33 +1418,26 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ನಿಯೋಜಿಸಲು ಕೀಯನ್ನು ಒತ್ತಿರಿ"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ಹುಡುಕಾಟದ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ಯಾವುದೇ ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳಿಲ್ಲ"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ಕುಗ್ಗಿಸುವ ಐಕಾನ್"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ಆ್ಯಕ್ಷನ್ ಅಥವಾ ಮೆಟಾ ಕೀ ಐಕಾನ್"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ಪ್ಲಸ್ ಐಕಾನ್"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ಮುಗಿದಿದೆ"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ಕೀಬೋರ್ಡ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ಶಾರ್ಟ್‌ಕಟ್ ಸೆಟ್ ಮಾಡಿ"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ರದ್ದುಮಾಡಿ"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ಕೀ ಅನ್ನು ಒತ್ತಿರಿ"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ಕೀ ಸಂಯೋಜನೆಯು ಈಗಾಗಲೇ ಬಳಕೆಯಲ್ಲಿದೆ. ಮತ್ತೊಂದು ಕೀ ಬಳಸಿ ನೋಡಿ."</string>
     <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>
-    <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"ಟಚ್‌ಪ್ಯಾಡ್ ಗೆಸ್ಚರ್‌ಗಳನ್ನು ಕಲಿಯಿರಿ"</string>
+    <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"ಟಚ್‌ಪ್ಯಾಡ್ ಜೆಸ್ಚರ್‌ಗಳನ್ನು ಕಲಿಯಿರಿ"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಮತ್ತು ಟಚ್‌ಪ್ಯಾಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"ಟಚ್‌ಪ್ಯಾಡ್ ಗೆಸ್ಚರ್‌ಗಳು, ಕೀಬೋರ್ಡ್‌ಗಳ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು ಮತ್ತು ಹೆಚ್ಚಿನದನ್ನು ತಿಳಿಯಿರಿ"</string>
     <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"ಹಿಂದಿರುಗಿ"</string>
@@ -1459,11 +1455,11 @@
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ಭೇಷ್‌!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ನೀವು ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳ ಗೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ನೀವು ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳ ಜೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್‌ನಲ್ಲಿ ಆ್ಯಕ್ಷನ್‌ ಕೀಯನ್ನು ಒತ್ತಿ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ಭೇಷ್!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ನೀವು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳ ಗೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ನೀವು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳ ಜೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ಕೀಬೋರ್ಡ್ ಬ್ಯಾಕ್‌ಲೈಟ್"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ಮನೆ ನಿಯಂತ್ರಣಗಳು"</string>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index 5a188f1..49c688a 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"ಆಫ್"</item>
     <item msgid="3028994095749238254">"ಆನ್"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"ಲಭ್ಯವಿಲ್ಲ"</item>
+    <item msgid="6419996398343291862">"ಆಫ್ ಆಗಿದೆ"</item>
+    <item msgid="5908720590832378783">"ಆನ್ ಆಗಿದೆ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index cc2cb90..931066b 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"입력"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"보청기"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"켜는 중..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"상위 앱에서 밝기를 제어하고 있으므로\n 밝기를 조절할 수 없습니다."</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"자동 회전"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"화면 자동 회전"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"위치"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"새 기기와 페어링하려면 클릭하세요"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"사전 설정을 업데이트할 수 없음"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"미리 설정"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"선택됨"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"도구"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"실시간 자막"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"메모"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"기기 마이크를 차단 해제하시겠습니까?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"기기 카메라를 차단 해제하시겠습니까?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"기기 카메라 및 마이크를 차단 해제하시겠습니까?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"알림 없음"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"새로운 알림 없음"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"알림 쿨다운 사용 설정됨"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"한 번에 너무 많은 알림을 받으면 최대 2분간 자동으로 기기 볼륨이 줄어들고 알림이 최소화됩니다."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"사용 중지"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"잠금 해제하여 이전 알림 보기"</string>
@@ -699,7 +698,7 @@
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"소음 제어"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"공간 음향"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"사용 안함"</string>
-    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"수정됨"</string>
+    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"고정됨"</string>
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"머리 추적"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"탭하여 벨소리 장치 모드 변경"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"벨소리 장치 모드"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"화면 분할을 사용하는 중에 오른쪽 또는 아래쪽에 있는 앱으로 전환"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"화면 분할을 사용하는 중에 왼쪽 또는 위쪽에 있는 앱으로 전환하기"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"화면 분할 중: 다른 앱으로 바꾸기"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"디스플레이 간 활성 창 이동"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"입력"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"다음 언어로 전환"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"이전 언어로 전환"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>자 미만이어야 합니다."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"대화 열기"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"대화 위젯"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"대화를 탭하여 홈 화면에 추가하세요."</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"해상도를 높이려면 후면 카메라를 사용하세요."</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"폴더블 기기를 펼치는 모습"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"폴더블 기기를 뒤집는 모습"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"접은 상태"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"펼친 상태"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,33 +1418,26 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"접근성"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"단축키"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"단축키 맞춤설정"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"키를 눌러 단축키 지정"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"검색 바로가기"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"검색 결과 없음"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"접기 아이콘"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"작업 또는 메타 키 아이콘"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"더하기 아이콘"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"맞춤설정"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"완료"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"키보드 설정"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"단축키 설정"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"취소"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"키를 누르세요."</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"이미 사용 중인 키 조합입니다. 다른 키를 사용해 보세요."</string>
     <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>
-    <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"터치패드 동작 알아보기"</string>
+    <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"터치패드 동작을 알아보세요."</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"키보드와 터치패드를 사용하여 이동"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"터치패드 동작, 단축키 등 알아보기"</string>
     <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"뒤로 이동"</string>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index bfa1127..002d38e 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"사용 안함"</item>
     <item msgid="3028994095749238254">"사용"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"사용할 수 없음"</item>
+    <item msgid="6419996398343291862">"사용 안함"</item>
+    <item msgid="5908720590832378783">"사용"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index bcf594d..fc16164 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -114,7 +114,7 @@
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүтүндөй экранды жаздыруу"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Толук экранды жаздыруу: %s"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Бүтүндөй экранды жаздырганда, андагы нерселердин баары видеого түшүп калат. Андыктан этият болуп, сырсөздөр, төлөм ыкмалары, билдирүүлөр, сүрөттөр, аудио жана видео материалдар сыяктуу купуя нерселерди көрсөтүп албаңыз."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Колдонмону жаздырганда ал колдонмодо көрсөтүлүп же ойнотулуп жаткан нерселер жаздырылат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Колдонмону жаздырганда, андагы нерселердин баары видеого түшүп калат. Андыктан сырсөздөр, төлөмдүн чоо-жайы, билдирүүлөр, сүрөттөр, аудио жана видео сыяктуу нерселер менен этият болуңуз."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Экранды жаздыруу"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Жаздыруу үчүн колдонмо тандоо"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио жаздыруу"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Киргизүү"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Угуу аппараттары"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Күйгүзүлүүдө…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Жарыктыкты тууралоого болбойт, анткени аны\n жогорку колдонмо көзөмөлдөйт"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Авто буруу"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Экранды авто буруу"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Жайгашкан жер"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Жаңы түзмөк кошуу үчүн басыңыз"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Алдын ала коюлган параметрлер жаңыртылган жок"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Алдын ала коюлган параметрлер"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Тандалды"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Куралдар"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ыкчам коштомо жазуулар"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Учкай маалымат"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Түзмөктүн микрофонун бөгөттөн чыгарасызбы?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Түзмөктүн камерасын бөгөттөн чыгарасызбы?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Түзмөктүн камерасы менен микрофону бөгөттөн чыгарылсынбы?"</string>
@@ -556,7 +556,7 @@
     <!-- no translation found for media_projection_entry_app_permission_dialog_option_text_entire_screen (5100078808078139706) -->
     <skip />
     <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Бүтүндөй экранды бөлүшкөндө андагы бардык нерселер <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна көрүнөт. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Колдонмону бөлүшкөндө ал колдонмодо көрсөтүлүп же ойнотулуп жаткан нерселер <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна көрүнөт. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Колдонмону бөлүшкөндө, андагы нерселер <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна көрүнөт. Андыктан сырсөздөр, төлөмдүн чоо-жайы, билдирүүлөр, сүрөттөр, аудио жана видеолор менен этият болуңуз."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Экранды бөлүшүү"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> бул параметрди өчүрүп койду"</string>
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Бөлүшүү үчүн колдонмо тандоо"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Билдирме жок"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңы билдирмелер жок"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Азыр билдирмелердин үнүн басаңдатуу күйүк"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Өтө көп билдирме келсе, түзмөктүн үнү 2 мүнөткө басаңдап, эскертүүлөрдүн саны азаят."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өчүрүү"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Билдирмелерди көрүү үчүн кулпуну ачыңыз"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Бөлүнгөн экранда сол же төмөн жактагы колдонмого которулуу"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Бөлүнгөн экранды колдонуп жатканда сол же жогору жактагы колдонмого которулуңуз"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлүү режиминде бир колдонмону экинчисине алмаштыруу"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Активдүү терезени экрандардын ортосунда жылдыруу"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Киргизүү"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Кийинки тилге которулуу"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Мурунку тилге которулуу"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> символдон ашпашы керек"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Сүйлөшүүлөр виджеттери"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Сүйлөшүүнү башкы экранга кошуу үчүн таптап коюңуз"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Жогорку дааналык үчүн телефондун арткы камерасын колдонуңуз"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ачылып турган бүктөлмө түзмөк"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Оодарылып жаткан бүктөлмө түзмөк"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"бүктөлгөн"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ачылган"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,34 +1418,27 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Атайын мүмкүнчүлүктөр"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Ыкчам баскычтар"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Ыкчам баскычтарды ыңгайлаштыруу"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Ыкчам баскычты дайындоо үчүн баскычты басыңыз"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ыкчам баскычтарды издөө"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Эч нерсе табылган жок"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жыйыштыруу сүрөтчөсү"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Аракет же Мета ачкыч сүрөтчөсү"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Кошуу сүрөтчөсү"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Ыңгайлаштыруу"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Бүттү"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Баскычтоп параметрлери"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
-    <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Нерселерге баскычтоп аркылуу өтүңүз"</string>
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ыкчам баскычты тууралоо"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Баскычты басыңыз"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ачкыч айкалышы колдонулууда. Башка ачкычты байкап көрүңүз."</string>
+    <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>
     <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Сенсордук тактадагы жаңсоолорду үйрөнүп алыңыз"</string>
-    <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Нерселерге баскычтоп жана сенсордук такта аркылуу өтүңүз"</string>
+    <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Керектүү нерселерге баскычтоп жана сенсордук такта аркылуу өтүү"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Сенсордук тактадагы жаңсоолор, ыкчам баскычтар жана башкалар жөнүндө билип алыңыз"</string>
     <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Артка кайтуу"</string>
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Башкы бетке өтүү"</string>
@@ -1452,7 +1447,7 @@
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артка кайтуу"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Сенсордук тактаны үч манжаңыз менен солго же оңго сүрүңүз"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Сонун!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"\"Артка\" жаңсоосу боюнча үйрөткүчтү бүтүрдүңүз."</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"\"Артка\" жаңсоосун үйрөндүңүз."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Башкы бетке өтүү"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Сенсордук тактаны үч манжаңыз менен жогору сүрүңүз"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Азаматсыз!"</string>
@@ -1496,6 +1491,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="5344853290033761627">"Бардык карталарды баштапкы абалга келтиресизби?"</string>
-    <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Бардык Ыкчам параметрлер карталары түзмөктүн баштапкы параметрлерине кайтарылат"</string>
+    <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Бардык параметрлерди кайра коесузбу?"</string>
+    <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Бардык ыкчам параметрлер түзмөктүн баштапкы маанилерине кайтарылат"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index e9d9612..4834dbc 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Өчүк"</item>
     <item msgid="3028994095749238254">"Күйүк"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Жеткиликсиз"</item>
+    <item msgid="6419996398343291862">"Өчүк"</item>
+    <item msgid="5908720590832378783">"Күйүк"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 4898fa8..3a8c682 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ການປ້ອນຂໍ້ມູນ"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ເຄື່ອງຊ່ວຍຟັງ"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ກຳລັງເປີດ..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ບໍ່ສາມາດປັບຄວາມແຈ້ງເນື່ອງຈາກມັນ\n ຖືກຄວບຄຸມໂດຍແອັບຍອດນິຍົມ"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ໝຸນ​ອັດ​ຕະ​ໂນ​ມັດ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ໝຸນໜ້າຈໍອັດຕະໂນມັດ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ສະຖານທີ່"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ຄລິກເພື່ອຈັບຄູ່ອຸປະກອນໃໝ່"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ບໍ່ສາມາດອັບເດດການຕັ້ງຄ່າລ່ວງໜ້າໄດ້"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ຄ່າທີ່ກຳນົດລ່ວງໜ້າ"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ເລືອກແລ້ວ"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ເຄື່ອງມື"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ຄຳບັນຍາຍສົດ"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"ບັນທຶກ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ປົດບລັອກໄມໂຄຣໂຟນອຸປະກອນບໍ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ປົດບລັອກກ້ອງຖ່າຍຮູບອຸ​ປະ​ກອນບໍ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ຍົກເລີກການບລັອກກ້ອງຖ່າຍຮູບ ຫຼື ໄມໂຄຣໂຟນອຸ​ປະ​ກອນບໍ?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຂວາ ຫຼື ທາງລຸ່ມໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຊ້າຍ ຫຼື ທາງເທິງໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ໃນລະຫວ່າງແບ່ງໜ້າຈໍ: ໃຫ້ປ່ຽນຈາກແອັບໜຶ່ງເປັນອີກແອັບໜຶ່ງ"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ຍ້າຍໜ້າຈໍທີ່ເປີດຢູ່ໄປມາລະຫວ່າງຈໍສະແດງຜົນຕ່າງໆ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ການປ້ອນຂໍ້ມູນ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ສະຫຼັບເປັນພາສາຖັດໄປ"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ສະຫຼັບເປັນພາສາກ່ອນໜ້າ"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ໃຊ້ໜ້ອຍກວ່າ <xliff:g id="LENGTH">%1$d</xliff:g> ຕົວອັກສອນ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"ວິດເຈັດການສົນທະນາ"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"ແຕະໃສ່ການສົນທະນາໃດໜຶ່ງເພື່ອເພີ່ມມັນໃສ່ໂຮມສະກຣີນຂອງທ່ານ"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ເພື່ອຄວາມລະອຽດທີ່ສູງຂຶ້ນ, ໃຫ້ປີ້ນໂທລະສັບ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ອຸປະກອນທີ່ພັບໄດ້ກຳລັງກາງອອກ"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ອຸປະກອນທີ່ພັກໄດ້ກຳລັງປີ້ນໄປມາ"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ພັບແລ້ວ"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ກາງອອກແລ້ວ"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"ຄີລັດ"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ປັບແຕ່ງຄີລັດ"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ກົດປຸ່ມເພື່ອກໍານົດທາງລັດ"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ທາງລັດການຊອກຫາ"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ບໍ່ມີຜົນການຊອກຫາ"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ໄອຄອນຫຍໍ້ລົງ"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ໄອຄອນຄຳສັ່ງ ຫຼື ປຸ່ມ Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ໄອຄອນໝາຍບວກ"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ປັບແຕ່ງ"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ແລ້ວໆ"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ການຕັ້ງຄ່າແປ້ນພິມ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ຕັ້ງທາງລັດ"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ຍົກເລີກ"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ກົດປຸ່ມ"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ນໍາໃຊ້ປຸ່ມປະສົມຢູ່ແລ້ວ. ໃຫ້ລອງປຸ່ມອື່ນ."</string>
     <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>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index 34af9aa..bc63895 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"ປິດ"</item>
     <item msgid="3028994095749238254">"ເປີດ"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+    <item msgid="6419996398343291862">"ປິດ"</item>
+    <item msgid="5908720590832378783">"ເປີດ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index aff0d30..ae85ed2 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Įvestis"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Klausos aparatai"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Įjungiama…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Negalima koreguoti ryškumo, nes jį valdo\n viršuje esanti programa"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatinis pasukimas"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatiškai sukti ekraną"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Vietovė"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Spustelėkite, kad susietumėte naują įrenginį"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Išankstinių nustatymų atnaujinti nepavyko"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Išankstiniai nustatymai"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Pasirinkta"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Įrankiai"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitrai realiuoju laiku"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Pastaba"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Panaikinti įrenginio mikrofono blokavimą?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Panaikinti įrenginio fotoaparato blokavimą?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Panaikinti įrenginio fotoaparato ir mikrofono blokavimą?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Perjunkite į programą dešinėje arba apačioje išskaidyto ekrano režimu"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Perjunkite į programą kairėje arba viršuje išskaidyto ekrano režimu"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Išskaidyto ekrano režimu: pakeisti iš vienos programos į kitą"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktyvaus lango perkėlimas iš vieno ekrano į kitą"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Įvestis"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Perjungti į kitą kalbą"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Perjungti į ankstesnę kalbą"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Naudokite daugiausia <xliff:g id="LENGTH">%1$d</xliff:g> simb."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Pokalbio valdikliai"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Palieskite pokalbį, kad pridėtumėte jį prie pagrindinio ekrano"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Kad raiška būtų geresnė, apverskite telefoną"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Lankstomasis įrenginys išlankstomas"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Lankstomasis įrenginys apverčiamas"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"sulenkta"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"nesulenkta"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pritaikomumas"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Spartieji klavišai"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sparčiųjų klavišų tinkinimas"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Paspauskite klavišą, kad priskirtumėte spartųjį klavišą"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ieškoti sparčiųjų klavišų"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nėra jokių paieškos rezultatų"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sutraukimo piktograma"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Veiksmo arba metaduomenų klavišo piktograma"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pliuso piktograma"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tinkinti"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Atlikta"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatūros nustatymai"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nustatyti spartųjį klavišą"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Atšaukti"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Paspauskite klavišą"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Klavišų derinys jau naudojamas. Bandykite naudoti kitą klavišą."</string>
     <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>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index 124f49c..12f8b6c 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Išjungta"</item>
     <item msgid="3028994095749238254">"Įjungta"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Nepasiekiama"</item>
+    <item msgid="6419996398343291862">"Išjungta"</item>
+    <item msgid="5908720590832378783">"Įjungta"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b0b4176..b20ab36 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ievade"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Dzirdes aparāti"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Notiek ieslēgšana…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nevar mainīt spilgtumu, jo to kontrolē\n aktīvā lietotne."</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automātiska pagriešana"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automātiska ekrāna pagriešana"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Atrašanās vieta"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Noklikšķiniet, lai savienotu pārī jaunu ierīci"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nevarēja atjaunināt pirmsiestatījumu"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pirmsiestatījums"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Atlasīts"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Rīki"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitri reāllaikā"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Piezīme"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vai atbloķēt ierīces mikrofonu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vai vēlaties atbloķēt ierīces kameru?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vai atbloķēt ierīces kameru un mikrofonu?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nav paziņojumu"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nav jaunu paziņojumu"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Nogaidīšanas periods paziņojumiem ir ieslēgts"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Saņemot par daudz paziņojumu uzreiz, skaļums un brīdinājumi tiek automātiski samazināti līdz 2 min."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Izslēgt"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Atbloķējiet vecāku paziņojumu skatīšanai"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pāriet uz lietotni pa labi/lejā, kamēr izmantojat sadalīto ekrānu."</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pāriet uz lietotni pa kreisi/augšā, kamēr izmantojat sadalīto ekrānu."</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ekrāna sadalīšanas režīmā: pārvietot lietotni no viena ekrāna uz otru"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Pārvietot aktīvo logu starp displejiem"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ievade"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Pārslēgt uz nākamo valodu"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Pārslēgt uz iepriekšējo valodu"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Izmantojiet mazāk nekā <xliff:g id="LENGTH">%1$d</xliff:g> rakstzīmes."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Sarunu logrīki"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Pieskarieties kādai sarunai, lai pievienotu to savam sākuma ekrānam."</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Lai izmantotu augstāku izšķirtspēju, apvērsiet tālruni"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Salokāma ierīce tiek atlocīta"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Salokāma ierīce tiek apgriezta"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"aizvērta"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"atvērta"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pieejamība"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Īsinājumtaustiņi"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Īsinājumtaustiņu pielāgošana"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Lai piešķirtu īsinājumtaustiņu, nospiediet taustiņu"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Meklēt saīsnes"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nav meklēšanas rezultātu"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sakļaušanas ikona"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Darbību jeb meta taustiņa ikona"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pluszīmes ikona"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Pielāgot"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gatavs"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastatūras iestatījumi"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Iestatīt īsinājumtaustiņu"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Atcelt"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Nospiediet taustiņu"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Taustiņu kombinācija jau tiek izmantota. Izmēģiniet citu taustiņu."</string>
     <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>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index e5cb175..1494836 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Izslēgts"</item>
     <item msgid="3028994095749238254">"Ieslēgts"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Nav pieejams"</item>
+    <item msgid="6419996398343291862">"Izslēgts"</item>
+    <item msgid="5908720590832378783">"Ieslēgts"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index e30cf21..f8bfcf9 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Влез"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слушни помагала"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Се вклучува…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Не може да се приспособи осветленоста бидејќи е\n контролирана од горната апликација"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматско ротирање"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматско ротирање на екранот"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за да спарите нов уред"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не можеше да се ажурира зададената вредност"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Зададени вредности"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатки"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматски титлови"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се одблокира пристапот до микрофонот на уредот?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се одблокира пристапот до камерата на уредот?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Да се одблокира пристапот до камерата и микрофонот на уредот?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Нема известувања"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нови известувања"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"„Подискретни известувања“ сега е вклучена"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Јачината на звукот и известувањата на уредот се намалуваат автоматски до 2 минути кога добивате премногу известувања одеднаш."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Исклучи"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Отклучете за да ги видите старите известувања"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Префрлете се на апликацијата десно или долу при користењето поделен екран"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Префрлете се на апликацијата лево или горе при користењето поделен екран"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"При поделен екран: префрлете ги аплик. од едната на другата страна"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Движете го активниот прозорец меѓу екраните"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Внесување"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Префрлете на следниот јазик"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Префрлете на претходниот јазик"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Употребете помалку од <xliff:g id="LENGTH">%1$d</xliff:g> знаци"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Виџети за разговор"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Допрете разговор за да го додадете на почетниот екран"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Отворете го телефонот за да добиете повисока резолуција"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Преклопувачки уред се отклопува"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Преклопувачки уред се врти"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворен"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворен"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Пристапност"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Кратенки од тастатура"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Приспособете ги кратенките од тастатурата"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Притиснете го копчето за да доделите кратенка"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пребарувајте кратенки"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултати од пребарување"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за собирање"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Икона за дејство или копче за дејство"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Икона плус"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Приспособете"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Поставки за тастатурата"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Поставете кратенка"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Откажи"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Притиснете го копчето"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Комбинацијата на копчиња веќе се користи. Обидете се со друго копче."</string>
     <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>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 61539d6..17545c3 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Исклучено"</item>
     <item msgid="3028994095749238254">"Вклучено"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Недостапно"</item>
+    <item msgid="6419996398343291862">"Исклучено"</item>
+    <item msgid="5908720590832378783">"Вклучено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 42f67c6..54364c8 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ഇൻപുട്ട്"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ശ്രവണ സഹായികൾ"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ഓണാക്കുന്നു…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"തെളിച്ചം അഡ്‌ജസ്റ്റ് ചെയ്യാനാകില്ല, അത്\n നിയന്ത്രിക്കുന്നത് ഏറ്റവും മുകളിലുള്ള ആപ്പാണ്"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"സ്‌ക്രീൻ സ്വയമേവ തിരിയൽ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"സ്‌ക്രീൻ സ്വയമേവ തിരിക്കുക"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ലൊക്കേഷൻ"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"പുതിയ ഉപകരണം ജോടിയാക്കാൻ ക്ലിക്ക് ചെയ്യുക"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"പ്രീസെറ്റ് അപ്ഡേറ്റ് ചെയ്യാനായില്ല"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"പ്രീസെറ്റ്"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"തിരഞ്ഞെടുത്തു"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ടൂളുകൾ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"തത്സമയ ക്യാപ്ഷൻ"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"കുറിപ്പ്"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ഉപകരണ മൈക്രോഫോൺ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ഉപകരണ ക്യാമറ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ഉപകരണ ക്യാമറയോ മൈക്രോഫോണോ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"പുതിയ അറിയിപ്പുകളൊന്നുമില്ല"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"അറിയിപ്പിന്റെ ശബ്ദം കുറയ്ക്കൽ ഇപ്പോൾ ഓണാണ്"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"നിരവധി അറിയിപ്പ് ഒരുമിച്ച് ലഭിക്കുമ്പോൾ, ഉപകരണത്തിന്റെ ശബ്‌ദവും മുന്നറിയിപ്പും 2 മിനിറ്റ് വരെ സ്വയമേവ കുറയ്ക്കും."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ഓഫാക്കുക"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"പഴയ അറിയിപ്പുകൾ കാണാൻ അൺലോക്ക് ചെയ്യുക"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ വലതുവശത്തെ/താഴത്തെ ആപ്പിലേക്ക് മാറുക"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ ഇടതുവശത്തെ/മുകളിലെ ആപ്പിലേക്ക് മാറൂ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"സ്‌ക്രീൻ വിഭജന മോഡിൽ: ഒരു ആപ്പിൽ നിന്ന് മറ്റൊന്നിലേക്ക് മാറുക"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"സജീവ വിൻഡോകൾ ഡിസ്‌പ്ലേകൾക്ക് ഇടയിൽ നീക്കുക"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ഇൻപുട്ട്"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"അടുത്ത ഭാഷയിലേക്ക് മാറുക"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"മുമ്പത്തെ ഭാഷയിലേക്ക് മാറുക"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>-ൽ കുറവ് പ്രതീകങ്ങൾ ഉപയോഗിക്കുക"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"സംഭാഷണ വിജറ്റുകൾ"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"നിങ്ങളുടെ ഹോം സ്‌ക്രീനിൽ ചേർക്കാൻ സംഭാഷണത്തിൽ ടാപ്പ് ചെയ്യുക"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ഉയർന്ന റെസല്യൂഷന്, ഫോൺ ഫ്ലിപ്പ് ചെയ്യുക"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം അൺഫോൾഡ് ആകുന്നു"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം, കറങ്ങുന്ന വിധത്തിൽ ഫ്ലിപ്പ് ആകുന്നു"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ഫോൾഡ് ചെയ്തത്"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"അൺഫോൾഡ് ചെയ്തത്"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ഉപയോഗസഹായി"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"കീബോഡ് കുറുക്കുവഴികൾ"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"കീബോർഡ് കുറുക്കുവഴികൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"കുറുക്കുവഴി അസൈൻ ചെയ്യാൻ കീ അമർത്തുക"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"തിരയൽ കുറുക്കുവഴികൾ"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"തിരയൽ ഫലങ്ങളൊന്നുമില്ല"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ചുരുക്കൽ ഐക്കൺ"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ആക്ഷൻ/മെറ്റാ കീ ഐക്കൺ"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"പ്ലസ് ഐക്കൺ"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ഇഷ്‌ടാനുസൃതമാക്കുക"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"പൂർത്തിയായി"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"കീബോർഡ് ക്രമീകരണം"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"കുറുക്കുവഴി സജ്ജീകരിക്കുക"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"റദ്ദാക്കുക"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"കീ അമർത്തുക"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"കീ കോമ്പിനേഷൻ ഇതിനകം ഉപയോഗത്തിലുണ്ട്. മറ്റൊരു കീ പരീക്ഷിക്കുക."</string>
     <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>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index c1278d4..689fe85 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"ഓഫാണ്"</item>
     <item msgid="3028994095749238254">"ഓണാണ്"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"ലഭ്യമല്ല"</item>
+    <item msgid="6419996398343291862">"ഓഫാണ്"</item>
+    <item msgid="5908720590832378783">"ഓണാണ്"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index c87f98a..0e2dc23 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Оролт"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Сонсголын төхөөрөмж"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Асааж байна…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Гэрэлтүүлгийг\nдавуу эрхтэй аппаас хянаж байгаа тул тохируулах боломжгүй"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматаар эргэх"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Дэлгэцийг автоматаар эргүүлэх"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Байршил"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Шинэ төхөөрөмж хослуулахын тулд товшино уу"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Урьдчилсан тохируулгыг шинэчилж чадсангүй"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Урьдчилсан тохируулга"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Сонгосон"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Хэрэгсэл"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Шууд тайлбар"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Тэмдэглэл"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Төхөөрөмжийн микрофоныг блокоос гаргах уу?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Төхөөрөмжийн камерыг блокоос гаргах уу?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Төхөөрөмжийн камер болон микрофоныг блокоос гаргах уу?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Мэдэгдэл байхгүй"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Шинэ мэдэгдэл алга"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Мэдэгдлийн хөргөлт одоо асаалттай байна"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Таныг хэт олон мэдэгдэл нэг дор авахад таны төхөөрөмжийн дууны түвшин болон дохиог 2 хүртэлх минутын турш автоматаар багасгадаг."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Унтраах"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Хуучин мэдэгдлийг харах бол түгжээг тайл"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Дэлгэц хуваахыг ашиглаж байхдаа баруун талд эсвэл доор байх апп руу сэлгэ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Дэлгэц хуваахыг ашиглаж байхдаа зүүн талд эсвэл дээр байх апп руу сэлгэ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Дэлгэц хуваах үеэр: аппыг нэгээс нөгөөгөөр солих"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Идэвхтэй цонхыг дэлгэц хооронд зөөх"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Оролт"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Дараагийн хэл рүү сэлгэх"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Өмнөх хэл рүү сэлгэх"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>-с цөөн тэмдэгт ашиглана уу"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийцийн дугаар"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Хийцийн дугаарыг түр санах ойд хуулсан."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Харилцан ярианы виджетүүд"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Үндсэн нүүрэндээ нэмэх харилцан яриаг товшино уу"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Илүү өндөр нягтрал авах бол утсыг хөнтөрнө үү"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Эвхэгддэг төхөөрөмжийг дэлгэж байна"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Эвхэгддэг төхөөрөмжийг хөнтөрч байна"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"эвхсэн"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"дэлгэсэн"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Хандалт"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Товчлуурын шууд холбоос"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Товчлуурын шууд холбоосыг өөрчлөх"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Товчлол оноохын тулд товч дарна уу"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Товчлолууд хайх"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ямар ч хайлтын илэрц байхгүй"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Хураах дүрс тэмдэг"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Үйлдлийн товч буюу өөрөөр Мета товчийн дүрс тэмдэг"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Нэмэх дүрс тэмдэг"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Өөрчлөх"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Болсон"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Гарын тохиргоо"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Товчлол тохируулах"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Цуцлах"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Товч дарна уу"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Товчийн хослолыг аль хэдийн ашиглаж байна. Өөр товч туршиж үзнэ үү."</string>
     <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>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index da890cc..94e3939 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Унтраалттай"</item>
     <item msgid="3028994095749238254">"Асаалттай"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Боломжгүй"</item>
+    <item msgid="6419996398343291862">"Унтраалттай"</item>
+    <item msgid="5908720590832378783">"Асаалттай"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 204399c..cd90622 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"श्रवणयंत्रे"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"सुरू करत आहे…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ब्राइटनेस ॲडजस्ट करू शकत नाही, कारण तो\n टॉप ॲपद्वारे नियंत्रित केला जात आहे"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ऑटो-रोटेट स्क्रीन"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"स्थान"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नवीन डिव्हाइस पेअर करण्यासाठी क्लिक करा"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट करता आले नाही"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"निवडला आहे"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव्ह कॅप्शन"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"टीप"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिव्हाइसचा मायक्रोफोन अनब्लॉक करायचा आहे का?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिव्हाइसचा कॅमेरा अनब्लॉक करायचा आहे का?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"डिव्हाइसचा कॅमेरा आणि मायक्रोफोन अनब्लॉक करायचा आहे का?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन वापरताना उजवीकडील किंवा खालील अ‍ॅपवर स्विच करा"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन वापरताना डावीकडील किंवा वरील अ‍ॅपवर स्विच करा"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीनदरम्यान: एक अ‍ॅप दुसऱ्या अ‍ॅपने बदला"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ॲक्टिव्ह विंडो डिस्प्लेदरम्यान हलवा"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"इनपुट"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"पुढील भाषेवर स्विच करा"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"मागील भाषेवर स्विच करा"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> वर्णांपेक्षा कमी वर्ण वापरा"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"संभाषण विजेट"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"तुमच्या होम स्क्रीन वर संभाषण जोडण्यासाठी त्यावर टॅप करा"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"उच्च रेझोल्यूशनसाठी, फोन फ्लिप करा"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड करता येण्यासारखे डिव्हाइस अनफोल्ड केले जात आहे"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड करता येण्यासारखे डिव्हाइस आजूबाजूला फ्लिप केले जात आहे"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"फोल्ड केलेले"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"फोल्ड न केलेले"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"अ‍ॅक्सेसिबिलिटी"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट कस्टमाइझ करा"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"शॉर्टकट असाइन करण्यासाठी की प्रेस करा"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शोधण्यासाठी शॉर्टकट"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कोणतेही शोध परिणाम नाहीत"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"कोलॅप्स करा आयकन"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"कृती किंवा मेटा की आयकन"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"अधिक आयकन"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"कस्टमाइझ करा"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"पूर्ण झाले"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"कीबोर्ड सेटिंग्ज"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"शॉर्टकट सेट करा"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द करा"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"की प्रेस करा"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"की कॉम्बिनेशन आधीपासून वापरले जात आहे. दुसरी की वापरून पहा."</string>
     <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>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index 3ea25a6..cbaefb9 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"बंद आहे"</item>
     <item msgid="3028994095749238254">"सुरू आहे"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"उपलब्ध नाही"</item>
+    <item msgid="6419996398343291862">"बंद आहे"</item>
+    <item msgid="5908720590832378783">"सुरू आहे"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index ce2b3f0..c108fc4 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Alat bantu pendengaran"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Menghidupkan…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Tidak dapat melaraskan kecerahan kerana peranti\n dikawal oleh apl popular"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoputar"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoputar skrin"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menggandingkan peranti baharu"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat mengemaskinikan pratetapan"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pratetapan"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatan"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sari Kata Langsung"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Nyahsekat mikrofon peranti?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Nyahsekat kamera peranti?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Nyahsekat kamera dan mikrofon peranti?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Tukar kepada apl di sebelah kanan/bawah semasa menggunakan skrin pisah"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Tukar kepada apl di sebelah kiri/atas semasa menggunakan skrin pisah"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Semasa skrin pisah: gantikan apl daripada satu apl kepada apl lain"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Alihkan tetingkap aktif antara paparan"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Beralih kepada bahasa seterusnya"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Beralih kepada bahasa sebelumnya"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gunakan kurang daripada <xliff:g id="LENGTH">%1$d</xliff:g> aksara"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widget perbualan"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Ketik perbualan untuk menambahkan perbualan itu pada skrin Utama anda"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Untuk peleraian lebih tinggi, balikkan telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Peranti boleh lipat dibuka"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Peranti boleh lipat diterbalikkan"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"terlipat"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"tidak terlipat"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kebolehaksesan"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan papan kekunci"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sesuaikan pintasan papan kekunci"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tekan kekunci untuk menetapkan pintasan"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan carian"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tiada hasil carian"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kuncupkan ikon"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon kekunci tindakan atau Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikon tambah"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sesuaikan"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Selesai"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tetapan Papan Kekunci"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tetapkan pintasan"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Batal"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tekan kekunci"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Gabungan kekunci sudah digunakan. Cuba kekunci lain."</string>
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigasi menggunakan papan kekunci"</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>
@@ -1449,17 +1445,17 @@
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Lihat apl terbaharu"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Selesai"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
-    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Leret ke kiri atau ke kanan menggunakan tiga jari pada pad sentuh anda"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Leret ke kiri atau ke kanan menggunakan tiga jari pada pad sentuh"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bagus!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah melengkapkan gerak isyarat undur."</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah melengkapkan gerak isyarat kembali."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Akses laman utama"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Leret ke atas dengan tiga jari pada pad sentuh anda"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bagus!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Anda telah melengkapkan gerak isyarat akses laman utama"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Lihat apl terbaharu"</string>
-    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Leret ke atas dan tahan menggunakan tiga jari pada pad sentuh anda"</string>
+    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Leret ke atas dan tahan menggunakan tiga jari pada pad sentuh"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Syabas!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Anda melengkapkan gerak isyarat lihat apl terbaharu."</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Anda telah melengkapkan gerak isyarat lihat apl terbaharu."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Lihat semua apl"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan kekunci tindakan pada papan kekunci anda"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Syabas!"</string>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index 51f215b..3c78bcc 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Mati"</item>
     <item msgid="3028994095749238254">"Hidup"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Tidak tersedia"</item>
+    <item msgid="6419996398343291862">"Mati"</item>
+    <item msgid="5908720590832378783">"Hidup"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index a3568f2..ce52f4e 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"အဝင်"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"နားကြားကိရိယာ"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ဖွင့်နေသည်…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"၎င်းကို ထိပ်ဆုံးရှိအက်ပ်က\n ထိန်းချုပ်နေသဖြင့် တောက်ပမှုကို ပြင်ဆင်၍မရပါ"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"အော်တို-လည်"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"မျက်နှာပြင်အား အလိုအလျောက်လှည့်ခြင်း"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"တည်နေရာ"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"စက်အသစ် တွဲချိတ်ရန် နှိပ်ပါ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"အသင့်သုံးကို အပ်ဒိတ်လုပ်၍မရပါ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ကြိုတင်သတ်မှတ်ချက်"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ရွေးထားသည်"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"တူးလ်များ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"တိုက်ရိုက်စာတန်း"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"မှတ်စု"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"စက်၏မိုက်ခရိုဖုန်းကို ပြန်ဖွင့်မလား။"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"စက်၏ကင်မရာကို ပြန်ဖွင့်မလား။"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"စက်၏ကင်မရာနှင့် မိုက်ခရိုဖုန်းကို ပြန်ဖွင့်မလား။"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"အကြောင်းကြားချက် မရှိပါ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"အကြောင်းကြားချက်သစ် မရှိပါ"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"အကြောင်းကြားချက် သတိပေးမှု လျှော့ချခြင်း ဖွင့်လိုက်ပြီ"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"အကြောင်းကြားချက်များစွာ တစ်ပြိုင်နက်ရပါက သင့်စက်၏ အသံနှင့် သတိပေးချက်ကို ၂ မိနစ်ကြာသည်အထိ အလိုအလျောက်လျှော့ချသည်။"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ပိတ်ရန်"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"အကြောင်းကြားချက်ဟောင်းကြည့်ရန် လော့ခ်ဖွင့်ပါ"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"မျက်နှာပြင်ခွဲ၍ပြသခြင်း သုံးစဉ် ညာ (သို့) အောက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသုံးစဉ် ဘယ် (သို့) အထက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"မျက်နှာပြင် ခွဲ၍ပြသစဉ်- အက်ပ်တစ်ခုကို နောက်တစ်ခုနှင့် အစားထိုးရန်"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"လက်ရှိဝင်းဒိုးကို ပြကွက်များအကြား ရွှေ့ခြင်း"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"စာရိုက်ခြင်း"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"နောက်ဘာသာစကားသို့ ပြောင်းရန်"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ယခင်ဘာသာစကားသို့ ပြောင်းရန်"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"အက္ခရာ <xliff:g id="LENGTH">%1$d</xliff:g> လုံးအောက် သုံးရန်"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်ပုံအမှတ်"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"စကားဝိုင်း ဝိဂျက်များ"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"စကားဝိုင်းကို သင်၏ ‘ပင်မစာမျက်နှာ’ သို့ထည့်ရန် တို့ပါ"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ပုံရိပ် ပိုမိုပြတ်သားစေရန် ဖုန်းကို တစ်ဖက်သို့ လှန်လိုက်ပါ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ခေါက်နိုင်သောစက်ကို ဖြန့်လိုက်သည်"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ခေါက်နိုင်သောစက်ကို တစ်ဘက်သို့ လှန်လိုက်သည်"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ခေါက်ထားသည်"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ဖြန့်ထားသည်"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"အများသုံးနိုင်မှု"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"လက်ကွက်ဖြတ်လမ်းများ"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"လက်ကွက်ဖြတ်လမ်းများကို စိတ်ကြိုက်လုပ်ခြင်း"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ဖြတ်လမ်းသတ်မှတ်ရန် ကီးကို နှိပ်ပါ"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ဖြတ်လမ်းများ ရှာရန်"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ရှာဖွေမှုရလဒ် မရှိပါ"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"လျှော့ပြရန် သင်္ကေတ"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"လုပ်ဆောင်ချက် (သို့) Meta ကီးသင်္ကေတ"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"အပေါင်းသင်္ကေတ"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"စိတ်ကြိုက်လုပ်ရန်"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ပြီးပြီ"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ကီးဘုတ်ဆက်တင်များ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ဖြတ်လမ်း သတ်မှတ်ရန်"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"မလုပ်တော့"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ကီးကို နှိပ်ပါ"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ကီးပေါင်းစပ်ခြင်းကို သုံးနေပြီးဖြစ်သည်။ အခြားကီးကို စမ်းကြည့်ပါ။"</string>
     <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>
@@ -1461,7 +1456,7 @@
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"သင့်တာ့ချ်ပက်တွင် လက်သုံးချောင်းဖြင့် အပေါ်သို့ပွတ်ဆွဲပြီး ဖိထားပါ"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"တော်ပါပေသည်။"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"မကြာသေးမီကအက်ပ်များကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ။"</string>
-    <string name="tutorial_action_key_title" msgid="8172535792469008169">"အက်ပ်အားလုံးကို ကြည့်ရန်"</string>
+    <string name="tutorial_action_key_title" msgid="8172535792469008169">"အက်ပ်အားလုံးကို ကြည့်ခြင်း"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ကီးဘုတ်တွင် လုပ်ဆောင်ချက်ကီး နှိပ်ပါ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"အလွန်ကောင်းပါသည်။"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"အက်ပ်အားလုံးကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ"</string>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index 7af7516..9675cb5 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"ပိတ်"</item>
     <item msgid="3028994095749238254">"ဖွင့်"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"မရနိုင်ပါ"</item>
+    <item msgid="6419996398343291862">"ပိတ်"</item>
+    <item msgid="5908720590832378783">"ဖွင့်"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 38b2673..db352a5 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Innenhet"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Høreapparater"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Slår på …"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Kan ikke justere lysstyrken, fordi den\n kontrolleres av appen på toppen"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotér automatisk"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotér skjermen automatisk"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Sted"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klikk for å koble til en ny enhet"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Kunne ikke oppdatere forhåndsinnstillingen"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forhåndsinnstilling"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktøy"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Direkteteksting"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Merknad"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du oppheve blokkeringen av enhetsmikrofonen?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du oppheve blokkeringen av enhetskameraet?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vil du oppheve blokkeringen av enhetskameraet og -mikrofonen?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ingen varsler"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye varsler"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Nå er varseldempingen slått på"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Enhetsvolumet og varsler reduseres automatisk i opptil 2 min når du får for mange varsler samtidig."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slå av"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås opp for å se eldre varsler"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bytt til appen til høyre eller under mens du bruker delt skjerm"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bytt til appen til venstre eller over mens du bruker delt skjerm"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"I delt skjerm: Bytt ut en app"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Flytt det aktive vinduet mellom skjermer"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Skrivespråk"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Bytt til neste språk"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Bytt til forrige språk"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Bruk færre enn <xliff:g id="LENGTH">%1$d</xliff:g> tegn"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Samtalemoduler"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Trykk på en samtale for å legge den til på startskjermen"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Brett ut telefonen for å få høyere oppløsning"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En foldbar enhet blir brettet ut"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En foldbar enhet blir snudd"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"lagt sammen"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"åpen"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tilgjengelighet"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Hurtigtaster"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpass hurtigtastene"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Trykk på tasten for å tilordne hurtigtasten"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snarveier til søk"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ingen søkeresultater"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Skjul-ikon"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Handlings- eller Meta-tast-ikon"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plussikon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tilpass"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Ferdig"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastaturinnstillinger"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Angi hurtigtast"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Avbryt"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Trykk på tasten"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tastekombinasjonen brukes allerede. Prøv en annen tast."</string>
     <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>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index 3ed1a4e..bd5b692 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Av"</item>
     <item msgid="3028994095749238254">"På"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Utilgjengelig"</item>
+    <item msgid="6419996398343291862">"Av"</item>
+    <item msgid="5908720590832378783">"På"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 82f9aca..2c1d727 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -73,7 +73,7 @@
     <string name="learn_more" msgid="4690632085667273811">"थप जान्नुहोस्"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"स्क्रिनसट"</string>
     <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"एक्स्टेन्ड अनलक अफ गरिएको छ"</string>
-    <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"कुनै छवि पठाइयो"</string>
+    <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"कुनै फोटो पठाइयो"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"स्क्रिनसट बचत गर्दै…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"कार्य प्रोफाइलमा स्क्रिनसट सेभ गरिँदै छ…"</string>
     <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"निजी प्रोफाइलमा स्क्रिनसट सेभ गरिँदै छ"</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तपाईंले आफ्नो पूरै स्क्रिन रेकर्ड गरिरहेका बेला तपाईंको स्क्रिनमा देखाइने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तपाईंले यो एप रेकर्ड गरिरहेका बेला यो एपमा देखाइने वा प्ले गरिने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रिन रेकर्ड गर्नुहोस्"</string>
-    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"रेकर्ड गर्न छनौट गर्नुहोस्"</string>
+    <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"रेकर्ड गर्न एप छनौट गर्नुहोस्"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"अडियो रेकर्ड गर्नुहोस्"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"डिभाइसको अडियो"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"तपाईंको डिभाइसका सङ्गीत, कल र रिङटोन जस्ता साउन्ड"</string>
@@ -311,7 +311,7 @@
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिस्कनेक्ट गर्नुहोस्"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"एक्टिभेट गर्नुहोस्"</string>
     <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"भोलि स्वतः अन गर्नुहोस्"</string>
-    <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक सेयर र Find My Device जस्ता सुविधाहरू प्रयोग गर्न ब्लुटुथ चाहिन्छ"</string>
+    <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक सेयर र Find My Device जस्ता सुविधाहरू प्रयोग गर्न ब्लुटुथ अन गर्नु पर्ने हुन्छ"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लुटुथ भोलि बिहान अन हुने छ"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"अडियो सेयर गर्नुहोस्"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"अडियो सेयर गरिँदै छ"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"हियरिङ डिभाइसहरू"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"सक्रिय गर्दै…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"टप एपले चमक नियन्त्रण गरिरहेकाले\n चमक मिलाउन मिल्दैन"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"अटो रोटेट"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रिन स्वतःघुम्ने"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"लोकेसन"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नयाँ डिभाइसमा कनेक्ट गर्न क्लिक गर्नुहोस्"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रिसेट अपडेट गर्न सकिएन"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"पूर्वनिर्धारित"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चयन गरिएको छ"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टुल"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइभ क्याप्सन"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिभाइसको माइक्रोफोन अनब्लक गर्ने हो?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिभाइसको क्यामेरा अनब्लक गर्ने हो?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"डिभाइसको क्यामेरा र माइक्रोफोन अनब्लक गर्ने हो?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा दायाँ वा तलको एप चलाउनुहोस्"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा बायाँ वा माथिको एप चलाउनुहोस्"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रिन प्रयोग गरिएका बेला: एउटा स्क्रिनमा भएको एप अर्कोमा लैजानुहोस्"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"सक्रिय विन्डोलाई एउटा डिस्प्लेबाट सारेर अर्को डिस्प्लेमा लैजानुहोस्"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"इनपुट"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"अर्को भाषा प्रयोग गर्नुहोस्"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"अघिल्लो भाषा प्रयोग गर्नुहोस्"</string>
@@ -1006,7 +1005,7 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi‑Fi अफ छ"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ब्लुटुथ अफ छ"</string>
-    <string name="dnd_is_off" msgid="3185706903793094463">"बाधा नपुर्‍याउनुहोस् नामक विकल्प निष्क्रिय छ"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"बाधा नपुर्‍याउनुहोस् नामक विकल्प अफ छ"</string>
     <string name="dnd_is_on" msgid="7009368176361546279">"Do Not Disturb अन छ"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"कुनै स्वचालित नियमले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रियो गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"कुनै एपले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> वटा भन्दा कम वर्ण प्रयोग गर्नुहोस्"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"वार्तालापसम्बन्धी विजेटहरू"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"कुनै वार्तालाप होम स्क्रिनमा हाल्न उक्त वार्तालापमा ट्याप गर्नुहोस्"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"उच्च रिजोल्युसनको सेल्फी खिच्न फोन फ्लिप गर्नुहोस्"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड गर्न मिल्ने डिभाइस अनफोल्ड गरेको देखाइएको एनिमेसन"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड गर्न मिल्ने डिभाइस यताउता पल्टाएर देखाइएको एनिमेसन"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"फोल्ड गरिएको"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"अनफोल्ड गरिएको"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सर्वसुलभता"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"किबोर्डका सर्टकटहरू"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"किबोर्डका सर्टकटहरू कस्टमाइज गर्नुहोस्"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"सर्टकट असाइन गर्न की थिच्नुहोस्"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"खोजका सर्टकटहरू"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कुनै पनि खोज परिणाम भेटिएन"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\"कोल्याप्स गर्नुहोस्\" आइकन"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"एक्सन वा Meta कीको आइकन"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"प्लस आइकन"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"कस्टमाइज गर्नुहोस्"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"पूरा भयो"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"किबोर्डसम्बन्धी सेटिङ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"सर्टकट सेट गर्नुहोस्"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द गर्नुहोस्"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"की थिच्नुहोस्"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"यो की कम्बिनेसन प्रयोग गरिसकिएको छ। अर्कै की प्रयोग गरी हेर्नुहोस्।"</string>
     <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>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index 2350c67d2..2dd209d 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"अफ छ"</item>
     <item msgid="3028994095749238254">"अन छ"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"उपलब्ध छैन"</item>
+    <item msgid="6419996398343291862">"अफ छ"</item>
+    <item msgid="5908720590832378783">"अन छ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 3e0b5d9..0d195a3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hoortoestellen"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aanzetten…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Kan de helderheid niet aanpassen omdat deze wordt\n beheerd door de bovenste app"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatisch draaien"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Scherm automatisch draaien"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Locatie"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nieuw apparaat te koppelen"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Kan voorinstelling niet updaten"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorinstelling"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Geselecteerd"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live ondertiteling"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notitie"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Microfoon van apparaat niet meer blokkeren?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Apparaatcamera niet meer blokkeren?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Blokkeren van apparaatcamera en -microfoon opheffen?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Naar de app rechts of onderaan gaan als je een gesplitst scherm gebruikt"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Naar de app links of bovenaan gaan als je een gesplitst scherm gebruikt"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijdens gesplitst scherm: een app vervangen door een andere"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Actief venster verplaatsen tussen schermen"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Invoer"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Overschakelen naar volgende taal"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Overschakelen naar vorige taal"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gebruik minder dan <xliff:g id="LENGTH">%1$d</xliff:g> tekens"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummer naar klembord gekopieerd."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Gesprekswidgets"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tik op een gesprek om het toe te voegen aan je startscherm"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Draai de telefoon om voor een hogere resolutie"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Opvouwbaar apparaat wordt uitgevouwen"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Opvouwbaar apparaat wordt gedraaid"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"dichtgevouwen"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"opengevouwen"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toegankelijkheid"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Sneltoetsen"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sneltoetsen aanpassen"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Druk op de toets om de sneltoets toe te wijzen"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sneltoetsen zoeken"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen zoekresultaten"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icoon voor samenvouwen"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icoon voor actie- of metatoets"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusicoon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Aanpassen"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klaar"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Toetsenbordinstellingen"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Sneltoets instellen"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuleren"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Druk op een toets"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Toetsencombinatie is al in gebruik. Probeer een andere toets."</string>
     <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>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index 4193463..221749c 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Uit"</item>
     <item msgid="3028994095749238254">"Aan"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Niet beschikbaar"</item>
+    <item msgid="6419996398343291862">"Uit"</item>
+    <item msgid="5908720590832378783">"Aan"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 980c47d..181315b 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ଇନପୁଟ୍"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ଶ୍ରବଣ ଯନ୍ତ୍ର"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ଅନ୍ ହେଉଛି…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ଟପ ଆପ ଦ୍ୱାରା ଉଜ୍ଜ୍ୱଳତା ନିୟନ୍ତ୍ରିତ\nହେଉଥିବା ଯୋଗୁଁ ଏହାକୁ ଆଡଜଷ୍ଟ କରିପାରିବେ ନାହିଁ"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ଅଟୋ-ରୋଟେଟ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ଅଟୋ-ରୋଟେଟ ସ୍କ୍ରିନ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ଲୋକେସନ"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ନୂଆ ଡିଭାଇସ ପେୟାର କରିବାକୁ କ୍ଲିକ କରନ୍ତୁ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ପ୍ରିସେଟକୁ ଅପଡେଟ କରାଯାଇପାରିଲା ନାହିଁ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ପ୍ରିସେଟ"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ଚୟନ କରାଯାଇଛି"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ଟୁଲ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ଲାଇଭ କେପ୍ସନ"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"ନୋଟ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ କରିବେ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ଡିଭାଇସର କେମେରାକୁ ଅନବ୍ଲକ କରିବେ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ଡିଭାଇସର କ୍ୟାମେରା ଏବଂ ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ୍ କରିବେ?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"କୌଣସି ନୂଆ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ନାହିଁ"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"ବିଜ୍ଞପ୍ତି କୁଲଡାଉନ ବର୍ତ୍ତମାନ ଚାଲୁ ଅଛି"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ଆପଣ ଥରକେ ଏକାଧିକ ବିଜ୍ଞପ୍ତି ପ୍ରାପ୍ତ କଲେ ଆପଣଙ୍କ ଡିଭାଇସର ଭଲ୍ୟୁମ ଓ ଆଲର୍ଟ ସ୍ୱତଃ 2 ମିନିଟ ପର୍ଯ୍ୟନ୍ତ କମ ହୁଏ।"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ପୁରୁଣା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖିବାକୁ ଅନଲକ କରନ୍ତୁ"</string>
@@ -699,7 +698,7 @@
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ନଏଜ କଣ୍ଟ୍ରୋଲ"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"ସ୍ପାସିଅଲ ଅଡିଓ"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"ବନ୍ଦ ଅଛି"</string>
-    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ନିଶ୍ଚିତ ହୋଇଛି"</string>
+    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ଠିକ ହୋଇଯାଇଛି"</string>
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ହେଡ ଟ୍ରାକିଂ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ରିଙ୍ଗର୍ ମୋଡ୍ ବଦଳାଇବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ରିଂଗର ମୋଡ"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ଡାହାଣପଟର ବା ତଳର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ବାମପଟର ବା ଉପରର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ସମୟରେ: କୌଣସି ଆପକୁ ଗୋଟିଏରୁ ଅନ୍ୟ ଏକ ଆପରେ ବଦଳାନ୍ତୁ"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ସକ୍ରିୟ ୱିଣ୍ଡୋକୁ ଡିସପ୍ଲେଗୁଡ଼ିକ ମଧ୍ୟରେ ମୁଭ କରନ୍ତୁ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ଇନପୁଟ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ପରବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ପୂର୍ବବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>ଟିରୁ କମ କେରେକ୍ଟର ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"ବାର୍ତ୍ତାଳାପ ୱିଜେଟଗୁଡ଼ିକ"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"ଏକ ବାର୍ତ୍ତାଳାପକୁ ଆପଣଙ୍କ ହୋମ ସ୍କ୍ରିନରେ ଯୋଗ କରିବା ପାଇଁ ସେଥିରେ ଟାପ କରନ୍ତୁ"</string>
@@ -1291,7 +1291,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ଟାଇଲ୍ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ଟାଇଲ୍ ଯୋଗ କର ନାହିଁ"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ୟୁଜର ଚୟନ କରନ୍ତୁ"</string>
-    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{#ଟି ଆପ ସକ୍ରିୟ ଅଛି}other{#ଟି ଆପ ସକ୍ରିୟ ଅଛି}}"</string>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ଆପ ସକ୍ରିୟ ଅଛି}other{# ଆପ ସକ୍ରିୟ ଅଛି}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ନୂଆ ସୂଚନା"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ସକ୍ରିୟ ଆପ୍ସ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"ଆପଣ ଏହି ଆପ୍ସକୁ ବ୍ୟବହାର କରୁନଥିଲେ ମଧ୍ୟ ସେଗୁଡ଼ିକ ସକ୍ରିୟ ରହିଥାଏ ଏବଂ ଚାଲୁଥାଏ। ଏହା ସେଗୁଡ଼ିକର କାର୍ଯ୍ୟକ୍ଷମତାକୁ ଉନ୍ନତ କରେ, କିନ୍ତୁ ଏହା ମଧ୍ୟ ବେଟେରୀ ଲାଇଫକୁ ପ୍ରଭାବିତ କରିପାରେ।"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ଉଚ୍ଚ ରିଜୋଲ୍ୟୁସନ ପାଇଁ ଫୋନକୁ ଫ୍ଲିପ କରନ୍ତୁ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଅନଫୋଲ୍ଡ କରାଯାଉଛି"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଫ୍ଲିପ କରାଯାଉଛି"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ଫୋଲ୍ଡେଡ"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ଅନଫୋଲ୍ଡେଡ"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ଆକ୍ସେସିବିଲିଟୀ"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"କୀବୋର୍ଡ ସର୍ଟକଟ"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"କୀବୋର୍ଡ ସର୍ଟକଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ସର୍ଟକଟ ଆସାଇନ କରିବା ପାଇଁ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ସର୍ଚ୍ଚ ସର୍ଟକଟ"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"କୌଣସି ସର୍ଚ୍ଚ ଫଳାଫଳ ନାହିଁ"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ଆଇକନକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ଆକ୍ସନ କିମ୍ବା ମେଟା କୀ ଆଇକନ"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ପ୍ଲସ ଆଇକନ"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ହୋଇଗଲା"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"କୀବୋର୍ଡ ସେଟିଂ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ସର୍ଟକଟ ସେଟ କରନ୍ତୁ"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ବାତିଲ କରନ୍ତୁ"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"କୀ ଦବାନ୍ତୁ"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"କୀ କମ୍ବିନେସନ ପୂର୍ବରୁ ବ୍ୟବହାର କରାଯାଉଛି। ଅନ୍ୟ ଏକ କୀ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ।"</string>
     <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>
@@ -1457,11 +1452,11 @@
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"ବଢ଼ିଆ କାମ!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"ଆପଣ \'ହୋମକୁ ଯାଆନ୍ତୁ\' ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି"</string>
-    <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ବର୍ତ୍ତମାନର ଆପ୍ସ ଭ୍ୟୁ କରନ୍ତୁ"</string>
+    <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ବର୍ତ୍ତମାନର ଆପ୍ସକୁ ଭ୍ୟୁ କରନ୍ତୁ"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠିକୁ ବ୍ୟବହାର କରି ଉପରକୁ ସ୍ୱାଇପ କରି ଧରି ରଖନ୍ତୁ"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ବଢ଼ିଆ କାମ!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ଆପଣ ବର୍ତ୍ତମାନର ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
-    <string name="tutorial_action_key_title" msgid="8172535792469008169">"ସମସ୍ତ ଆପ ଭ୍ୟୁ କରନ୍ତୁ"</string>
+    <string name="tutorial_action_key_title" msgid="8172535792469008169">"ସବୁ ଆପ ଭ୍ୟୁ କରନ୍ତୁ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ଆପଣଙ୍କର କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ବହୁତ ବଢ଼ିଆ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ଆପଣ ସମସ୍ତ ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି"</string>
diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml
index 35afd61..8d23073 100644
--- a/packages/SystemUI/res/values-or/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"ବନ୍ଦ ଅଛି"</item>
     <item msgid="3028994095749238254">"ଚାଲୁ ଅଛି"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"ଅନୁପଲବ୍ଧ"</item>
+    <item msgid="6419996398343291862">"ବନ୍ଦ ଅଛି"</item>
+    <item msgid="5908720590832378783">"ଚାଲୁ ଅଛି"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 8cc9f6e..5b9919e 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ਇਨਪੁੱਟ"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ਸੁਣਨ ਦੇ ਸਾਧਨ"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ਚਮਕ ਨੂੰ ਵਿਵਸਥਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਕਿਉਂਕਿ ਇਹ ਪਹਿਲਾਂ ਚੱਲ ਰਹੀ ਐਪ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕਰਨ ਕਰਕੇ \n ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ਸਵੈ-ਘੁਮਾਓ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ਸਕ੍ਰੀਨ ਨੂੰ ਆਪਣੇ ਆਪ ਘੁੰਮਾਓ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ਟਿਕਾਣਾ"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"\'ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ\' \'ਤੇ ਕਲਿੱਕ ਕਰੋ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ਪ੍ਰੀਸੈੱਟ ਨੂੰ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ਪ੍ਰੀਸੈੱਟ"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ਚੁਣਿਆ ਗਿਆ"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ਟੂਲ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ਲਾਈਵ ਸੁਰਖੀਆਂ"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"ਨੋਟ-ਕਥਨ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ਕੋਈ ਨਵੀਂ ਸੂਚਨਾ ਨਹੀਂ ਹੈ"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"ਨੋਟੀਫ਼ਿਕੇਸ਼ਨ ਕੂਲਡਾਊਨ ਹੁਣ ਚਾਲੂ ਹੈ"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ਇੱਕ ਵਾਰ \'ਚ ਕਈ ਸੂਚਨਾਵਾਂ ਮਿਲਣ \'ਤੇ, ਡੀਵਾਈਸ ਦੀ ਅਵਾਜ਼ ਅਤੇ ਅਲਰਟ ਵੱਧੋ-ਵੱਧ 2 ਮਿੰਟਾਂ ਲਈ ਆਪਣੇ-ਆਪ ਘੱਟ ਜਾਂਦੇ ਹਨ।"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ਬੰਦ ਕਰੋ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ਪੁਰਾਣੀਆਂ ਸੂਚਨਾਵਾਂ ਦੇਖਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਸੱਜੇ ਜਾਂ ਹੇਠਾਂ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਖੱਬੇ ਜਾਂ ਉੱਪਰ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੌਰਾਨ: ਇੱਕ ਐਪ ਨਾਲ ਦੂਜੀ ਐਪ ਨੂੰ ਬਦਲੋ"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ਕਿਰਿਆਸ਼ੀਲ ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਤੋਂ ਦੂਜੇ ਡਿਸਪਲੇ \'ਤੇ ਲਿਜਾਓ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ਇਨਪੁੱਟ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ਅਗਲੀ ਭਾਸ਼ਾ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ਪਿਛਲੀ ਭਾਸ਼ਾ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> ਤੋਂ ਘੱਟ ਅੱਖਰ-ਚਿੰਨ੍ਹ ਵਰਤੋ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"ਗੱਲਬਾਤ ਵਿਜੇਟ"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਕਿਸੇ ਗੱਲਬਾਤ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ਉੱਚ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਲਈ, ਫ਼ੋਨ ਨੂੰ ਫਲਿੱਪ ਕਰੋ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਆਲੇ-ਦੁਆਲੇ ਫਲਿੱਪ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ਫੋਲਡਯੋਗ ਡੀਵਾਈਸ"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ਅਣਫੋਲਡਯੋਗ ਡੀਵਾਈਸ"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,31 +1418,24 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ਪਹੁੰਚਯੋਗਤਾ"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ਸ਼ਾਰਟਕੱਟ ਨਿਰਧਾਰਿਤ ਕਰਨ ਲਈ ਕੁੰਜੀ ਦਬਾਓ"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ਸ਼ਾਰਟਕੱਟ ਖੋਜੋ"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ਕੋਈ ਖੋਜ ਨਤੀਜਾ ਨਹੀਂ ਮਿਲਿਆ"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ਪ੍ਰਤੀਕ ਨੂੰ ਸਮੇਟੋ"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ਕਾਰਵਾਈ ਜਾਂ Meta ਕੁੰਜੀ ਪ੍ਰਤੀਕ"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ਜੋੜ-ਚਿੰਨ੍ਹ ਦਾ ਪ੍ਰਤੀਕ"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ਹੋ ਗਿਆ"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ਕੀ-ਬੋਰਡ ਸੈਟਿੰਗਾਂ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ਸ਼ਾਰਟਕੱਟ ਸੈੱਟ ਕਰੋ"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ਰੱਦ ਕਰੋ"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ਕੁੰਜੀ ਦਬਾਓ"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ਕੁੰਜੀ ਸੁਮੇਲ ਪਹਿਲਾਂ ਹੀ ਵਰਤੋਂ ਵਿੱਚ ਹੈ। ਕੋਈ ਹੋਰ ਕੁੰਜੀ ਨੂੰ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ਆਪਣੇ ਕੀ-ਬੋਰਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
-    <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਬਾਰੇ ਜਾਣੋ"</string>
+    <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ਕੀ-ਬੋਰਡ ਦੇ ਸ਼ਾਰਟਕੱਟਾਂ ਬਾਰੇ ਜਾਣੋ"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ਆਪਣੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
     <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"ਟੱਚਪੈਡ ਇਸ਼ਾਰਿਆਂ ਬਾਰੇ ਜਾਣੋ"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"ਆਪਣੇ ਕੀ-ਬੋਰਡ ਅਤੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index ab2f8ab..0f53e5d 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"ਬੰਦ ਹੈ"</item>
     <item msgid="3028994095749238254">"ਚਾਲੂ ਹੈ"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"ਉਪਲਬਧ ਨਹੀਂ"</item>
+    <item msgid="6419996398343291862">"ਬੰਦ"</item>
+    <item msgid="5908720590832378783">"ਚਾਲੂ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c183116e..e41d16f 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Wejście"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparaty słuchowe"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Włączam…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nie można dostosować jasności, ponieważ jest ona\nkontrolowana przez aplikację na pierwszym planie"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoobracanie"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoobracanie ekranu"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokalizacja"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknij, aby sparować nowe urządzenie"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nie udało się zaktualizować gotowego ustawienia"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Gotowe ustawienie"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Wybrano"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Narzędzia"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Napisy na żywo"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notatka"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokować mikrofon urządzenia?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokować aparat urządzenia?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokować aparat i mikrofon urządzenia?"</string>
@@ -561,8 +561,8 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ma wyłączoną tę opcję"</string>
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Wybieranie aplikacji do udostępniania"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Włączyć przesyłanie treści wyświetlanych na ekranie?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Przesyłanie obrazu z jednej aplikacji"</string>
-    <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Przesyłanie obrazu z całego ekranu"</string>
+    <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Przesyłanie obrazu z 1 aplikacji"</string>
+    <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Przesyłanie całego ekranu"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Kiedy przesyłasz treści z całego ekranu, widoczny jest cały obraz z wyświetlacza. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Kiedy przesyłasz obraz z aplikacji, widoczne jest wszystko to, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Prześlij ekran"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Przełącz się na aplikację po prawej lub poniżej na podzielonym ekranie"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Przełącz się na aplikację po lewej lub powyżej na podzielonym ekranie"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Podczas podzielonego ekranu: zastępowanie aplikacji"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Przenieś aktywne okno na inny ekran"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Wprowadzanie"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Przełącz na następny język"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Przełącz na poprzedni język"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Wpisz mniej znaków niż <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widżety rozmów"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Kliknij rozmowę, aby dodać ją do ekranu głównego"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Odwróć telefon, aby uzyskać wyższą rozdzielczość"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Składane urządzenie jest rozkładane"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Składane urządzenie jest obracane"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"po zamknięciu"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"po otwarciu"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ułatwienia dostępu"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Skróty klawiszowe"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Dostosuj skróty klawiszowe"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Naciśnij klawisz, aby przypisać skrót"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Skróty do wyszukiwania"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Brak wyników wyszukiwania"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zwijania"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona klawisza działania/meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona plusa"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Dostosuj"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotowe"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ustawienia klawiatury"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ustaw skrót"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anuluj"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Naciśnij klawisz"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacja klawiszy jest już używana. Użyj innego klawisza."</string>
     <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>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index d3191b0..c9eb500 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Wyłączono"</item>
     <item msgid="3028994095749238254">"Włączone"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Niedostępny"</item>
+    <item msgid="6419996398343291862">"Wyłączony"</item>
+    <item msgid="5908720590832378783">"Włączony"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index f1dd9a4..72e593c 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparelhos auditivos"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ativando…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Não é possível ajustar o brilho, porque ele está sendo\n controlado pelo app principal"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Desbloquear a câmera e o microfone do dispositivo?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"Desativado"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"Não definido"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gerenciar nas configurações"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum modo ativo}=1{{mode} está ativo}one{# modo está ativo}many{# de modos estão ativos}other{# modos estão ativos}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum ativo}=1{{mode} ativo}one{# modo ativo}many{# de modos ativos}other{# modos ativos}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"Você não será perturbado por sons e vibrações, exceto alarmes. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -563,8 +563,8 @@
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir a tela?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir um app"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Transmitir tela inteira"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Quando você está transmitindo a tela inteira, tudo nela fica visível. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Quando você transmite um app, todas as informações visíveis ou abertas nele ficam visíveis. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Durante a transmissão, tudo que está na sua tela fica visível. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Quando você transmite um app, todas as informações visíveis ou abertas nele vão aparecer. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Transmitir tela"</string>
     <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Escolha um app para transmitir"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Começar a compartilhar?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"O recurso de atenuar notificações está ativado"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volume e alertas são reduzidos por até 2 min quando você recebe muitas notificações juntas."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover janela ativa entre telas"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para o próximo idioma"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Mudar para o idioma anterior"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução maior, vire o smartphone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"fechado"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aberto"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pressione a tecla para atribuir o atalho"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla de ação"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de adição"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configurações do teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Definir atalho"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pressione a tecla"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Essa combinação de teclas já está em uso. Tente outra tecla."</string>
     <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>
@@ -1458,7 +1453,7 @@
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Muito bem!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Você concluiu o gesto para acessar a tela inicial"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver os apps recentes"</string>
-    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima e pressione com 3 dedos no touchpad"</string>
+    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima com 3 dedos e mantenha"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Muito bem!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Você concluiu o gesto para ver os apps recentes."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todos os apps"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
index e315bad..9ddc41c 100644
--- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Desativar"</item>
     <item msgid="3028994095749238254">"Ativar"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Indisponível"</item>
+    <item msgid="6419996398343291862">"Desativado"</item>
+    <item msgid="5908720590832378783">"Ativado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 03c32a83..460d553 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparelhos auditivos"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"A ativar..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Não é possível ajustar o brilho porque está a ser\n controlado pela app principal"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotação auto."</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rodar o ecrã automaticamente"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para sincronizar um novo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legendas instantâneas"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmara do dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Quer desbloquear a câmara e o microfone?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"Desativado"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"Não definido"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gerir nas definições"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum modo ativo}=1{{mode} está ativo}many{# modos estão ativos}other{# modos estão ativos}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum modo ativo}=1{{mode} ativo}many{# modos ativos}other{# modos ativos}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"Não é incomodado por sons e vibrações, exceto de alarmes, lembretes, eventos e autores de chamadas que especificar. Continua a ouvir tudo o que optar por reproduzir, incluindo música, vídeos e jogos."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"Não é incomodado por sons e vibrações, exceto de alarmes. Continua a ouvir tudo o que optar por reproduzir, incluindo música, vídeos e jogos."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para a app à direita ou abaixo enquanto usa o ecrã dividido"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mude para a app à esquerda ou acima enquanto usa o ecrã dividido"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Durante o ecrã dividido: substituir uma app por outra"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mova a janela ativa entre ecrãs"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para idioma seguinte"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Mudar para idioma anterior"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use menos de <xliff:g id="LENGTH">%1$d</xliff:g> carateres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Toque numa conversa para a adicionar ao ecrã principal"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução superior, inverta o telemóvel"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável a ser desdobrado"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável a ser virado ao contrário"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"fechado"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aberto"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos de teclado"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalize os atalhos de teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Prima a tecla para atribuir o atalho"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado da pesquisa"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone de reduzir"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla Meta ou de ação"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de mais"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Definições do teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configurar atalho"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prima a tecla"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"A combinação de teclas já está a ser usada. Experimente outra tecla."</string>
     <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>
@@ -1457,7 +1453,7 @@
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"É assim mesmo!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Concluiu o gesto para aceder ao ecrã principal"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver apps recentes"</string>
-    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize rapidamente para cima e mantenha premido com 3 dedos no touchpad"</string>
+    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize rapidamente para cima sem soltar com 3 dedos no touchpad"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Muito bem!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Concluiu o gesto para ver as apps recentes."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todas as apps"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index deb6783..5baa61c 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Desativados"</item>
     <item msgid="3028994095749238254">"Ativados"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Indisponível"</item>
+    <item msgid="6419996398343291862">"Desativado"</item>
+    <item msgid="5908720590832378783">"Ativado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index f1dd9a4..72e593c 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparelhos auditivos"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ativando…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Não é possível ajustar o brilho, porque ele está sendo\n controlado pelo app principal"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Desbloquear a câmera e o microfone do dispositivo?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"Desativado"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"Não definido"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gerenciar nas configurações"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum modo ativo}=1{{mode} está ativo}one{# modo está ativo}many{# de modos estão ativos}other{# modos estão ativos}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum ativo}=1{{mode} ativo}one{# modo ativo}many{# de modos ativos}other{# modos ativos}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"Você não será perturbado por sons e vibrações, exceto alarmes. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -563,8 +563,8 @@
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir a tela?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir um app"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Transmitir tela inteira"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Quando você está transmitindo a tela inteira, tudo nela fica visível. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Quando você transmite um app, todas as informações visíveis ou abertas nele ficam visíveis. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Durante a transmissão, tudo que está na sua tela fica visível. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Quando você transmite um app, todas as informações visíveis ou abertas nele vão aparecer. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Transmitir tela"</string>
     <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Escolha um app para transmitir"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Começar a compartilhar?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"O recurso de atenuar notificações está ativado"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volume e alertas são reduzidos por até 2 min quando você recebe muitas notificações juntas."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover janela ativa entre telas"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para o próximo idioma"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Mudar para o idioma anterior"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução maior, vire o smartphone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"fechado"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aberto"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pressione a tecla para atribuir o atalho"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla de ação"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de adição"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configurações do teclado"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Definir atalho"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pressione a tecla"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Essa combinação de teclas já está em uso. Tente outra tecla."</string>
     <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>
@@ -1458,7 +1453,7 @@
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Muito bem!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Você concluiu o gesto para acessar a tela inicial"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver os apps recentes"</string>
-    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima e pressione com 3 dedos no touchpad"</string>
+    <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima com 3 dedos e mantenha"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Muito bem!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Você concluiu o gesto para ver os apps recentes."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todos os apps"</string>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
index e315bad..9ddc41c 100644
--- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Desativar"</item>
     <item msgid="3028994095749238254">"Ativar"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Indisponível"</item>
+    <item msgid="6419996398343291862">"Desativado"</item>
+    <item msgid="5908720590832378783">"Ativado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5b3190f..42fd14b 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Intrare"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparate auditive"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Se activează..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nu se poate ajusta luminozitatea deoarece este\n controlată de aplicația de top"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotire automată"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotirea automată a ecranului"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Locație"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Dă clic pentru a asocia un nou dispozitiv"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nu s-a putut actualiza presetarea"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Presetare"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selectat"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Instrumente"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitrări live"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notă"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblochezi microfonul dispozitivului?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblochezi camera dispozitivului?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblochezi camera și microfonul dispozitivului?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Începe acum"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nicio notificare"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nicio notificare nouă"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Reducerea sunetului notificărilor este activată"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volumul și alertele dispozitivului sunt reduse automat timp de până la 2 min. când primești prea multe notificări odată"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Dezactivează"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Deblochează ca să vezi notificări vechi"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Treci la aplicația din dreapta sau de mai jos cu ecranul împărțit"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Treci la aplicația din stânga sau de mai sus cu ecranul împărțit"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"În modul ecran împărțit: înlocuiește o aplicație cu alta"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mută fereastra activă de pe un ecran pe altul"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Introducere"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Comută la următoarea limbă"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Comută la limba anterioară"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Folosește maximum <xliff:g id="LENGTH">%1$d</xliff:g> caractere"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Deschide conversația"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widgeturi pentru conversație"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Atinge o conversație ca să o adaugi pe ecranul de pornire"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pentru o rezoluție mai mare, deschide telefonul"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispozitiv pliabil care este desfăcut"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispozitiv pliabil care este întors"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"închis"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"deschis"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilitate"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Comenzi rapide de la tastatură"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizează comenzile rapide de la tastatură"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Apasă tasta pentru a atribui comanda rapidă"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Comenzi directe de căutare"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Niciun rezultat al căutării"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Pictograma de restrângere"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Pictograma pentru acțiune sau tastă Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pictograma plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizează"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gata"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Setările tastaturii"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Setează o comandă rapidă"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anulează"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Apasă tasta"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinația de taste este deja folosită. Încearcă altă tastă."</string>
     <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>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index fa950c3..528b112 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Dezactivat"</item>
     <item msgid="3028994095749238254">"Activat"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Indisponibil"</item>
+    <item msgid="6419996398343291862">"Dezactivat"</item>
+    <item msgid="5908720590832378783">"Activat"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 665bd26..866cb5e 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -113,8 +113,8 @@
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записывать одно приложение"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записывать весь экран"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Записывать весь экран: %s"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Во время записи всего экрана все данные и действия, которые на нем показываются, попадают на видео. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Во время записи приложения все данные и действия, которые показываются в его окне, попадают на видео. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"На видео попадет все, что будет происходить на экране. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"На видео попадет все, что происходит в выбранном приложении. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Запись экрана"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Выбор приложения для записи экрана"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Записывать аудио"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Устройство ввода"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слуховые аппараты"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Включение…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Невозможно изменить яркость,\nтак как она регулируется общими настройками."</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоповорот"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоповорот экрана"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Геолокация"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Нажмите, чтобы подключить новое устройство"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не удалось обновить набор настроек."</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор настроек"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрано"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменты"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматические субтитры"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Заметка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблокировать микрофон устройства?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблокировать камеру устройства?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Разблокировать камеру и микрофон устройства?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"Отключено"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"Не задано"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Открыть настройки"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Включено 0 режимов}=1{Включен режим \"{mode}\"}one{Включен # режим}few{Включено # режима}many{Включено # режимов}other{Включено # режима}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{0 режимов}=1{Режим \"{mode}\"}one{# режим}few{# режима}many{# режимов}other{# режима}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"Вас не будут отвлекать звуки и вибрация, за исключением сигналов будильника, напоминаний, уведомлений о мероприятиях и звонков от помеченных контактов. Вы по-прежнему будете слышать включенную вами музыку, видео, игры и т. д."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"Вас не будут отвлекать звуки и вибрация, за исключением сигналов будильника. Вы по-прежнему будете слышать включенную вами музыку, видео, игры и т. д."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Настроить"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Нет уведомлений."</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Новых уведомлений нет"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Снижение громкости уведомлений включено"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Если придет слишком много уведомлений, на две минуты громкость и количество оповещений уменьшатся."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Отключить"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблокируйте, чтобы увидеть уведомления"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти к приложению справа или внизу на разделенном экране"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Перейти к приложению слева или вверху на разделенном экране"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"В режиме разделения экрана заменить одно приложение другим"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Переместить активное окно между экранами"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ввод"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Выбрать следующий язык"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Выбрать предыдущий язык"</string>
@@ -1006,7 +1004,7 @@
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Модуль Wi-Fi отключен"</string>
-    <string name="bt_is_off" msgid="7436344904889461591">"Модуль Bluetooth отключен."</string>
+    <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth отключен"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не беспокоить\" отключен"</string>
     <string name="dnd_is_on" msgid="7009368176361546279">"Режим \"Не беспокоить\" включен"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режим \"Не беспокоить\" был включен специальным правилом (<xliff:g id="ID_1">%s</xliff:g>)."</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Максимальное количество символов – <xliff:g id="LENGTH">%1$d</xliff:g>."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Виджеты разговоров"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Нажмите на разговор, чтобы добавить его на главный экран"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Переверните телефон и используйте основную камеру, чтобы делать снимки с более высоким разрешением."</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складное устройство в разложенном виде"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перевернутое складное устройство"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"устройство сложено"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"устройство разложено"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Быстрые клавиши"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Как настроить быстрые клавиши"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Нажмите клавишу, чтобы назначить быструю команду."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Найти быстрые клавиши"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ничего не найдено"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Свернуть\""</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Значок клавиши Meta для выполнения действия"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Значок плюса"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Настроить"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Настройки клавиатуры"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Задать сочетание клавиш"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Отмена"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Нажмите клавишу"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Это сочетание клавиш уже используется. Попробуйте другое."</string>
     <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>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index cd12bae..43d3e2a 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Отключены"</item>
     <item msgid="3028994095749238254">"Включены"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Недоступно"</item>
+    <item msgid="6419996398343291862">"Отключено"</item>
+    <item msgid="5908720590832378783">"Включено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 0df5d44..0ccd61c 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ආදානය"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ශ්‍රවණාධාරක"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ක්‍රියාත්මක කරමින්…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ඉහළ යෙදුම මඟින් එය පාලනය වන නිසා\nදීප්තිය ගැළපුම් කළ නොහැක"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ස්වයංක්‍රීය කරකැවීම"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ස්වයංක්‍රීයව-භ්‍රමණය වන තිරය"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ස්ථානය"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"නව උපාංගය යුගල කිරීමට ක්ලික් කරන්න"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"පෙර සැකසීම යාවත්කාලීන කළ නොහැකි විය"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"පෙරසැකසුම"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"තෝරන ලදි"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"මෙවලම්"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"සජීවී සිරස්තල"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"සටහන"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"උපාංග මයික්‍රෆෝනය අවහිර කිරීම ඉවත් කරන්නද?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"උපාංග කැමරාව අවහිර කිරීම ඉවත් කරන්නද?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"උපාංග කැමරාව සහ මයික්‍රෆෝනය අවහිර කිරීම ඉවත් කරන්නද?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"දැන් අරඹන්න"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"දැනුම්දීම් නැත"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"නව දැනුම්දීම් නැත"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"දැනුම්දීම් සිසිල් කිරීම දැන් ක්‍රියාත්මකයි"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ඔබට එකවර දැනුම්දීම් වැඩි ප්‍රමාණයක් ලැබෙන විට ඔබේ උපාංග පරිමාව සහ ඇඟවීම් මිනිත්තු 2ක් දක්වා ස්වයංක්‍රීයව අඩු වේ."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ක්‍රියාවිරහිත කරන්න"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"පැරණි දැනුම්දීම් බැලීමට අගුළු හරින්න"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"බෙදුම් තිරය භාවිත කරන අතරතුර දකුණේ හෝ පහළින් ඇති යෙදුමට මාරු වන්න"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"බෙදුම් තිරය භාවිත කරන අතරතුර වමේ හෝ ඉහළ ඇති යෙදුමට මාරු වන්න"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"බෙදුම් තිරය අතරතුර: යෙදුමක් එකකින් තවත් එකක් ප්‍රතිස්ථාපනය කරන්න"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"සක්‍රිය කවුළුව සංදර්ශක අතර ගෙන යන්න"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ආදානය"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"මීළඟ භාෂාවට මාරු වන්න"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"පෙර භාෂාවට මාරු වන්න"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"අනුලකුණු <xliff:g id="LENGTH">%1$d</xliff:g>කට වඩා අඩුවෙන් භාවිතා කරන්න"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"සංවාද විජට්"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"ඔබගේ මුල් තිරයට එය එක් කිරීමට සංවාදයක් තට්ටු කරන්න"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ඉහළ විභේදනය සඳහා, දුරකථනය හරවන්න"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"දිග හැරෙමින් පවතින නැමිය හැකි උපාංගය"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"වටා පෙරළෙමින් තිබෙන නැමිය හැකි උපාංගය"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"නැවූ"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"නොනැවූ"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්‍රවේශ්‍යතාව"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"යතුරු පුවරු කෙටි මං"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"යතුරුපුවරු කෙටිමං අභිරුචිකරණය කරන්න"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"කෙටි මග පැවරීමට යතුර ඔබන්න"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"කෙටි මං සොයන්න"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"සෙවීම් ප්‍රතිඵල නැත"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"හැකුළුම් නිරූපකය"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ක්‍රියාව හෝ Meta යතුරු නිරූපකය"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ධන නිරූපකය"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"අභිරුචිකරණය කරන්න"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"නිමයි"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"යතුරු පුවරු සැකසීම්"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"කෙටිමඟ සකසන්න"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"අවලංගු කරන්න"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"යතුර ඔබන්න"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"යතුරු සංයෝජනය දැනටමත් භාවිත වේ. වෙනත් යතුරක් උත්සාහ කරන්න."</string>
     <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>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
index 595575d..91280e1 100644
--- a/packages/SystemUI/res/values-si/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"ක්‍රියාවිරහිතයි"</item>
     <item msgid="3028994095749238254">"ක්‍රියාත්මකයි"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"ලබා ගත නොහැක"</item>
+    <item msgid="6419996398343291862">"ක්‍රියාවිරහිතයි"</item>
+    <item msgid="5908720590832378783">"ක්‍රියාත්මකයි"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 7331ba0..cc59bea 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vstup"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Načúvadlá"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Zapína sa…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Jas sa nedá upraviť, pretože ho \n ovláda horná aplikácia"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatické otáčanie"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otáčanie obrazovky"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zariadenie"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Predvoľbu sa nepodarilo aktualizovať"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predvoľba"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybrané"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Živý prepis"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Chcete odblokovať mikrofón zariadenia?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Chcete odblokovať kameru zariadenia?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Chcete odblokovať fotoaparát a mikrofón zariadenia?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Žiadne upozornenia"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Žiadne nové upozornenia"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Stlmenie upozornení je zapnuté"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Keď dostanete priveľa upozornení naraz, až na dve minúty sa zníži hlasitosť  zariadenia a upozornenia sa obmedzia."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnúť"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odomknutím zobrazíte staršie upozornenia"</string>
@@ -700,7 +699,7 @@
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Priestorový zvuk"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Vypnuté"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Pevné"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sled. polohy hlavy"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sledovanie hlavy"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Režim zvonenia zmeníte klepnutím"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"režim zvonenia"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnite zvuk"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prechod na aplikáciu vpravo alebo dole pri rozdelenej obrazovke"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prechod na aplikáciu vľavo alebo hore pri rozdelenej obrazovke"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Počas rozdelenej obrazovky: nahradenie aplikácie inou"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Presun aktívneho okna medzi obrazovkami"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vstup"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Prepnutie na ďalší jazyk"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Prepnutie na predchádzajúci jazyk"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Použite menej znakov než <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Miniaplikácie konverzácií"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Klepnite na konverzáciu a pridajte ju tak na plochu"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ak chcete vyššie rozlíšenie, prevráťte telefón"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozloženie skladacieho zariadenia"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Prevrátenie skladacieho zariadenia"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zložené"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"rozložené"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,55 +1418,48 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostupnosť"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové skratky"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prispôsobenie klávesových skratiek"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Stlačením klávesa priraďte skratku"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prehľadávať skratky"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žiadne výsledky vyhľadávania"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zbalenia"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona akčného klávesa alebo metaklávesa"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prispôsobiť"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hotovo"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavenia klávesnice"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
-    <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Prechádzajte pomocou klávesnice"</string>
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastaviť skratku"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Zrušiť"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Stlačte kláves"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinácia klávesov sa už používa. Skúste iný kláves."</string>
+    <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Pohybujte sa v systéme 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>
+    <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Pohybujte sa v systéme pomocou touchpadu"</string>
     <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Naučte sa gestá touchpadu"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Prechádzajte pomocou klávesnice a touchpadu"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Naučte sa gestá touchpadu, klávesové skratky a ďalšie funkcie"</string>
-    <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Prejsť späť"</string>
+    <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Prechod späť"</string>
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Prejsť na plochu"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Zobrazenie nedávnych aplikácií"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hotovo"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Prejsť späť"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Potiahnite troma prstami na touchpade doľava alebo doprava"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Výborne!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Dokončili ste gesto na prechod späť."</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Použili ste gesto na prechod späť."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Prechod na plochu"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Potiahnite troma prstami na touchpade nahor"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Skvelé!"</string>
-    <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Dokončili ste gesto na prechod na plochu"</string>
+    <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Použili ste gesto na prechod na plochu."</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Zobrazenie nedávnych aplikácií"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Potiahnite troma prstami na touchpade nahor a pridržte"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Skvelé!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Dokončili ste gesto na zobrazenie nedávnych aplikácií."</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Použili ste gesto na zobrazenie nedávnych aplikácií."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Zobrazenie všetkých aplikácií"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Stlačte na klávesnici akčný kláves"</string>
-    <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Výborne!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Dokončili ste gesto na zobrazenie všetkých aplikácií"</string>
+    <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Dobre!"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Použili ste gesto na zobrazenie všetkých aplikácií."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvietenie klávesnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. úroveň z %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládanie domácnosti"</string>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index 607c221..0b0b894 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Vypnuté"</item>
     <item msgid="3028994095749238254">"Zapnuté"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Nedostupné"</item>
+    <item msgid="6419996398343291862">"Vypnuté"</item>
+    <item msgid="5908720590832378783">"Zapnuté"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index d0b0a9d..38f1e5a 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vhodna naprava"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušni aparati"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Vklapljanje …"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Svetlosti ni mogoče prilagoditi, ker jo\n nadzoruje aplikacija na vrhu"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Samodejno sukanje"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Samodejno sukanje zaslona"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite za seznanitev nove naprave"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Prednastavljenih vrednosti ni bilo mogoče posodobiti"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Prednastavljeno"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izbrano"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Orodja"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Samodejni podnapisi"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Opomba"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite odblokirati mikrofon v napravi?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite odblokirati fotoaparat v napravi?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite odblokirati fotoaparat in mikrofon v napravi?"</string>
@@ -561,8 +561,8 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogočila to možnost"</string>
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Izbira aplikacije za deljenje"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Želite predvajati vsebino zaslona?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Predvajanje vsebine ene aplikacije"</string>
-    <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Predvajanje vsebine celotnega zaslona"</string>
+    <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Predvajanje ene aplikacije"</string>
+    <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Predvajanje celotnega zaslona"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Pri predvajanju vsebine celotnega zaslona je vidno vse na zaslonu. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Pri predvajanju vsebine aplikacije je vidno vse, kar je prikazano ali predvajano v tej aplikaciji. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Predvajanje zaslona"</string>
@@ -699,7 +699,7 @@
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Prostorski zvok"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Izklopljeno"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksno"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Spremljanje premikov glave"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Spremljanje glave"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Dotaknite se, če želite spremeniti način zvonjenja."</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"način zvonjenja"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izklop zvoka"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Preklop na aplikacijo desno ali spodaj med uporabo razdeljenega zaslona"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Preklop na aplikacijo levo ali zgoraj med uporabo razdeljenega zaslona"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Pri razdeljenem zaslonu: medsebojna zamenjava aplikacij"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Premikanje aktivnega okna med zasloni"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vnos"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Preklop na naslednji jezik"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Preklop na prejšnji jezik"</string>
@@ -1202,8 +1201,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvočniki in zasloni"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predlagane naprave"</string>
-    <string name="media_input_group_title" msgid="2057057473860783021">"Vhodno"</string>
-    <string name="media_output_group_title" msgid="6789001895863332576">"Izhodno"</string>
+    <string name="media_input_group_title" msgid="2057057473860783021">"Vhod"</string>
+    <string name="media_output_group_title" msgid="6789001895863332576">"Izhod"</string>
     <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Ustavi deljeno sejo za premik predstavnosti v drugo napravo."</string>
     <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Ustavi"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako deluje oddajanje"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Uporabite manj kot <xliff:g id="LENGTH">%1$d</xliff:g> znakov."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Pripomočki za pogovore"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Dotaknite se pogovora, da ga dodate na začetni zaslon."</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višjo ločljivost obrnite telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Razpiranje zložljive naprave"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Obračanje zložljive naprave"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zaprto"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"razprto"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostopnost"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Bližnjične tipke"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagajanje bližnjičnih tipk"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite tipko za dodelitev bližnjice"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Iskanje po bližnjicah"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ni rezultatov iskanja"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za strnitev"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tipke za dejanje ali metapodatke"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona znaka plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Končano"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavitve tipkovnice"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastavite bližnjico"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Prekliči"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipko"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacija tipk je že v uporabi. Poskusite z drugo tipko."</string>
     <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>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index fddaea6..f9ccbb1 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Izklopljeno"</item>
     <item msgid="3028994095749238254">"Vklopljeno"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Ni na voljo"</item>
+    <item msgid="6419996398343291862">"Izklopljeno"</item>
+    <item msgid="5908720590832378783">"Vklopljeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 428caf0..9ed8bf2 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Hyrja"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparatet e dëgjimit"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Po aktivizohet…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ndriçimi nuk mund të rregullohet pasi\n po kontrollohet nga aplikacioni i sipërm"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rrotullim automatik"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rrotullimi automatik i ekranit"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Vendndodhja"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliko për të çiftuar një pajisje të re"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Paravendosja nuk mund të përditësohej"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Paravendosja"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Zgjedhur"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Veglat"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titrat në çast"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Shënim"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Të zhbllokohet mikrofoni i pajisjes?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Të zhbllokohet kamera e pajisjes?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Të zhbllokohen kamera dhe mikrofoni i pajisjes?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Asnjë njoftim"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nuk ka njoftime të reja"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Reduktimi i njoftimeve është aktiv tani"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volumi i pajisjes dhe sinjalizimet zvogëlohen automatikisht për deri në 2 minuta kur merr shumë njoftime në të njëjtën kohë."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Çaktivizo"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Shkyç për të parë njoftimet e vjetra"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Kalo tek aplikacioni djathtas ose poshtë kur përdor ekranin e ndarë"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Kalo tek aplikacioni në të majtë ose sipër kur përdor ekranin e ndarë"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Gjatë ekranit të ndarë: zëvendëso një aplikacion me një tjetër"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Zhvendose dritaren aktive mes ekraneve"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Hyrja"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Kalo te gjuha tjetër"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Kalo te gjuha e mëparshme"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Përdor më pak se <xliff:g id="LENGTH">%1$d</xliff:g> karaktere"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Miniaplikacionet e bisedave"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Trokit te një bisedë dhe shtoje në ekranin bazë"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Për rezolucion më të lartë, përmbys telefonin"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Pajisja e palosshme duke u hapur"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Pajisja e palosshme duke u rrotulluar"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"palosur"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"shpalosur"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qasshmëria"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Shkurtoret e tastierës"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizo shkurtoret e tastierës"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Shtyp tastin për të caktuar shkurtoren"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Kërko për shkurtoret"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Asnjë rezultat kërkimi"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona e palosjes"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona e tastit të veprimit ose tastit Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona e plusit"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizo"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"U krye"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Cilësimet e tastierës"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Cakto shkurtoren"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anulo"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Shtyp tastin"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinimi i tasteve është tashmë në përdorim. Provo një tast tjetër."</string>
     <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>
@@ -1450,7 +1445,7 @@
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Shiko aplikacionet e fundit"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"U krye"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kthehu prapa"</string>
-    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta në bllokun me prekje."</string>
+    <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta në bllokun me prekje"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bukur!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"E ke përfunduar gjestin e kthimit prapa."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Shko tek ekrani bazë"</string>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index b30c8e7..1ab4f01 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Joaktive"</item>
     <item msgid="3028994095749238254">"Aktive"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Nuk ofrohen"</item>
+    <item msgid="6419996398343291862">"Joaktive"</item>
+    <item msgid="5908720590832378783">"Aktive"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 63b3e9a..102c452 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Унос"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слушни апарати"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Укључује се..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Не можете да прилагодите осветљеност јер је\n контролише апликација у врху"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аутоматска ротација"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аутоматско ротирање екрана"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликните да бисте упарили нов уређај"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ажурирање задатих подешавања није успело"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Унапред одређена подешавања"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Изабрано"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатке"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Титл уживо"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Желите да одблокирате микрофон уређаја?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Желите да одблокирате камеру уређаја?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Желите да одблокирате камеру и микрофон уређаја?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пређи у апликацију здесна или испод док је подељен екран"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пређите у апликацију слева или изнад док користите подељени екран"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"У режиму подељеног екрана: замена једне апликације другом"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Премести активан прозор на следећи екран"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Унос"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Пређи на следећи језик"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Пређи на претходни језик"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Користите мањи број знакова од <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Виџети за конверзацију"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Додирните конверзацију да бисте је додали на почетни екран"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"За већу резолуцију обрните телефон"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Уређај на преклоп се отвара"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Уређај на преклоп се обрће"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворено"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворено"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Приступачност"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Тастерске пречице"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Прилагодите тастерске пречице"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Притисните тастер да бисте доделили пречицу"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Претражите пречице"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултата претраге"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за скупљање"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Икона тастера за радњу или мета тастера"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Икона знака плус"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Прилагоди"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Подешавања тастатуре"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Подеси пречицу"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Откажи"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Притисните тастер"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Комбинација тастера се већ користи. Пробајте са другим тастером."</string>
     <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>
@@ -1450,7 +1446,7 @@
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Превуците улево или удесно са три прста на тачпеду"</string>
-    <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Свака част!"</string>
+    <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Супер!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Довршили сте покрет за повратак."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Иди на почетни екран"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Превуците нагоре са три прста на тачпеду"</string>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index 2a2e074..ec5f10f 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Искључено"</item>
     <item msgid="3028994095749238254">"Укључено"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Недоступно"</item>
+    <item msgid="6419996398343291862">"Искључено"</item>
+    <item msgid="5908720590832378783">"Укључено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index bffd40b6..c2ac216 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ingång"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hörapparater"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktiverar …"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Det går inte att justera ljusstyrkan eftersom den\n styrs av den översta appen"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotera automatiskt"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotera skärmen automatiskt"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Plats"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicka för att parkoppla en ny enhet"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Det gick inte att uppdatera förinställningen"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Förinställning"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Markerad"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktyg"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Anteckning"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vill du återaktivera enhetens mikrofon?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vill du återaktivera enhetens kamera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vill du återaktivera enhetens kamera och mikrofon?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Inga aviseringar"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Det finns inga nya aviseringar"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Nu är dämpning av aviseringar på"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Enheten sänker volymen och minimerar aviseringar i upp till två minuter när du får för många aviseringar samtidigt."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Inaktivera"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås upp för att se äldre aviseringar"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Byt till appen till höger eller nedanför när du använder delad skärm"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Byt till appen till vänster eller ovanför när du använder delad skärm"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Med delad skärm: ersätt en app med en annan"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Flytta det aktiva fönstret mellan skärmar"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Inmatning"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Byt till nästa språk"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Byt till föregående språk"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Använd färre än <xliff:g id="LENGTH">%1$d</xliff:g> tecken"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Konversationswidgetar"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tryck på en konversation för att lägga till den på startskärmen"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Vänd telefonen för högre upplösning"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En vikbar enhet viks upp"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En vikbar enhet vänds"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"hopvikt"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"uppvikt"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tillgänglighet"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Kortkommandon"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Anpassa kortkommandon"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tryck på tangenten för att ange kortkommando"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sökgenvägar"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Inga sökresultat"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikonen Komprimera"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon för åtgärdstangent"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusikon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Anpassa"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klar"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tangentbordsinställningar"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ange kortkommando"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Avbryt"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tryck på tangenten"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tangentkombinationen används redan. Testa en annan tangent."</string>
     <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>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index b72f404..e9da805 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Av"</item>
     <item msgid="3028994095749238254">"På"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Inte tillgängligt"</item>
+    <item msgid="6419996398343291862">"Av"</item>
+    <item msgid="5908720590832378783">"På"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 2140a8a..3418907 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vifaa vya kuingiza sauti"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Visaidizi vya kusikia"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Inawasha..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Imeshindwa kurekebisha mwangaza kwa sababu\n inadhibitiwa na programu inayotumika"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Zungusha kiotomatiki"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Skrini ijizungushe kiotomatiki"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Mahali"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Bofya ili uunganishe kifaa kipya"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Imeshindwa kusasisha mipangilio iliyowekwa mapema"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Mipangilio iliyowekwa mapema"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Umechagua"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Zana"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Manukuu Papo Hapo"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Dokezo"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Ungependa kuwacha kuzuia maikrofoni ya kifaa?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Ungependa kuacha kuzuia kamera ya kifaa?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Ungependa kuwacha kuzuia kamera na maikrofoni ya kifaa?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Hakuna arifa"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Hakuna arifa mpya"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Mipangilio ya kutuliza arifa imewashwa"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Arifa na sauti hupunguzwa kiotomatiki kwenye kifaa chako kwa hadi dakika 2 unapopokea arifa nyingi kwa wakati mmoja."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Zima"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Fungua ili uone arifa za zamani"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Badilisha ili uende kwenye programu iliyo kulia au chini unapotumia hali ya kugawa skrini"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Badilisha uende kwenye programu iliyo kushoto au juu unapotumia hali ya kugawa skrini"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ukigawanya skrini: badilisha kutoka programu moja hadi nyingine"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Hamisha dirisha linalotumika kati ya skrini moja na nyingine"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vifaa vya kuingiza data"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Badilisha utumie lugha inayofuata"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Badilisha utumie lugha iliyotangulia"</string>
@@ -1203,7 +1201,7 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Spika na Skrini"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Vifaa Vilivyopendekezwa"</string>
-    <string name="media_input_group_title" msgid="2057057473860783021">"Vifaa vya kuingiza data"</string>
+    <string name="media_input_group_title" msgid="2057057473860783021">"Vifaa vya kuingiza maudhui"</string>
     <string name="media_output_group_title" msgid="6789001895863332576">"Vifaa vya kutoa maudhui"</string>
     <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Simamisha kipindi unachoshiriki ili uhamishie maudhui kwenye kifaa kingine"</string>
     <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Simamisha"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Hupaswi kuzidi herufi <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Wijeti za mazungumzo"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Gusa mazungumzo ili uyaweke kwenye Skrini yako ya kwanza"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Kwa ubora wa juu, geuza simu"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Kifaa kinachokunjwa kikikunjuliwa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Kifaa kinachokunjwa kikigeuzwa"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kimekunjwa"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kimefunguliwa"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,31 +1418,24 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Mikato ya kibodi"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Weka mapendeleo ya mikato ya kibodi"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Bonyeza kitufe ukabidhi njia ya mkato"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Njia mkato za kutafutia"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hamna matokeo ya utafutaji"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kunja aikoni"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Aikoni ya kitufe cha Vitendo au cha Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Aikoni ya alama ya kujumlisha"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Weka mapendeleo"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Nimemaliza"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Mipangilio ya Kibodi"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Weka njia ya mkato"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Acha"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Bonyeza kitufe"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tayari unatumia mchanganyiko huu wa vitufe. Jatibu kitufe kingine."</string>
     <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_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Fahamu kuhusu mikato ya kibodi"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Kusogeza kwa kutumia padi yako ya kugusa"</string>
     <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Fahamu miguso ya padi ya kugusa"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Kusogeza kwa kutumia kibodi na padi yako ya kugusa"</string>
@@ -1452,7 +1447,7 @@
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Rudi nyuma"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Telezesha vidole vitatu kushoto au kulia kwenye padi yako ya kugusa"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Safi!"</string>
-    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Umekamilisha ishara ya kurudi nyuma."</string>
+    <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Umekamilisha mafunzo ya miguso ya kurudi nyuma."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Nenda kwenye skrini ya kwanza"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Telezesha vidole vitatu juu kwenye padi yako ya kugusa"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Kazi nzuri!"</string>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index 4de75caf0..702af45 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Vimezimwa"</item>
     <item msgid="3028994095749238254">"Vimewashwa"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Halipatikani"</item>
+    <item msgid="6419996398343291862">"Limezimwa"</item>
+    <item msgid="5908720590832378783">"Limewashwa"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 639bc39..99c912c 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -310,7 +310,7 @@
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"சேமிக்கப்பட்டது"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"இணைப்பு நீக்கும்"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"செயல்படுத்தும்"</string>
-    <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"தானாகவே நாளை இயக்கப்படும்"</string>
+    <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"தானாகவே நாளை இயங்குதல்"</string>
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"விரைவுப் பகிர்தல், Find My Device போன்ற அம்சங்கள் புளூடூத்தைப் பயன்படுத்துகின்றன"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"நாளை காலை புளூடூத் இயக்கப்படும்"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ஆடியோவைப் பகிர்"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"உள்ளீடு"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"செவித்துணைக் கருவி"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ஆன் செய்கிறது…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"சிறந்த ஆப்ஸால் ஒளிர்வு கட்டுப்படுத்தப்படுவதால்\n இதைச் சரிசெய்ய முடியவில்லை"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"தானாகச் சுழற்று"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"திரையைத் தானாகச் சுழற்று"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"இருப்பிடம்"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"புதிய சாதனத்தை இணைக்க கிளிக் செய்யலாம்"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"முன்னமைவைப் புதுப்பிக்க முடியவில்லை"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"முன்னமைவு"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"தேர்ந்தெடுக்கப்பட்டது"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"கருவிகள்"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"உடனடி வசனம்"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"குறிப்பு"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"சாதனத்தின் மைக்ரோஃபோனுக்கான தடுப்பை நீக்கவா?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"சாதனத்தின் கேமராவுக்கான தடுப்பை நீக்கவா?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"சாதனத்தின் கேமராவுக்கும் மைக்ரோஃபோனுக்குமான தடுப்பை நீக்கவா?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது வலது/கீழ் உள்ள ஆப்ஸுக்கு மாறுதல்"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது இடது/மேலே உள்ள ஆப்ஸுக்கு மாறுதல்"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"திரைப் பிரிப்பின்போது: ஓர் ஆப்ஸுக்குப் பதிலாக மற்றொன்றை மாற்றுதல்"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"காட்சிகளுக்கு இடையே செயலில் உள்ள சாளரத்தை நகர்த்துதல்"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"உள்ளீடு"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"அடுத்த மொழிக்கு மாற்றுதல்"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"முந்தைய மொழிக்கு மாற்றுதல்"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> எழுத்துகளுக்குக் குறைவாகப் பயன்படுத்துங்கள்"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"உரையாடல் விட்ஜெட்டுகள்"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"ஓர் உரையாடலை உங்கள் முகப்புத் திரையில் சேர்க்க அந்த உரையாடலைத் தட்டுங்கள்"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"உயர் தெளிவுத்திறனுக்கு, மொபைலை ஃபிளிப் செய்யுங்கள்"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"மடக்கத்தக்க சாதனம் திறக்கப்படுகிறது"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"மடக்கத்தக்க சாதனம் ஃபிளிப் செய்யப்பட்டு திருப்பப்படுகிறது"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"மடக்கப்பட்டது"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"விரிக்கப்பட்டது"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"மாற்றுத்திறன் வசதி"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"கீபோர்டு ஷார்ட்கட்கள்"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"கீபோர்டு ஷார்ட்கட்களைப் பிரத்தியேகப்படுத்துதல்"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ஷார்ட்கட்டை அமைக்க பட்டனை அழுத்துங்கள்"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ஷார்ட்கட்களைத் தேடுக"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"தேடல் முடிவுகள் இல்லை"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"சுருக்குவதற்கான ஐகான்"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ஆக்‌ஷன்/மெட்டா பட்டன் ஐகான்"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"பிளஸ் ஐகான்"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"பிரத்தியேகப்படுத்தும்"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"முடிந்தது"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"கீபோர்டு அமைப்புகள்"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ஷார்ட்கட்டை அமையுங்கள்"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ரத்துசெய்"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"பட்டனை அழுத்துங்கள்"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"பட்டன் சேர்க்கை ஏற்கெனவே பயன்பாட்டில் உள்ளது. வேறொரு பட்டனைப் பயன்படுத்திப் பார்க்கவும்."</string>
     <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>
@@ -1463,7 +1459,7 @@
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"அனைத்து ஆப்ஸையும் காட்டு"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"உங்கள் கீபோர்டில் ஆக்‌ஷன் பட்டனை அழுத்தவும்"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"அருமை!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"அனைத்து ஆப்ஸுக்கான சைகை பயிற்சியையும் நிறைவுசெய்துவிட்டீர்கள்"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"அனைத்து ஆப்ஸையும் பார்ப்பதற்கான சைகை பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"கீபோர்டு பேக்லைட்"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"நிலை, %2$d இல் %1$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ஹோம் கன்ட்ரோல்கள்"</string>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index 66cdeec..17cc570 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"முடக்கப்பட்டுள்ளது"</item>
     <item msgid="3028994095749238254">"இயக்கப்பட்டுள்ளது"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"கிடைக்கவில்லை"</item>
+    <item msgid="6419996398343291862">"முடக்கப்பட்டுள்ளது"</item>
+    <item msgid="5908720590832378783">"இயக்கப்பட்டுள்ளது"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 2834196..5a08823 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ఇన్‌పుట్"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"వినికిడి పరికరాలు"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ఆన్ చేస్తోంది…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ఇది టాప్ యాప్ ద్వారా\n కంట్రోల్ చేయబడుతున్నందున బ్రైట్‌నెస్‌ను సర్దుబాటు చేయడం సాధ్యం కాదు"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ఆటో-రొటేట్‌"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"స్క్రీన్ ఆటో-రొటేట్‌"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"లొకేషన్"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"కొత్త పరికరాన్ని పెయిర్ చేయడానికి క్లిక్ చేయండి"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ప్రీసెట్‌ను అప్‌డేట్ చేయడం సాధ్యపడలేదు"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ప్రీసెట్"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ఎంచుకోబడింది"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"టూల్స్"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"లైవ్ క్యాప్షన్"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"గమనిక"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"పరికరం మైక్రోఫోన్‌ను అన్‌బ్లాక్ చేయమంటారా?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"పరికరంలోని కెమెరాను అన్‌బ్లాక్ చేయమంటారా?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"పరికరంలోని కెమెరా, మైక్రోఫోన్‌లను అన్‌బ్లాక్ చేయమంటారా?"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"ఆఫ్‌లో ఉంది"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"సెట్ చేసి లేదు"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"సెట్టింగ్‌లలో మేనేజ్ చేయండి"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{మోడ్స్ ఏవీ యాక్టివ్‌గా లేవు}=1{{mode} యాక్టివ్‌గా ఉంది}other{# మోడ్స్ యాక్టివ్‌గా ఉన్నాయి}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{యాక్టివ్ మోడ్స్ లేవు}=1{{mode} యాక్టివ్‌గా ఉంది}other{# మోడ్స్ యాక్టివ్‌గా ఉన్నాయి}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"మీరు పేర్కొనే అలారాలు, రిమైండర్‌లు, ఈవెంట్‌లు మరియు కాలర్‌ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"అలారాలు నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"అనుకూలంగా మార్చండి"</string>
@@ -584,7 +584,7 @@
     <string name="notification_settings_button_description" msgid="2441994740884163889">"నోటిఫికేషన్ సెట్టింగ్‌లు"</string>
     <string name="notification_history_button_description" msgid="1578657591405033383">"నోటిఫికేషన్ హిస్టరీ"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"కొత్తవి"</string>
-    <string name="notification_section_header_gentle" msgid="6804099527336337197">"నిశ్శబ్దం"</string>
+    <string name="notification_section_header_gentle" msgid="6804099527336337197">"సైలెంట్ మోడ్"</string>
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"నోటిఫికేషన్‌లు"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"సంభాషణలు"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"అన్ని నిశ్శబ్ద నోటిఫికేషన్‌లను క్లియర్ చేస్తుంది"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు కుడి లేదా కింద యాప్‌నకు మారండి"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు ఎడమ లేదా పైన యాప్‌నకు మారండి"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"స్ప్లిట్ స్క్రీన్ సమయంలో: ఒక దాన్నుండి మరో దానికి యాప్ రీప్లేస్ చేయండి"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"యాక్టివ్ విండోను డిస్‌ప్లేల మధ్య తరలించండి"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ఇన్‌పుట్"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"తర్వాత భాషకు స్విచ్ అవ్వండి"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"మునుపటి భాషకు స్విచ్ అవ్వండి"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> కంటే తక్కువ అక్షరాలను ఉపయోగించండి"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"సంభాషణ విడ్జెట్‌లు"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"ఏదైనా సంభాషణను మీ మొదటి స్క్రీన్‌కు జోడించడానికి దానిని ట్యాప్ చేయండి"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"అధిక రిజల్యూషన్ కోసం, ఫోన్‌ను తిప్పండి"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"మడవగల పరికరం విప్పబడుతోంది"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"మడవగల పరికరం చుట్టూ తిప్పబడుతోంది"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"మడిచే సదుపాయం గల పరికరం"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"మడిచే సదుపాయం లేని పరికరం"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,33 +1418,26 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"యాక్సెసిబిలిటీ"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"కీబోర్డ్ షార్ట్‌కట్‌లు"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"కీబోర్డ్ షార్ట్‌కట్‌లను అనుకూలంగా మార్చండి"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"షార్ట్‌కట్‌ను కేటాయించడానికి కీని నొక్కండి"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"షార్ట్‌కట్‌లను వెతకండి"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"సెర్చ్ ఫలితాలు ఏవీ లేవు"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"కుదించండి చిహ్నం"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"యాక్షన్ లేదా మెటా కీ చిహ్నం"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ప్లస్ చిహ్నం"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"అనుకూలంగా మార్చండి"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"పూర్తయింది"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"కీబోర్డ్ సెట్టింగ్‌లు"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"షార్ట్‌కట్‌ను సెట్ చేయండి"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"రద్దు చేయండి"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"కీని నొక్కండి"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"కీ కాంబినేషన్ ఇప్పటికే వినియోగంలో ఉంది. వేరొక కీని ట్రై చేయండి."</string>
     <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>
-    <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"టచ్‌ప్యాడ్ సంజ్ఞ గురించి తెలుసుకోండి"</string>
+    <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"మీ టచ్‌ప్యాడ్‌ను ఉపయోగించి నావిగేట్ చేయండి"</string>
+    <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"టచ్‌ప్యాడ్ సంజ్ఞల గురించి తెలుసుకోండి"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"మీ కీబోర్డ్, టచ్‌ప్యాడ్‌ను ఉపయోగించి నావిగేట్ చేయండి"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"టచ్‌ప్యాడ్ సంజ్ఞలు, కీబోర్డ్ షార్ట్‌కట్‌లు, అలాగే మరిన్నింటిని గురించి తెలుసుకోండి"</string>
     <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"వెనుకకు వెళ్లండి"</string>
@@ -1450,7 +1446,7 @@
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"పూర్తయింది"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"వెనుకకు"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"మీ టచ్‌ప్యాడ్‌లో మూడు వేళ్లను ఉపయోగించి ఎడమ వైపునకు లేదా కుడి వైపునకు స్వైప్ చేయండి"</string>
-    <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"పనితీరు బాగుంది!"</string>
+    <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"సూపర్!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"తిరిగి వెనుకకు వెళ్ళడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"మొదటి ట్యాబ్‌కు వెళ్లండి"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"మీ టచ్‌ప్యాడ్‌పై మూడు వేళ్లతో పైకి స్వైప్ చేయండి"</string>
@@ -1458,12 +1454,12 @@
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"మీరు మొదటి స్క్రీన్‌కు వెళ్లే సంజ్ఞను పూర్తి చేశారు"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ఇటీవలి యాప్‌లను చూడండి"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"మీ టచ్‌ప్యాడ్‌లో మూడు వేళ్లను ఉపయోగించి పైకి స్వైప్ చేసి, హోల్డ్ చేయండి"</string>
-    <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"పనితీరు అద్భుతంగా ఉంది!"</string>
-    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"మీరు ఇటీవలి యాప్‌ల వీక్షణ సంజ్ఞను పూర్తి చేశారు."</string>
+    <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"చక్కగా పూర్తి చేశారు!"</string>
+    <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ఇటీవలి యాప్‌లను చూడడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"అన్ని యాప్‌లను చూడండి"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"మీ కీబోర్డ్‌లో యాక్షన్ కీని నొక్కండి"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"చక్కగా చేశారు!"</string>
-    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"మీరు అన్ని యాప్‌ల వీక్షణ సంజ్ఞను పూర్తి చేశారు"</string>
+    <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"అన్ని యాప్‌లను చూడడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"కీబోర్డ్ బ్యాక్‌లైట్"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dలో %1$dవ స్థాయి"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"హోమ్ కంట్రోల్స్"</string>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index 42ee13d..8a0ab484 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"ఆఫ్‌లో ఉంది"</item>
     <item msgid="3028994095749238254">"ఆన్‌లో ఉంది"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"అందుబాటులో లేదు"</item>
+    <item msgid="6419996398343291862">"ఆఫ్‌లో ఉంది"</item>
+    <item msgid="5908720590832378783">"ఆన్‌లో ఉంది"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index fcfc4e2..816514a 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"อินพุต"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"เครื่องช่วยฟัง"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"กำลังเปิด..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ปรับความสว่างไม่ได้เนื่องจาก\nควบคุมโดยแอปที่อยู่ด้านบน"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"หมุนอัตโนมัติ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"หมุนหน้าจออัตโนมัติ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ตำแหน่ง"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"คลิกเพื่อจับคู่อุปกรณ์ใหม่"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ไม่สามารถอัปเดตค่าที่กำหนดล่วงหน้า"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ค่าที่กำหนดล่วงหน้า"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"เลือกแล้ว"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"เครื่องมือ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"คำบรรยายสด"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"จดบันทึก"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"เลิกบล็อกไมโครโฟนของอุปกรณ์ใช่ไหม"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"เลิกบล็อกกล้องของอุปกรณ์ใช่ไหม"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"เลิกบล็อกกล้องและไมโครโฟนของอุปกรณ์ใช่ไหม"</string>
@@ -454,7 +454,7 @@
     <string name="zen_mode_off" msgid="1736604456618147306">"ปิด"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"ไม่ได้ตั้งค่า"</string>
     <string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"จัดการในการตั้งค่า"</string>
-    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{ไม่มีโหมดที่ใช้งานอยู่}=1{ใช้งานอยู่ {mode} โหมด}other{ใช้งานอยู่ # โหมด}}"</string>
+    <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{ไม่มีโหมดที่ใช้งานอยู่}=1{{mode} ทำงานอยู่}other{ใช้งานอยู่ # โหมด}}"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นเสียงนาฬิกาปลุก การช่วยเตือน กิจกรรม และผู้โทรที่ระบุไว้ คุณจะยังคงได้ยินสิ่งที่คุณเลือกเล่น เช่น เพลง วิดีโอ และเกม"</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นเสียงนาฬิกาปลุก คุณจะยังคงได้ยินสิ่งที่คุณเลือกเล่น เช่น เพลง วิดีโอ และเกม"</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"กำหนดค่า"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"เปลี่ยนไปใช้แอปทางด้านขวาหรือด้านล่างขณะใช้โหมดแยกหน้าจอ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"เปลี่ยนไปใช้แอปทางด้านซ้ายหรือด้านบนขณะใช้โหมดแยกหน้าจอ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ระหว่างใช้โหมดแยกหน้าจอ: เปลี่ยนแอปหนึ่งเป็นอีกแอปหนึ่ง"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ย้ายหน้าต่างที่ใช้งานไปยังหน้าจอต่างๆ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"อินพุต"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"เปลี่ยนเป็นภาษาถัดไป"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"เปลี่ยนเป็นภาษาก่อนหน้า"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ใช้อักขระไม่เกิน <xliff:g id="LENGTH">%1$d</xliff:g> ตัว"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"วิดเจ็ตการสนทนา"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"แตะการสนทนาเพื่อเพิ่มไปยังหน้าจอหลัก"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"พลิกด้านโทรศัพท์เพื่อให้ได้ภาพที่มีความละเอียดมากขึ้น"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"อุปกรณ์ที่พับได้กำลังกางออก"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"อุปกรณ์ที่พับได้กำลังพลิกไปมา"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"พับ"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"กางออก"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"การช่วยเหลือพิเศษ"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"แป้นพิมพ์ลัด"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ปรับแต่งแป้นพิมพ์ลัด"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"กดแป้นเพื่อกำหนดแป้นพิมพ์ลัด"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ค้นหาแป้นพิมพ์ลัด"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ไม่พบผลการค้นหา"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ไอคอนยุบ"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ไอคอนการดำเนินการหรือแป้น Meta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ไอคอนเครื่องหมายบวก"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ปรับแต่ง"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"เสร็จสิ้น"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"การตั้งค่าแป้นพิมพ์"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ตั้งค่าแป้นพิมพ์ลัด"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ยกเลิก"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"กดแป้น"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"มีการใช้แป้นที่กดร่วมกันนี้แล้ว โปรดลองใช้แป้นอื่น"</string>
     <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>
diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml
index d249057..4db59c0 100644
--- a/packages/SystemUI/res/values-th/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"ปิด"</item>
     <item msgid="3028994095749238254">"เปิด"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"ไม่พร้อมใช้งาน"</item>
+    <item msgid="6419996398343291862">"ปิด"</item>
+    <item msgid="5908720590832378783">"เปิด"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 68cc6d2..3845fcd 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Mga hearing aid"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ino-on…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Hindi ma-adjust ang liwanag dahil\n kinokontrol ito ng nangingibabaw na app"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"I-auto rotate"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Awtomatikong i-rotate ang screen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasyon"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"I-click para magpares ng bagong device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Hindi ma-update ang preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Napili"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Mga Tool"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Instant Caption"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Tala"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"I-unblock ang mikropono ng device?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"I-unblock ang camera ng device?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"I-unblock ang camera at mikropono ng device?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Lumipat sa app sa kanan o ibaba habang ginagamit ang split screen"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Lumipat sa app sa kaliwa o itaas habang ginagamit ang split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Habang nasa split screen: magpalit-palit ng app"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Ilipat ang aktibong window sa pagitan ng mga display"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Lumipat sa susunod na wika"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Lumipat sa dating wika"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gumamit ng mas kaunti sa <xliff:g id="LENGTH">%1$d</xliff:g> (na) character"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Mga widget ng pag-uusap"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Mag-tap sa isang pag-uusap para idagdag ito sa iyong Home screen"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para sa mas mataas na resolution, i-flip ang telepono"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ina-unfold na foldable na device"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Fini-flip na foldable na device"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"naka-fold"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"hindi naka-fold"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Mga keyboard shortcut"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"I-customize ang mga keyboard shortcut"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pindutin ang key para magtalaga ng shortcut"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Mga shortcut ng paghahanap"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Walang resulta ng paghahanap"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"I-collapse ang icon"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icon ng Action o Meta key"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icon na plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"I-customize"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Tapos na"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Mga Setting ng Keyboard"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Magtakda ng shortcut"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Kanselahin"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pindutin ang key"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ginagamit na ang kumbinasyon ng key. Sumubok ng ibang key."</string>
     <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>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index 0e43faf..4832d1d 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Naka-off"</item>
     <item msgid="3028994095749238254">"Naka-on"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Hindi available"</item>
+    <item msgid="6419996398343291862">"Naka-off"</item>
+    <item msgid="5908720590832378783">"Naka-on"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index fd4bb45..45d8b46 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -111,7 +111,7 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekranınız kaydedilsin mi?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bir uygulamayı kaydet"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tüm ekranı kaydedin"</string>
+    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tüm ekranı kaydet"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Tüm ekranı kaydet: %s"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Tüm ekranınızı kaydettiğinizde ekranınızda gösterilen her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Bir uygulamayı kaydettiğinizde o uygulamada gösterilen veya oynatılan her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
@@ -311,7 +311,7 @@
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"bağlantıyı kes"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"etkinleştir"</string>
     <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Yarın otomatik olarak aç"</string>
-    <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ve Cihazımı Bul gibi özellikler Bluetooth\'u kullanır"</string>
+    <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ve Cihazımı Bul gibi özellikler Bluetooth\'u kullanır."</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth yarın sabah açılacak"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sesi paylaş"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Ses paylaşılıyor"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Giriş"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"İşitme cihazları"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Açılıyor…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Parlaklık ayarlanamıyor, çünkü bu özellik\n en üstteki uygulama tarafından kontrol ediliyor"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Otomatik döndür"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranı otomatik döndür"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Konum"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz eşlemek için tıklayın"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncellenemedi"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçili"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Araçlar"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Not"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonunun engellemesi kaldırılsın mı?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerasının engellemesi kaldırılsın mı?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Cihaz kamerası ile mikrofonunun engellemesi kaldırılsın mı?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Bildirim yok"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildirim yok"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Bildirim şiddetini düşürme etkin"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Aynı anda çok sayıda bildirim aldığınızda 2 dakika boyunca otomatik olarak cihazınızın sesi kısılır ve uyarıları azaltılır."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Kapat"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Eski bildirimler için kilidi açın"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran kullanırken sağdaki veya alttaki uygulamaya geçiş yap"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran kullanırken soldaki veya üstteki uygulamaya geçiş yapın"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran etkinken: Bir uygulamayı başkasıyla değiştir"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Etkin pencereyi ekranlar arasında taşıma"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Giriş"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Sonraki dile geç"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Önceki dile geç"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"En fazla <xliff:g id="LENGTH">%1$d</xliff:g> karakter kullanın"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Görüşme widget\'ları"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Ana ekranınıza eklemek için bir görüşmeye dokunun"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Daha yüksek çözünürlük için telefonu çevirin"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Katlanabilir cihaz açılıyor"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Katlanabilir cihaz döndürülüyor"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"katlanmış"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"katlanmamış"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erişilebilirlik"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Klavye kısayolları"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klavye kısayollarını özelleştirin"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Kısayol atamak için tuşa basın"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Arama kısayolları"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Arama sonucu yok"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Daralt simgesi"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"İşlem veya Meta tuşu simgesi"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Artı simgesi"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Özelleştir"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Bitti"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klavye Ayarları"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Kısayol ayarla"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"İptal"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tuşa basın"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tuş kombinasyonu zaten kullanılıyor. Başka bir tuş deneyin."</string>
     <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>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index 1e30c6d..1c0c110 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Kapalı"</item>
     <item msgid="3028994095749238254">"Açık"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Yok"</item>
+    <item msgid="6419996398343291862">"Kapalı"</item>
+    <item msgid="5908720590832378783">"Açık"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index ab5f8a4..4c4c80e 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -311,7 +311,7 @@
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"від’єднати"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активувати"</string>
     <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Автоматично ввімкнути завтра"</string>
-    <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Такі функції, як швидкий обмін і \"Знайти пристрій\", використовують Bluetooth"</string>
+    <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Такі функції, як \"Швидкий обмін\" і \"Знайти пристрій\", використовують Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth увімкнеться завтра вранці"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Поділитись аудіо"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Надсилання аудіо"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Джерело сигналу"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слухові апарати"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Увімкнення…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Не вдається змінити яскравість, оскільки\n нею керує основний додаток"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автообертання"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично обертати екран"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Геодані"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Натисніть, щоб підключити новий пристрій"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не вдалось оновити набір налаштувань"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набір налаштувань"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Вибрано"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменти"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Живі субтитри"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нотатка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Надати доступ до мікрофона?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Надати доступ до камери пристрою?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Надати доступ до камери й мікрофона?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Сповіщень немає"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Немає нових сповіщень"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Зниження гучності сповіщень увімкнено"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Коли ви отримуєте забагато сповіщень за раз, пристрій автоматично знижує їх гучність і кількість на період до 2 хвилин."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Вимкнути"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Розблокуйте, щоб переглянути старіші"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти до додатка праворуч або внизу на розділеному екрані"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Під час розділення екрана перемикатися на додаток ліворуч або вгорі"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Під час розділення екрана: замінити додаток іншим"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Перемістити активне вікно між дисплеями"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Метод введення"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Вибрати наступну мову"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Вибрати попередню мову"</string>
@@ -1203,8 +1201,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Колонки й екрани"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Пропоновані пристрої"</string>
-    <string name="media_input_group_title" msgid="2057057473860783021">"Введення"</string>
-    <string name="media_output_group_title" msgid="6789001895863332576">"Виведення"</string>
+    <string name="media_input_group_title" msgid="2057057473860783021">"Ввід"</string>
+    <string name="media_output_group_title" msgid="6789001895863332576">"Вивід"</string>
     <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Зупиніть сеанс спільного доступу, щоб перенести медіаконтент на інший пристрій"</string>
     <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Зупинити"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як працює трансляція"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Кількість символів має бути менше ніж <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Віджети розмов"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Натисніть розмову, щоб додати її на головний екран"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Для вищої роздільної здатності переверніть телефон"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Розкладний пристрій у розкладеному стані"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Розкладний пристрій обертається"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"складений"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"розкладений"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Комбінації клавіш"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Налаштуйте комбінації клавіш"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Натисніть клавішу, щоб призначити комбінацію клавіш"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Комбінації клавіш для пошуку"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нічого не знайдено"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок згортання"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Значок клавіші дії або метаклавіші"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Значок \"плюс\""</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Налаштувати"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Налаштування клавіатури"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Налаштувати комбінацію клавіш"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Скасувати"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Натисніть клавішу"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Комбінація клавіш уже використовується. Спробуйте іншу клавішу."</string>
     <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>
diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
index 6c03aea..656ccd4 100644
--- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Вимкнено"</item>
     <item msgid="3028994095749238254">"Увімкнено"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Недоступно"</item>
+    <item msgid="6419996398343291862">"Вимкнено"</item>
+    <item msgid="5908720590832378783">"Увімкнено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 39aa5d1..109f43e 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ان پٹ"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"سماعتی آلات"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"آن ہو رہا ہے…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"چمک کو ایڈجسٹ نہیں کیا جا سکتا کیونکہ اسے سرفہرست ایپ کے ذریعے \n کنٹرول کیا جا رہا ہے"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"خود کار طور پر گھمائیں"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"اسکرین کو خود کار طور پر گھمائیں"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"مقام"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"نئے آلے کا جوڑا بنانے کے لیے کلک کریں"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"پہلے سے ترتیب شدہ کو اپ ڈیٹ نہیں کیا جا سکا"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"پہلے سے ترتیب شدہ"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"منتخب کردہ"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ٹولز"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"لائیو کیپشن"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"نوٹ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"آلے کا مائیکروفون غیر مسدود کریں؟"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"آلے کا کیمرا غیر مسدود کریں؟"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"آلے کا کیمرا اور مائیکروفون غیر مسدود کریں؟"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ابھی شروع کریں"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"کوئی اطلاعات نہیں ہیں"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"کوئی نئی اطلاعات نہیں"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"ںوٹیفیکیشن کول ڈاؤن اب آن ہے"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"جب آپ کو ایک ساتھ بہت زیادہ اطلاعات موصول ہوتی ہیں تو آپ کے آلے کا والیوم اور الرٹس خودکار طور پر 2 منٹ تک کم ہو جاتے ہیں۔"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"آف کریں"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"پرانی اطلاعات دیکھنے کیلئے غیر مقفل کریں"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"اسپلٹ اسکرین کا استعمال کرتے ہوئے دائیں یا نیچے ایپ پر سوئچ کریں"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"اسپلٹ اسکرین کا استعمال کرتے ہوئے بائیں یا اوپر ایپ پر سوئچ کریں"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"اسپلٹ اسکرین کے دوران: ایک ایپ کو دوسرے سے تبدیل کریں"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"فعال ونڈو کو ڈسپلیز کے مابین منتقل کریں"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ان پٹ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"اگلی زبان پر سوئچ کریں"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"پچھلی زبان پر سوئچ کریں"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> حروف سے کم استعمال کریں"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"گفتگو ویجیٹس"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"اسے اپنی ہوم اسکرین پر شامل کرنے کے لیے گفتگو پر تھپتھپائیں"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"زیادہ ریزولوشن کے لیے، فون پلٹائیں"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"فولڈ ہونے والے آلے کو کھولا جا رہا ہے"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"فولڈ ہونے والے آلے کو گھمایا جا رہا ہے"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"فولڈ کردہ"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"اَن فولڈ کردہ"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ایکسیسبیلٹی"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"کی بورڈ شارٹ کٹس"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"کی بورڈ شارٹ کٹس کو حسب ضرورت بنائیں"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"شارٹ کٹ تفویض کرنے کے لیے کلید کو دبائیں"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"تلاش کے شارٹ کٹس"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"تلاش کا کوئی نتیجہ نہیں ہے"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"آئیکن سکیڑیں"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"‏کارروائی یا Meta کلید کا آئیکن"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"پلس کا آئیکن"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"حسب ضرورت بنائیں"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ہو گیا"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"کی بورڈ کی ترتیبات"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"شارٹ کٹ سیٹ کریں"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"منسوخ کریں"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"کلید کو دبائیں"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"کلیدی مجموعہ پہلے سے استعمال میں ہے۔ دوسری کلید آزمائیں۔"</string>
     <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>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index a213f00..4aa490d 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"آف ہے"</item>
     <item msgid="3028994095749238254">"آن ہے"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"دستیاب نہیں ہے"</item>
+    <item msgid="6419996398343291862">"آف"</item>
+    <item msgid="5908720590832378783">"آن"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 67cc8b6..1c27a00 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -114,7 +114,7 @@
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Butun ekranni yozib olish"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Butun ekranni yozib olish: %s"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Butun ekranni yozib olishda ekranda koʻrsatilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ilovani yozib olishda ilova koʻrsatilgan yoki ijro etilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ilovani yozib olishda ilovada koʻrsatilgan yoki ijro etilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranni yozib olish"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Yozib olinadigan ilovani tanlash"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Audio yozib olish"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Kirish"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Eshitish moslamalari"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Yoqilmoqda…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Yorqinlik umumiy sozlamalar orqali boshqariladi.\nUni moslash imkonsiz"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avto-burilish"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranning avtomatik burilishi"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Joylashuv"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yangi qurilmani ulash uchun bosing"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Andoza yangilanmadi"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Andoza"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Tanlangan"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Vositalar"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Jonli izoh"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qayd"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Qurilma mikrofoni blokdan chiqarilsinmi?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Qurilma kamerasi blokdan chiqarilsinmi?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Qurilma kamerasi va mikrofoni blokdan chiqarilsinmi?"</string>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ajratilgan ekranda oʻngdagi yoki pastdagi ilovaga almashish"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ajratilgan ekranda chapdagi yoki yuqoridagi ilovaga almashish"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ajratilgan rejimda ilovalarni oʻzaro almashtirish"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Faol oynani ekranlararo koʻchirish"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Kiritish"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Keyingi tilga almashtirish"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Avvalgi tilga almashtirish"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Kiritiladigan belgilar <xliff:g id="LENGTH">%1$d</xliff:g> tadan oshmasin"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Suhbat vidjetlari"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Bosh ekranga chiqariladigan suhbat ustiga bosing"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Yuqori aniqlik uchun telefonni aylantiring"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Buklanadigan qurilma ochilmoqda"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Buklanadigan qurilma aylantirilmoqda"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"buklangan"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"buklanmagan"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tezkor tugmalarni moslash"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tezkor tugma sozlash uchun tugmani bosing"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tezkor tugmalar qidiruvi"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hech narsa topilmadi"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Yigʻish belgisi"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Amal bajarish uchun Meta tugmasi belgisi"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus belgisi"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Moslash"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Tayyor"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatura sozlamalari"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tezkor tugma sozlash"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Bekor qilish"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tugmani bosing"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Bu tugmalar birikmasi band. Boshqasini ishlating."</string>
     <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>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index 5e6611c..1c32e9fb 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Oʻchiq"</item>
     <item msgid="3028994095749238254">"Yoniq"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Mavjud emas"</item>
+    <item msgid="6419996398343291862">"Yoqilmagan"</item>
+    <item msgid="5908720590832378783">"Yoniq"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 6752ceb..d8e3bc0 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Thiết bị đầu vào"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Thiết bị trợ thính"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Đang bật…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Không điều chỉnh được độ sáng vì độ sáng đang được\n ứng dụng trên cùng điều khiển"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Tự động xoay"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Tự động xoay màn hình"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Vị trí"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Nhấp để ghép nối thiết bị mới"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Không cập nhật được giá trị đặt trước"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Chế độ đặt sẵn"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Đã chọn"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Công cụ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Phụ đề trực tiếp"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ghi chú"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Bỏ chặn micrô của thiết bị?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Bỏ chặn camera của thiết bị?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Bỏ chặn máy ảnh và micrô của thiết bị?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Không có thông báo nào"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Không có thông báo mới"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Chế độ Giảm dần âm lượng thông báo đang bật"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Khi bạn nhận quá nhiều thông báo cùng lúc, âm lượng và cảnh báo tự động giảm trong tối đa 2 phút."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Tắt"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Mở khoá để xem thông báo cũ"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Chuyển sang ứng dụng bên phải hoặc ở dưới khi đang chia đôi màn hình"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Chuyển sang ứng dụng bên trái hoặc ở trên khi đang chia đôi màn hình"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Trong chế độ chia đôi màn hình: thay một ứng dụng bằng ứng dụng khác"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Di chuyển cửa sổ đang hoạt động giữa các màn hình"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Đầu vào"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Chuyển sang ngôn ngữ tiếp theo"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Chuyển về ngôn ngữ trước"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Hãy dùng ít hơn <xliff:g id="LENGTH">%1$d</xliff:g> ký tự"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Tiện ích trò chuyện"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Nhấn vào một cuộc trò chuyện để thêm cuộc trò chuyện đó vào Màn hình chính"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Để có độ phân giải cao hơn, hãy lật điện thoại"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Thiết bị có thể gập lại đang được mở ra"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Thiết bị có thể gập lại đang được lật ngược"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"gập"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"mở"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hỗ trợ tiếp cận"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Phím tắt"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tuỳ chỉnh phím tắt"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Nhấn phím để chỉ định phím tắt"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tìm lối tắt"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Không có kết quả tìm kiếm nào"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Biểu tượng Thu gọn"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Biểu tượng phím Meta (phím hành động)"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Biểu tượng dấu cộng"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tuỳ chỉnh"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Xong"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Cài đặt bàn phím"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Đặt phím tắt"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Huỷ"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Nhấn phím"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tổ hợp phím đã được sử dụng. Hãy thử một phím khác."</string>
     <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>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index 8aa360b..466eb3d6 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Đang tắt"</item>
     <item msgid="3028994095749238254">"Đang bật"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Không có"</item>
+    <item msgid="6419996398343291862">"Đang tắt"</item>
+    <item msgid="5908720590832378783">"Đang bật"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 6e76bb7..d9a974a 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -311,7 +311,7 @@
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"断开连接"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"启用"</string>
     <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"明天自动开启"</string>
-    <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"快速分享、查找我的设备等功能会使用蓝牙"</string>
+    <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"“快速分享”“查找我的设备”等功能会使用蓝牙"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"蓝牙将在明天早上开启"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"分享音频"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"正在分享音频"</string>
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"输入"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"助听器"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"正在开启…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"亮度无法调整,因为它正在被\n顶层应用控制"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自动屏幕旋转"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自动旋转屏幕"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"位置信息"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"点击即可与新设备配对"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"无法更新预设"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"预设"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已选择"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"实时字幕"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"记事"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解锁设备麦克风吗?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解锁设备摄像头吗?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要解锁设备摄像头和麦克风吗?"</string>
@@ -449,7 +449,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>
@@ -871,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分屏模式时,切换到右侧或下方的应用"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分屏模式时,切换到左侧或上方的应用"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"在分屏期间:将一个应用替换为另一个应用"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"在各个显示屏之间移动活动窗口"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"输入"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"切换到下一种语言"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"切换到上一种语言"</string>
@@ -1221,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"必须少于 <xliff:g id="LENGTH">%1$d</xliff:g> 个字符"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build 号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已将 Build 号复制到剪贴板。"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"开放式对话"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"对话微件"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"点按对话即可将其添加到主屏幕"</string>
@@ -1356,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"若要获得更高的分辨率,请翻转手机"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展开可折叠设备"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻转可折叠设备"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"折叠状态"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"展开状态"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"无障碍功能"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"键盘快捷键"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自定义键盘快捷键"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"按下按键即可指定快捷键"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜索快捷键"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"无搜索结果"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收起图标"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"操作键或元键图标"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"加号图标"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"自定义"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完成"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"键盘设置"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"设置快捷键"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按下按键"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"按键组合已被使用,请尝试使用其他按键。"</string>
     <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>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index 2259076..65415f6 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"已关闭"</item>
     <item msgid="3028994095749238254">"已开启"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"不可用"</item>
+    <item msgid="6419996398343291862">"关闭"</item>
+    <item msgid="5908720590832378783">"开启"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 32fe2a1..443b855 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"輸入"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"助聽器"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"正在開啟…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"無法調整亮度,因為\n目前是由上層應用程式控制亮度"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"位置"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"㩒一下就可以配對新裝置"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"揀咗"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解除封鎖裝置相機嗎?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要解除封鎖裝置相機和麥克風嗎?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"通知緩和功能現已啟用"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"當你在短時間內收到太多通知時,裝置就會調低音量並減少通知數量最多兩分鐘。"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割螢幕時,切換至右邊或下方的應用程式"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割螢幕時,切換至左邊或上方的應用程式"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割螢幕期間:更換應用程式"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"在不同畫面間移動使用中的視窗"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"輸入"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"切換至下一個語言"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"切換至上一個語言"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"請使用少於 <xliff:g id="LENGTH">%1$d</xliff:g> 個字元"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"開啟對話"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"對話小工具"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"輕按對話即可新增至主畫面"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"如要提高解像度,請切換至手機後置鏡頭"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開折疊式裝置"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"已摺疊"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"已打開"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙功能"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"按鍵即可指派快速鍵"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"沒有相符的搜尋結果"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"快捷操作鍵或修飾鍵圖示"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"加號圖示"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"自訂"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完成"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"鍵盤設定"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"設定快速鍵"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按鍵"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"此按鍵組合已在使用,請改用其他按鍵。"</string>
     <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>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index c5e05c9..0882be7 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"關閉"</item>
     <item msgid="3028994095749238254">"開啟"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"無法使用"</item>
+    <item msgid="6419996398343291862">"關閉"</item>
+    <item msgid="5908720590832378783">"開啟"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9778e70..4b84f25 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"輸入"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"助聽器"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"開啟中…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"無法調整亮度,因為\n目前是由上層應用程式控制亮度"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"定位"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"按一下即可配對新裝置"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設設定"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已選取"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"解除封鎖裝置相機?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要將裝置的相機和麥克風解除封鎖嗎?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"「通知冷卻」設定已開啟"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"如果一次收到過多通知,裝置就會自動降低音量並減少通知數量,持續時間最多 2 分鐘。"</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割畫面時,切換到右邊或上方的應用程式"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割畫面時,切換到左邊或上方的應用程式"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割畫面期間:更換應用程式"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"在不同畫面間移動使用中的視窗"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"輸入"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"切換到下一個語言"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"切換到上一個語言"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"不得超過 <xliff:g id="LENGTH">%1$d</xliff:g> 個半形字元"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"開放式對話"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"對話小工具"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"輕觸對話即可新增至主畫面"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"如要提高解析度,請切換至手機後置鏡頭"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"已摺疊"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"已展開"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"按下按鍵即可指派快速鍵"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"找不到相符的搜尋結果"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"快捷操作鍵或修飾鍵圖示"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"加號圖示"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"自訂"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完成"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"鍵盤設定"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"設定快速鍵"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按下按鍵"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"這個按鍵組合已在使用中,請改用其他按鍵。"</string>
     <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>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index 2d34b38..f94b044 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"已關閉"</item>
     <item msgid="3028994095749238254">"已開啟"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"無法使用"</item>
+    <item msgid="6419996398343291862">"關閉"</item>
+    <item msgid="5908720590832378783">"開啟"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9f8cf1f..4afb67d 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -326,8 +326,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Okokufaka"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Imishini yendlebe"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Iyavula..."</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ayikwazi ukulungisa ukukhanya ngoba ilawulwa\n yi-app ephezulu"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ukuphenduka okuzenzakalelayo"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Phendula iskrini ngokuzenzakalela"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Indawo"</string>
@@ -415,9 +414,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Chofoza ukuze ubhangqe idivayisi entsha"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ayikwazanga ukubuyekeza ukusetha ngaphambilini"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ukusetha ngaphambilini"</string>
+    <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Okukhethiwe"</string>
+    <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Amathuluzi"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okushuthwe Bukhoma"</string>
-    <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
-    <skip />
+    <string name="quick_settings_notes_label" msgid="1028004078001002623">"Inothi"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vulela imakrofoni yedivayisi?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vulela ikhamera yedivayisi?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vulela ikhamera yedivayisi nemakrofoni?"</string>
@@ -593,8 +593,7 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Azikho izaziso"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Azikho izaziso ezintsha"</string>
-    <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
-    <skip />
+    <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Ukwehlisa umsindo wezaziso manje kuvuliwe"</string>
     <string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Ivolumu yedivayisi yakho kanye nezexwayiso kuncishiswa ngokuzenzakalelayo imizuzu efika kwemi-2 lapho uthola izaziso eziningi kakhulu ngesikhathi esisodwa."</string>
     <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vala"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vula ukuze ubone izaziso ezindala"</string>
@@ -872,8 +871,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Shintshela ku-app ngakwesokudla noma ngezansi ngenkathi usebenzisa uhlukanisa isikrini"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Shintshela ku-app ngakwesokunxele noma ngaphezulu ngenkathi usebenzisa ukuhlukanisa isikrini"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ngesikhathi sokuhlukaniswa kwesikrini: shintsha i-app ngenye"</string>
-    <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
-    <skip />
+    <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Hambisa iwindi elisebenzayo phakathi kwezibonisi"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Okokufaka"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Shintshela olimini olulandelayo"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Shintshela olimini lwangaphambili"</string>
@@ -1222,6 +1220,8 @@
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Sebenzisa isinhlamvu ezimbalwa kuneziyi-<xliff:g id="LENGTH">%1$d</xliff:g>"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string>
+    <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+    <skip />
     <string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Amawijethi wengxoxo"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Thepha ingxoxo ukuyengeza Kusikrini sakho sasekhaya"</string>
@@ -1357,6 +1357,8 @@
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ukuze uthole ukulungiswa okuphezulu, phendula ifoni"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Idivayisi egoqekayo iyembulwa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Idivayisi egoqekayo iphendulwa nxazonke"</string>
+    <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+    <skip />
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kugoqiwe"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kuvuliwe"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ukufinyeleleka"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Izinqamuleli zekhibhodi"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Hlela izinqamuleli zekhibhodi ngendlela oyifisayo"</string>
-    <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
-    <skip />
+    <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Cindezela ukhiye ukuze unikeze isinqamuleli"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sesha izinqamuleli"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ayikho imiphumela yosesho"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Goqa isithonjana"</string>
-    <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
-    <skip />
+    <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Isithonjana sesenzo noma seMeta"</string>
+    <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Isithonjana sesengezo"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Enza ngendlela oyifisayo"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Kwenziwe"</string>
     <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>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Amasethingi Ekhibhodi"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
-    <skip />
-    <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Setha isinqamuleli"</string>
+    <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Khansela"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Cindezela ukhiye"</string>
+    <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Inhlanganisela yokhiye isiyasetshenziswa kakade. Zama omunye ukhiye."</string>
     <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>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index 1a7ce57..be5c6d8 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -191,7 +191,9 @@
     <item msgid="3079622119444911877">"Kuvaliwe"</item>
     <item msgid="3028994095749238254">"Kuvuliwe"</item>
   </string-array>
-    <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
-    <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
-    <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+  <string-array name="tile_states_notes">
+    <item msgid="5894333929299989301">"Ayitholakali"</item>
+    <item msgid="6419996398343291862">"Valiwe"</item>
+    <item msgid="5908720590832378783">"Vuliwe"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 48af82a..42e9092 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -506,6 +506,12 @@
          icon will be shown. -->
     <string name="config_screenshotFilesApp" translatable="false"></string>
 
+    <!-- Recommends a UI mode for the default note-taking app when launched with
+         android.content.Intent#ACTION_CREATE_NOTE
+         0: No UI recommendation. The note app should use its default mode
+         1: Recommend a UI optimized for stylus input. -->
+    <integer name="config_preferredNotesMode">1</integer>
+
     <!-- The component name of the screenshot editing activity that provides the App Clips flow.
          The App Clips flow includes taking a screenshot, showing user screenshot cropping activity
          and finally letting user send the screenshot to the calling notes app. This activity
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index bb63632..2cbadd5 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -368,6 +368,9 @@
     <!-- The vertical space between items in the alert selections in the inline settings -->
     <dimen name="notification_guts_option_vertical_padding">16dp</dimen>
 
+    <!-- Extra space for guts bundle feedback button -->
+    <dimen name="notification_guts_bundle_feedback_size">48dp</dimen>
+
     <dimen name="notification_importance_toggle_size">48dp</dimen>
     <dimen name="notification_importance_button_separation">8dp</dimen>
     <dimen name="notification_importance_drawable_padding">8dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index c3f4222..864e630 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -753,7 +753,7 @@
     <!-- QuickSettings: Bluetooth dialog device in audio sharing default summary [CHAR LIMIT=50]-->
     <string name="quick_settings_bluetooth_device_audio_sharing">Audio Sharing</string>
     <!-- QuickSettings: Bluetooth dialog device summary for devices that are capable of audio sharing and switching to active[CHAR LIMIT=NONE]-->
-    <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active">Tap to switch or share audio</string>
+    <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active">Supports audio sharing</string>
     <!-- QuickSettings: Bluetooth dialog device saved default summary [CHAR LIMIT=NONE]-->
     <string name="quick_settings_bluetooth_device_saved">Saved</string>
     <!-- QuickSettings: Accessibility label to disconnect a device [CHAR LIMIT=NONE]-->
@@ -1336,6 +1336,10 @@
     <string name="communal_widgets_disclaimer_text">To open an app using a widget, you\u2019ll need to verify it\u2019s you. Also, keep in mind that anyone can view them, even when your tablet\u2019s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here.</string>
     <!-- Button for user to verify they understand the information presented. [CHAR LIMIT=50] -->
     <string name="communal_widgets_disclaimer_button">Got it</string>
+    <!-- Lockscreen affordance to open glanceable hub. [CHAR LIMIT=20] -->
+    <string name="glanceable_hub_lockscreen_affordance_label">Widgets</string>
+    <!-- Text explaining that the glanceable hub affordance is disabled. [CHAR LIMIT=NONE] -->
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text">To add Widgets on the lock screen as a shortcut, make sure it is enabled in settings.</string>
 
     <!-- Related to user switcher --><skip/>
 
@@ -2034,6 +2038,9 @@
     <!-- Text shown in notification guts for conversation notifications that don't implement the full feature -->
     <string name="no_shortcut"><xliff:g id="app_name" example="YouTube">%1$s</xliff:g> doesn\u2019t support conversation features</string>
 
+    <!-- [CHAR LIMIT=80] Text shown in feedback button in notification guts for a bundled notification -->
+    <string name="notification_guts_bundle_feedback">Provide Bundle Feedback</string>
+
     <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
     <string name="notification_unblockable_desc">These notifications can\'t be modified.</string>
 
@@ -2280,6 +2287,14 @@
     <string name="system_multitasking_replace">During split screen: replace an app from one to another</string>
     <!-- User visible title for the keyboard shortcut that moves a focused task to a next display [CHAR LIMIT=70] -->
     <string name="system_multitasking_move_to_next_display">Move active window between displays</string>
+    <!-- User visible title for the keyboard shortcut that snaps a task to the left in desktop mode [CHAR LIMIT=70] -->
+    <string name="system_desktop_mode_snap_left_window">Move window to the left</string>
+    <!-- User visible title for the keyboard shortcut that snaps a task to the right in desktop mode [CHAR LIMIT=70] -->
+    <string name="system_desktop_mode_snap_right_window">Move window to the right</string>
+    <!-- User visible title for the keyboard shortcut that toggles between maximizing and restoring a task's previous bounds in desktop mode [CHAR LIMIT=70] -->
+    <string name="system_desktop_mode_toggle_maximize_window">Maximize window</string>
+    <!-- User visible title for the keyboard shortcut that minimizes a task in desktop mode [CHAR LIMIT=70] -->
+    <string name="system_desktop_mode_minimize_window">Minimize window</string>
 
     <!-- User visible title for the input keyboard shortcuts list. [CHAR LIMIT=70] -->
     <string name="keyboard_shortcut_group_input">Input</string>
@@ -3753,11 +3768,20 @@
          is a component that shows the user which keyboard shortcuts they can use.
          [CHAR LIMIT=NONE] -->
     <string name="shortcut_helper_customize_mode_title">Customize keyboard shortcuts</string>
+    <!-- Title at the top of the keyboard shortcut helper remove shortcut dialog.
+         The helper is a component that shows the user which keyboard shortcuts they can use. Also
+         allows the user to add/remove custom shortcuts.[CHAR LIMIT=NONE] -->
+    <string name="shortcut_customize_mode_remove_shortcut_dialog_title">Remove shortcut?</string>
     <!-- Sub title at the top of the keyboard shortcut helper customization dialog. Explains to the
          user what action they need to take in the customization dialog to assign a new custom shortcut.
-         The helper is a component that shows the user which keyboard shortcuts they can use.
+         The shortcut customize dialog allows users to add/remove custom shortcuts
          [CHAR LIMIT=NONE] -->
-    <string name="shortcut_helper_customize_mode_sub_title">Press key to assign shortcut</string>
+    <string name="shortcut_customize_mode_add_shortcut_description">Press key to assign shortcut</string>
+    <!-- Sub title at the top of the remove custom shortcut dialog. Explains to the user what action
+         they're about to take when they click remove shortcut. The shortcut customize dialog allows
+         users to add/remove custom shortcuts
+         [CHAR LIMIT=NONE] -->
+    <string name="shortcut_customize_mode_remove_shortcut_description">This will delete your custom shortcut permanently.</string>
     <!-- Placeholder text shown in the search box of the keyboard shortcut helper, when the user
          hasn't typed in anything in the search box yet. The helper is a  component that shows the
          user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
@@ -3813,6 +3837,10 @@
          confirm and assign key combination to selected shortcut. The helper is a  component that
          shows the user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label">Set shortcut</string>
+    <!-- Label on the remove shortcut button in keyboard shortcut helper customize dialog, that allows user to
+         confirm and remove previously added custom shortcut. The helper is a  component that
+         shows the user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
+    <string name="shortcut_helper_customize_dialog_remove_button_label">Remove</string>
     <!-- Label on the cancel button in keyboard shortcut helper customize dialog, that allows user to
          cancel and exit shortcut customization dialog, returning to the main shortcut helper page.
          The helper is a  component that shows the user which keyboard shortcuts they can use.
@@ -3826,8 +3854,16 @@
     <!-- Error message displayed when the user select a key combination that is already in use while
          assigning a new custom key combination to a shortcut 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_customize_dialog_error_message">Key combination already in use. Try another key.</string>
-
+    <string name="shortcut_customizer_key_combination_in_use_error_message">Key combination already in use. Try another key.</string>
+    <!-- Generic error message displayed when the user selected key combination cannot be used as
+         custom keyboard shortcut in shortcut helper. The helper is a component that shows the user
+         which keyboard shortcuts they can use and allows users to customize their keyboard
+         shortcuts. [CHAR LIMIT=NONE] -->
+    <string name="shortcut_customizer_generic_error_message">Shortcut cannot be set.</string>
+    <!-- Plus sign, used in keyboard shortcut helper to combine keys for shortcut. E.g. Ctrl + A
+         The helper is a component that shows the user which keyboard shortcuts they can use.
+         [CHAR LIMIT=NONE] -->
+    <string name="shortcut_helper_plus_symbol">+</string>
 
     <!-- Keyboard touchpad tutorial scheduler-->
     <!-- Notification title for launching keyboard tutorial [CHAR_LIMIT=100] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index e14008a..0381811 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -831,6 +831,11 @@
         <item name="android:textColor">?attr/onSurfaceVariant</item>
     </style>
 
+    <style name="TextAppearance.QSEditTitle" >
+        <item name="android:fontFamily">"gsf-title-medium-emphasized"</item>
+        <item name="android:textColor">?attr/onSurfaceVariant</item>
+    </style>
+
     <style name="QSCustomizeToolbar" parent="@*android:style/Widget.DeviceDefault.Toolbar">
         <item name="android:textColor">?attr/onSurface</item>
         <item name="android:elevation">10dp</item>
diff --git a/packages/SystemUI/res/xml/volume_dialog_ringer_drawer_motion_scene.xml b/packages/SystemUI/res/xml/volume_dialog_ringer_drawer_motion_scene.xml
new file mode 100644
index 0000000..877637e
--- /dev/null
+++ b/packages/SystemUI/res/xml/volume_dialog_ringer_drawer_motion_scene.xml
@@ -0,0 +1,49 @@
+<?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.
+  -->
+
+<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <Transition
+        android:id="@+id/transition"
+        app:constraintSetEnd="@+id/volume_dialog_ringer_drawer_open"
+        app:constraintSetStart="@+id/volume_dialog_ringer_drawer_close"
+        app:transitionEasing="path(0.05f, 0.7f, 0.1f, 1f)"
+        app:duration="400">
+    </Transition>
+
+    <ConstraintSet android:id="@+id/volume_dialog_ringer_drawer_close">
+        <Constraint
+            android:id="@+id/volume_ringer_drawer"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+    </ConstraintSet>
+
+    <ConstraintSet android:id="@+id/volume_dialog_ringer_drawer_open">
+        <Constraint
+            android:id="@+id/volume_ringer_drawer"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+    </ConstraintSet>
+
+</MotionScene>
\ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
index 76af813..7d220b5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
@@ -18,9 +18,11 @@
 
 import android.os.RemoteException;
 import android.util.Log;
+import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 import android.window.PictureInPictureSurfaceTransaction;
 import android.window.TaskSnapshot;
+import android.window.WindowAnimationState;
 
 import com.android.internal.os.IResultReceiver;
 import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -107,6 +109,17 @@
     }
 
     /**
+     * @see IRecentsAnimationController#handOffAnimation
+     */
+    public void handOffAnimation(RemoteAnimationTarget[] targets, WindowAnimationState[] states) {
+        try {
+            mAnimationController.handOffAnimation(targets, states);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to hand off animation", e);
+        }
+    }
+
+    /**
      * @see IRecentsAnimationController#detachNavigationBarFromApp
      */
     public void detachNavigationBarFromApp(boolean moveHomeToTop) {
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
index b116e29..dcbacec 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import static com.android.systemui.Flags.simPinUseSlotId;
 import static com.android.keyguard.logging.CarrierTextManagerLogger.REASON_ACTIVE_DATA_SUB_CHANGED;
 import static com.android.keyguard.logging.CarrierTextManagerLogger.REASON_ON_TELEPHONY_CAPABLE;
 import static com.android.keyguard.logging.CarrierTextManagerLogger.REASON_REFRESH_CARRIER_INFO;
@@ -368,10 +369,12 @@
 
         for (int i = 0; i < numSubs; i++) {
             int subId = subs.get(i).getSubscriptionId();
+            int slotId = subs.get(i).getSimSlotIndex();
             carrierNames[i] = "";
             subsIds[i] = subId;
-            subOrderBySlot[subs.get(i).getSimSlotIndex()] = i;
-            int simState = mKeyguardUpdateMonitor.getSimState(subId);
+            subOrderBySlot[slotId] = i;
+            int simState = simPinUseSlotId() ? mKeyguardUpdateMonitor.getSimStateForSlotId(slotId)
+                    :  mKeyguardUpdateMonitor.getSimState(subId);
             CharSequence carrierName = subs.get(i).getCarrierName();
             CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
             mLogger.logUpdateLoopStart(subId, simState, String.valueOf(carrierName));
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index 8ed675c..6ef7de4 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -16,7 +16,10 @@
 
 package com.android.keyguard;
 
+import static com.android.systemui.Flags.gsfBouncer;
+
 import android.content.Context;
+import android.graphics.Typeface;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
@@ -122,6 +125,9 @@
                 textId = com.android.internal.R.string.lockscreen_emergency_call;
             }
             setText(textId);
+            if (gsfBouncer()) {
+                setTypeface(Typeface.create("gsf-title-medium", Typeface.NORMAL));
+            }
         } else {
             setVisibility(View.GONE);
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 6bcacd0..fcaccd2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -32,6 +32,7 @@
 import static androidx.constraintlayout.widget.ConstraintSet.TOP;
 import static androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT;
 
+import static com.android.systemui.Flags.gsfBouncer;
 import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
 
 import static java.lang.Integer.max;
@@ -51,6 +52,7 @@
 import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.graphics.Typeface;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
@@ -1335,6 +1337,9 @@
                     true);
             mUserSwitcherViewGroup = mView.findViewById(R.id.keyguard_bouncer_user_switcher);
             mUserSwitcher = mView.findViewById(R.id.user_switcher_header);
+            if (gsfBouncer()) {
+                mUserSwitcher.setTypeface(Typeface.create("gsf-label-medium", Typeface.NORMAL));
+            }
         }
 
         interface UserSwitcherCallback {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 8ca0e80..2c8fff8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -44,6 +44,7 @@
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
 import static com.android.systemui.Flags.simPinBouncerReset;
+import static com.android.systemui.Flags.simPinUseSlotId;
 import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED;
 
 import android.annotation.AnyThread;
@@ -172,7 +173,6 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -318,6 +318,7 @@
 
     private final Object mSimDataLockObject = new Object();
     HashMap<Integer, SimData> mSimDatas = new HashMap<>();
+    HashMap<Integer, SimData> mSimDatasBySlotId = new HashMap<>();
     HashMap<Integer, ServiceState> mServiceStates = new HashMap<>();
 
     private int mPhoneState;
@@ -616,16 +617,17 @@
                 // It is possible for active subscriptions to become invalid (-1), and these will
                 // not be present in the subscriptionInfo list
                 synchronized (mSimDataLockObject) {
-                    Iterator<Map.Entry<Integer, SimData>> iter = mSimDatas.entrySet().iterator();
+                    var iter = simPinUseSlotId() ? mSimDatasBySlotId.entrySet().iterator()
+                            : mSimDatas.entrySet().iterator();
+
                     while (iter.hasNext()) {
-                        Map.Entry<Integer, SimData> simData = iter.next();
-                        if (!activeSubIds.contains(simData.getKey())) {
-                            mSimLogger.logInvalidSubId(simData.getKey());
+                        SimData data = iter.next().getValue();
+                        if (!activeSubIds.contains(data.subId)) {
+                            mSimLogger.logInvalidSubId(data.subId, data.slotId);
                             iter.remove();
 
-                            SimData data = simData.getValue();
                             for (int j = 0; j < mCallbacks.size(); j++) {
-                                KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
+                                var cb = mCallbacks.get(j).get();
                                 if (cb != null) {
                                     cb.onSimStateChanged(data.subId, data.slotId, data.simState);
                                 }
@@ -634,10 +636,15 @@
                     }
 
                     for (int i = 0; i < changedSubscriptions.size(); i++) {
-                        SimData data = mSimDatas.get(
-                                changedSubscriptions.get(i).getSubscriptionId());
+                        SimData data;
+                        if (simPinUseSlotId()) {
+                            data = mSimDatasBySlotId.get(changedSubscriptions.get(i)
+                                .getSimSlotIndex());
+                        } else {
+                            data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
+                        }
                         for (int j = 0; j < mCallbacks.size(); j++) {
-                            KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
+                            var cb = mCallbacks.get(j).get();
                             if (cb != null) {
                                 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
                             }
@@ -3409,12 +3416,13 @@
      */
     private void invalidateSlot(int slotId) {
         synchronized (mSimDataLockObject) {
-            Iterator<Map.Entry<Integer, SimData>> iter = mSimDatas.entrySet().iterator();
+            var iter = simPinUseSlotId() ? mSimDatasBySlotId.entrySet().iterator()
+                    : mSimDatas.entrySet().iterator();
             while (iter.hasNext()) {
                 SimData data = iter.next().getValue();
                 if (data.slotId == slotId
                         && SubscriptionManager.isValidSubscriptionId(data.subId)) {
-                    mSimLogger.logInvalidSubId(data.subId);
+                    mSimLogger.logInvalidSubId(data.subId, data.slotId);
                     iter.remove();
                 }
             }
@@ -3427,7 +3435,7 @@
     @VisibleForTesting
     void handleSimStateChange(int subId, int slotId, int state) {
         Assert.isMainThread();
-        mSimLogger.logSimState(subId, slotId, state);
+        mSimLogger.logSimState(subId, slotId, TelephonyManager.simStateToString(state));
 
         boolean becameAbsent = ABSENT_SIM_STATE_LIST.contains(state);
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -3444,11 +3452,15 @@
 
         // TODO(b/327476182): Preserve SIM_STATE_CARD_IO_ERROR sims in a separate data source.
         synchronized (mSimDataLockObject) {
-            SimData data = mSimDatas.get(subId);
+            SimData data = simPinUseSlotId() ? mSimDatasBySlotId.get(slotId) : mSimDatas.get(subId);
             final boolean changed;
             if (data == null) {
                 data = new SimData(state, slotId, subId);
-                mSimDatas.put(subId, data);
+                if (simPinUseSlotId()) {
+                    mSimDatasBySlotId.put(slotId, data);
+                } else {
+                    mSimDatas.put(subId, data);
+                }
                 changed = true; // no data yet; force update
             } else {
                 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
@@ -3727,7 +3739,8 @@
         callback.onTelephonyCapable(mTelephonyCapable);
 
         synchronized (mSimDataLockObject) {
-            for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
+            var simDatas = simPinUseSlotId() ? mSimDatasBySlotId : mSimDatas;
+            for (Entry<Integer, SimData> data : simDatas.entrySet()) {
                 final SimData state = data.getValue();
                 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
             }
@@ -3860,7 +3873,8 @@
      */
     public boolean isSimPinSecure() {
         synchronized (mSimDataLockObject) {
-            for (SimData data : mSimDatas.values()) {
+            var simDatas = simPinUseSlotId() ? mSimDatasBySlotId : mSimDatas;
+            for (SimData data : simDatas.values()) {
                 if (isSimPinSecure(data.simState)) {
                     return true;
                 }
@@ -3870,6 +3884,10 @@
     }
 
     public int getSimState(int subId) {
+        if (simPinUseSlotId()) {
+            throw new UnsupportedOperationException("Method not supported with flag "
+                    + "simPinUseSlotId");
+        }
         synchronized (mSimDataLockObject) {
             if (mSimDatas.containsKey(subId)) {
                 return mSimDatas.get(subId).simState;
@@ -3879,12 +3897,32 @@
         }
     }
 
+    /**
+     * Find the sim state for a slot id, or SIM_STATE_UNKNOWN if not found.
+     */
+    public int getSimStateForSlotId(int slotId) {
+        if (!simPinUseSlotId()) {
+            throw new UnsupportedOperationException("Method not supported without flag "
+                    + "simPinUseSlotId");
+        }
+        synchronized (mSimDataLockObject) {
+            if (mSimDatasBySlotId.containsKey(slotId)) {
+                return mSimDatasBySlotId.get(slotId).simState;
+            } else {
+                return TelephonyManager.SIM_STATE_UNKNOWN;
+            }
+        }
+    }
+
     private int getSlotId(int subId) {
         synchronized (mSimDataLockObject) {
-            if (!mSimDatas.containsKey(subId)) {
-                refreshSimState(subId, SubscriptionManager.getSlotIndex(subId));
+            var simDatas = simPinUseSlotId() ? mSimDatasBySlotId : mSimDatas;
+            int slotId = SubscriptionManager.getSlotIndex(subId);
+            int index = simPinUseSlotId() ? slotId : subId;
+            if (!simDatas.containsKey(index)) {
+                refreshSimState(subId, slotId);
             }
-            SimData simData = mSimDatas.get(subId);
+            SimData simData = simDatas.get(index);
             return simData != null ? simData.slotId : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         }
     }
@@ -3928,8 +3966,7 @@
     private boolean refreshSimState(int subId, int slotId) {
         int state = mTelephonyManager.getSimState(slotId);
         synchronized (mSimDataLockObject) {
-            SimData data = mSimDatas.get(subId);
-
+            SimData data = simPinUseSlotId() ? mSimDatasBySlotId.get(slotId) : mSimDatas.get(subId);
             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
                 invalidateSlot(slotId);
             }
@@ -3937,7 +3974,11 @@
             final boolean changed;
             if (data == null) {
                 data = new SimData(state, slotId, subId);
-                mSimDatas.put(subId, data);
+                if (simPinUseSlotId()) {
+                    mSimDatasBySlotId.put(slotId, data);
+                } else {
+                    mSimDatas.put(subId, data);
+                }
                 changed = true; // no data yet; force update
             } else {
                 changed = data.simState != state;
@@ -4033,10 +4074,17 @@
         for (int i = 0; i < list.size(); i++) {
             final SubscriptionInfo info = list.get(i);
             final int id = info.getSubscriptionId();
-            int slotId = getSlotId(id);
-            if (state == getSimState(id) && bestSlotId > slotId) {
-                resultId = id;
-                bestSlotId = slotId;
+            final int slotId = info.getSimSlotIndex();
+            if (simPinUseSlotId()) {
+                if (state == getSimStateForSlotId(slotId) && bestSlotId > slotId) {
+                    resultId = id;
+                    bestSlotId = slotId;
+                }
+            } else {
+                if (state == getSimState(id) && bestSlotId > slotId) {
+                    resultId = id;
+                    bestSlotId = slotId;
+                }
             }
         }
         return resultId;
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 7fe4ec8..ebde8a3 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -15,11 +15,13 @@
  */
 package com.android.keyguard;
 
+import static com.android.systemui.Flags.gsfBouncer;
 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
 
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
+import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
 import android.os.PowerManager;
@@ -158,6 +160,9 @@
         int klondikeColor = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary)
                 .getDefaultColor();
         mDigitText.setTextColor(textColor);
+        if (gsfBouncer()) {
+            mDigitText.setTypeface(Typeface.create("gsf-label-large-emphasized", Typeface.NORMAL));
+        }
         mKlondikeText.setTextColor(klondikeColor);
 
         if (mAnimator != null) mAnimator.reloadColors(getContext());
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/SimLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/SimLogger.kt
index a81698b..fb26c6a 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/SimLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/SimLogger.kt
@@ -47,12 +47,15 @@
 
     fun log(@CompileTimeConstant msg: String, level: LogLevel) = logBuffer.log(TAG, level, msg)
 
-    fun logInvalidSubId(subId: Int) {
+    fun logInvalidSubId(subId: Int, slotId: Int) {
         logBuffer.log(
             TAG,
             INFO,
-            { int1 = subId },
-            { "Previously active sub id $int1 is now invalid, will remove" },
+            {
+                int1 = subId
+                int2 = slotId
+            },
+            { "Previously active subId: $int1, slotId: $int2 is now invalid, will remove" },
         )
     }
 
@@ -94,16 +97,16 @@
         )
     }
 
-    fun logSimState(subId: Int, slotId: Int, state: Int) {
+    fun logSimState(subId: Int, slotId: Int, state: String) {
         logBuffer.log(
             TAG,
             DEBUG,
             {
                 int1 = subId
                 int2 = slotId
-                long1 = state.toLong()
+                str1 = state
             },
-            { "handleSimStateChange(subId=$int1, slotId=$int2, state=$long1)" },
+            { "handleSimStateChange(subId=$int1, slotId=$int2, state=$str1)" },
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index e91bb6a..4723ab9 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -305,7 +305,7 @@
         }
         if (mMagnificationMode != mode) {
             mMagnificationMode = mode;
-            mImageView.setImageResource(getIconResId(mMagnificationMode));
+            mImageView.setImageResource(getIconResId());
         }
         if (!mIsVisible) {
             onConfigurationChanged(mContext.getResources().getConfiguration());
@@ -455,7 +455,7 @@
     }
 
     @VisibleForTesting
-    static int getIconResId(int mode) { // TODO(b/242233514): delete non used param
+    static int getIconResId() {
         return R.drawable.ic_open_in_new_window;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 7d5cf23..3794e7b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -283,7 +283,7 @@
                 com.android.internal.R.integer.config_shortAnimTime));
         updateDimensions();
 
-        final Size windowFrameSize = restoreMagnificationWindowFrameSizeIfPossible();
+        final Size windowFrameSize = restoreMagnificationWindowFrameIndexAndSizeIfPossible();
         setMagnificationFrame(windowFrameSize.getWidth(), windowFrameSize.getHeight(),
                 mWindowBounds.width() / 2, mWindowBounds.height() / 2);
         computeBounceAnimationScale();
@@ -541,7 +541,7 @@
             return false;
         }
         mWindowBounds.set(currentWindowBounds);
-        final Size windowFrameSize = restoreMagnificationWindowFrameSizeIfPossible();
+        final Size windowFrameSize = restoreMagnificationWindowFrameIndexAndSizeIfPossible();
         final float newCenterX = (getCenterX()) * mWindowBounds.width() / oldWindowBounds.width();
         final float newCenterY = (getCenterY()) * mWindowBounds.height() / oldWindowBounds.height();
 
@@ -787,18 +787,6 @@
         mMagnificationFrame.set(initX, initY, initX + width, initY + height);
     }
 
-    private Size restoreMagnificationWindowFrameSizeIfPossible() {
-        if (Flags.saveAndRestoreMagnificationSettingsButtons()) {
-            return restoreMagnificationWindowFrameIndexAndSizeIfPossible();
-        }
-
-        if (!mWindowMagnificationFrameSizePrefs.isPreferenceSavedForCurrentDensity()) {
-            return getDefaultMagnificationWindowFrameSize();
-        }
-
-        return mWindowMagnificationFrameSizePrefs.getSizeForCurrentDensity();
-    }
-
     private Size restoreMagnificationWindowFrameIndexAndSizeIfPossible() {
         if (!mWindowMagnificationFrameSizePrefs.isPreferenceSavedForCurrentDensity()) {
             notifyWindowSizeRestored(MagnificationSize.DEFAULT);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefs.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefs.java
index ee36c6e..558c87c 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefs.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefs.java
@@ -22,8 +22,6 @@
 import android.content.SharedPreferences;
 import android.util.Size;
 
-import com.android.systemui.Flags;
-
 /**
  * Class to handle SharedPreference for window magnification size.
  */
@@ -52,14 +50,10 @@
      * Saves the window frame size for current screen density.
      */
     public void saveIndexAndSizeForCurrentDensity(int index, Size size) {
-        if (Flags.saveAndRestoreMagnificationSettingsButtons()) {
-            mWindowMagnificationSizePreferences.edit()
-                    .putString(getKey(),
-                            WindowMagnificationFrameSpec.serialize(index, size)).apply();
-        } else {
-            mWindowMagnificationSizePreferences.edit()
-                    .putString(getKey(), size.toString()).apply();
-        }
+        mWindowMagnificationSizePreferences
+                .edit()
+                .putString(getKey(), WindowMagnificationFrameSpec.serialize(index, size))
+                .apply();
     }
 
     /**
@@ -91,13 +85,9 @@
      * Gets the size preference for current screen density.
      */
     public Size getSizeForCurrentDensity() {
-        if (Flags.saveAndRestoreMagnificationSettingsButtons()) {
-            return WindowMagnificationFrameSpec
-                    .deserialize(mWindowMagnificationSizePreferences.getString(getKey(), null))
-                    .getSize();
-        } else {
-            return Size.parseSize(mWindowMagnificationSizePreferences.getString(getKey(), null));
-        }
+        return WindowMagnificationFrameSpec.deserialize(
+                        mWindowMagnificationSizePreferences.getString(getKey(), null))
+                .getSize();
     }
 
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index 2f0ca6e..9d9f569 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -59,7 +59,6 @@
 import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.systemui.Flags;
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView;
 import com.android.systemui.res.R;
 import com.android.systemui.util.settings.SecureSettings;
@@ -460,12 +459,8 @@
                 mAllowDiagonalScrollingView.setVisibility(View.VISIBLE);
                 mFullScreenButton.setVisibility(View.GONE);
                 if (selectedButtonIndex == MagnificationSize.FULLSCREEN) {
-                    if (Flags.saveAndRestoreMagnificationSettingsButtons()) {
-                        selectedButtonIndex =
-                                windowMagnificationFrameSizePrefs.getIndexForCurrentDensity();
-                    } else {
-                        selectedButtonIndex = MagnificationSize.CUSTOM;
-                    }
+                    selectedButtonIndex =
+                            windowMagnificationFrameSizePrefs.getIndexForCurrentDensity();
                 }
                 break;
 
@@ -482,10 +477,8 @@
                 } else { // mode = ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
                     mEditButton.setVisibility(View.VISIBLE);
                     mAllowDiagonalScrollingView.setVisibility(View.VISIBLE);
-                    if (Flags.saveAndRestoreMagnificationSettingsButtons()) {
-                        selectedButtonIndex =
-                                windowMagnificationFrameSizePrefs.getIndexForCurrentDensity();
-                    }
+                    selectedButtonIndex =
+                            windowMagnificationFrameSizePrefs.getIndexForCurrentDensity();
                 }
                 break;
 
@@ -581,13 +574,15 @@
                 || (configDiff & ActivityInfo.CONFIG_ASSETS_PATHS) != 0
                 || (configDiff & ActivityInfo.CONFIG_FONT_SCALE) != 0
                 || (configDiff & ActivityInfo.CONFIG_LOCALE) != 0
-                || (configDiff & ActivityInfo.CONFIG_DENSITY) != 0) {
+                || (configDiff & ActivityInfo.CONFIG_DENSITY) != 0
+                || (configDiff & ActivityInfo.CONFIG_FONT_WEIGHT_ADJUSTMENT) != 0) {
             // We listen to following config changes to trigger layout inflation:
             // CONFIG_UI_MODE: theme change
             // CONFIG_ASSETS_PATHS: wallpaper change
             // CONFIG_FONT_SCALE: font size change
             // CONFIG_LOCALE: language change
             // CONFIG_DENSITY: display size change
+            // CONFIG_FONT_WEIGHT_ADJUSTMENT: bold text setting change
             mParams.width = getPanelWidth(mContext);
             mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt
index 60d80ef..3f717e2 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt
@@ -15,6 +15,7 @@
  */
 package com.android.systemui.accessibility.extradim
 
+import android.os.Handler
 import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
@@ -32,18 +33,21 @@
     private val extraDimDialogDelegateProvider: Provider<ExtraDimDialogDelegate>,
     private val mActivityStarter: ActivityStarter,
     private val dialogTransitionAnimator: DialogTransitionAnimator,
+    private val mainHandler: Handler,
 ) {
     private var dialog: SystemUIDialog? = null
 
     @JvmOverloads
     fun dismissKeyguardIfNeededAndShowDialog(expandable: Expandable? = null) {
-        mActivityStarter.executeRunnableDismissingKeyguard(
-            { showRemoveExtraDimShortcutsDialog(expandable) },
-            /* cancelAction= */ null,
-            /* dismissShade= */ false,
-            /* afterKeyguardGone= */ true,
-            /* deferred= */ false,
-        )
+        mainHandler.post {
+            mActivityStarter.executeRunnableDismissingKeyguard(
+                { showRemoveExtraDimShortcutsDialog(expandable) },
+                /* cancelAction= */ null,
+                /* dismissShade= */ true,
+                /* afterKeyguardGone= */ true,
+                /* deferred= */ false,
+            )
+        }
     }
 
     /** Show the dialog for removing all Extra Dim shortcuts. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt b/packages/SystemUI/src/com/android/systemui/activity/ActivityManagerModule.kt
similarity index 66%
copy from packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt
copy to packages/SystemUI/src/com/android/systemui/activity/ActivityManagerModule.kt
index 83551e9..db315e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/activity/ActivityManagerModule.kt
@@ -14,15 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone
+package com.android.systemui.activity
 
+import com.android.systemui.activity.data.repository.ActivityManagerRepository
+import com.android.systemui.activity.data.repository.ActivityManagerRepositoryImpl
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.policy.BaseHeadsUpManager
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import dagger.Binds
 import dagger.Module
 
 @Module
-interface HeadsUpModule {
-    @Binds @SysUISingleton fun bindsHeadsUpManager(hum: BaseHeadsUpManager): HeadsUpManager
+interface ActivityManagerModule {
+    @Binds
+    @SysUISingleton
+    fun activityManagerRepository(impl: ActivityManagerRepositoryImpl): ActivityManagerRepository
 }
diff --git a/packages/SystemUI/src/com/android/systemui/activity/data/repository/ActivityManagerRepository.kt b/packages/SystemUI/src/com/android/systemui/activity/data/repository/ActivityManagerRepository.kt
new file mode 100644
index 0000000..94614b7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/activity/data/repository/ActivityManagerRepository.kt
@@ -0,0 +1,118 @@
+/*
+ * 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.activity.data.repository
+
+import android.app.ActivityManager
+import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.log.core.Logger
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.onStart
+
+/** Repository for interfacing with [ActivityManager]. */
+interface ActivityManagerRepository {
+    /**
+     * Given a UID, creates a flow that emits true when the process with the given UID is visible to
+     * the user and false otherwise.
+     *
+     * @param identifyingLogTag a tag identifying who created this flow, used for logging.
+     */
+    fun createIsAppVisibleFlow(
+        creationUid: Int,
+        logger: Logger,
+        identifyingLogTag: String,
+    ): Flow<Boolean>
+}
+
+@SysUISingleton
+class ActivityManagerRepositoryImpl
+@Inject
+constructor(
+    @Background private val backgroundContext: CoroutineContext,
+    private val activityManager: ActivityManager,
+) : ActivityManagerRepository {
+    override fun createIsAppVisibleFlow(
+        creationUid: Int,
+        logger: Logger,
+        identifyingLogTag: String,
+    ): Flow<Boolean> {
+        return conflatedCallbackFlow {
+                val listener =
+                    object : ActivityManager.OnUidImportanceListener {
+                        override fun onUidImportance(uid: Int, importance: Int) {
+                            if (uid != creationUid) {
+                                return
+                            }
+                            val isAppVisible = isAppVisibleToUser(importance)
+                            logger.d({
+                                "$str1: #onUidImportance. importance=$int1, isAppVisible=$bool1"
+                            }) {
+                                str1 = identifyingLogTag
+                                int1 = importance
+                                bool1 = isAppVisible
+                            }
+                            trySend(isAppVisible)
+                        }
+                    }
+                try {
+                    // TODO(b/286258140): Replace this with the #addOnUidImportanceListener
+                    //  overload that filters to certain UIDs.
+                    activityManager.addOnUidImportanceListener(listener, IMPORTANCE_CUTPOINT)
+                } catch (e: SecurityException) {
+                    logger.e({ "$str1: Security exception on #addOnUidImportanceListener" }, e) {
+                        str1 = identifyingLogTag
+                    }
+                }
+
+                awaitClose { activityManager.removeOnUidImportanceListener(listener) }
+            }
+            .distinctUntilChanged()
+            .onStart {
+                try {
+                    val isVisibleOnStart =
+                        isAppVisibleToUser(activityManager.getUidImportance(creationUid))
+                    logger.d({ "$str1: Starting UID observation. isAppVisible=$bool1" }) {
+                        str1 = identifyingLogTag
+                        bool1 = isVisibleOnStart
+                    }
+                    emit(isVisibleOnStart)
+                } catch (e: SecurityException) {
+                    logger.e({ "$str1: Security exception on #getUidImportance" }, e) {
+                        str1 = identifyingLogTag
+                    }
+                    emit(false)
+                }
+            }
+            .flowOn(backgroundContext)
+    }
+
+    /** Returns true if the given [importance] represents an app that's visible to the user. */
+    private fun isAppVisibleToUser(importance: Int): Boolean {
+        return importance <= IMPORTANCE_CUTPOINT
+    }
+
+    companion object {
+        private const val IMPORTANCE_CUTPOINT = IMPORTANCE_FOREGROUND
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index e634726..1176cb0 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -19,6 +19,7 @@
 
 import static com.android.settingslib.flags.Flags.newStatusBarIcons;
 import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.Flags.gsfQuickSettings;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
@@ -33,6 +34,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
+import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -384,6 +386,9 @@
         }
         float fontHeight = mBatteryPercentView.getPaint().getFontMetricsInt(null);
         mBatteryPercentView.setLineHeight(TypedValue.COMPLEX_UNIT_PX, fontHeight);
+        if (gsfQuickSettings()) {
+            mBatteryPercentView.setTypeface(Typeface.create("gsf-label-large", Typeface.NORMAL));
+        }
         if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
         addView(mBatteryPercentView, new LayoutParams(
                 LayoutParams.WRAP_CONTENT,
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt
index 13c7209..4dc2a13 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt
@@ -27,7 +27,6 @@
 import com.android.settingslib.bluetooth.LeAudioProfile
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast
 import com.android.settingslib.bluetooth.LocalBluetoothManager
-import com.android.settingslib.flags.Flags.audioSharingQsDialogImprovement
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
@@ -69,7 +68,7 @@
                 }
                 deviceItem.type ==
                     DeviceItemType.AVAILABLE_AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE -> {
-                    if (audioSharingQsDialogImprovement()) {
+                    if (audioSharingInteractor.qsDialogImprovementAvailable()) {
                         withContext(mainDispatcher) {
                             delegateFactory
                                 .create(deviceItem.cachedBluetoothDevice)
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt
index 65f1105..c4f26cd 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt
@@ -16,10 +16,13 @@
 
 package com.android.systemui.bluetooth.qsdialog
 
+import android.content.Context
+import androidx.annotation.WorkerThread
 import com.android.settingslib.bluetooth.BluetoothUtils
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
 import com.android.settingslib.bluetooth.LocalBluetoothManager
-import com.android.settingslib.bluetooth.onPlaybackStarted
+import com.android.settingslib.bluetooth.onBroadcastMetadataChanged
+import com.android.settingslib.flags.Flags.audioSharingQsDialogImprovement
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import javax.inject.Inject
@@ -52,6 +55,8 @@
     suspend fun startAudioSharing()
 
     suspend fun audioSharingAvailable(): Boolean
+
+    suspend fun qsDialogImprovementAvailable(): Boolean
 }
 
 @SysUISingleton
@@ -59,11 +64,14 @@
 class AudioSharingInteractorImpl
 @Inject
 constructor(
+    private val context: Context,
     private val localBluetoothManager: LocalBluetoothManager?,
     private val audioSharingRepository: AudioSharingRepository,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
 ) : AudioSharingInteractor {
 
+    private var previewEnabled: Boolean? = null
+
     override val isAudioSharingOn: Flow<Boolean> =
         flow { emit(audioSharingAvailable()) }
             .flatMapLatest { isEnabled ->
@@ -93,10 +101,10 @@
                     isAudioSharingOn
                         .mapNotNull { audioSharingOn ->
                             if (audioSharingOn) {
-                                // onPlaybackStarted could emit multiple times during one
-                                // audio sharing session, we only perform add source on the
-                                // first time
-                                profile.onPlaybackStarted.firstOrNull()
+                                // onBroadcastMetadataChanged could emit multiple times during one
+                                // audio sharing session, we only perform add source on the first
+                                // time
+                                profile.onBroadcastMetadataChanged.firstOrNull()
                             } else {
                                 null
                             }
@@ -141,6 +149,20 @@
     override suspend fun audioSharingAvailable(): Boolean {
         return audioSharingRepository.audioSharingAvailable()
     }
+
+    override suspend fun qsDialogImprovementAvailable(): Boolean {
+        return withContext(backgroundDispatcher) {
+            audioSharingQsDialogImprovement() || isAudioSharingPreviewEnabled()
+        }
+    }
+
+    @WorkerThread
+    private fun isAudioSharingPreviewEnabled(): Boolean {
+        if (previewEnabled == null) {
+            previewEnabled = BluetoothUtils.isAudioSharingPreviewEnabled(context.contentResolver)
+        }
+        return previewEnabled ?: false
+    }
 }
 
 @SysUISingleton
@@ -160,4 +182,6 @@
     override suspend fun startAudioSharing() {}
 
     override suspend fun audioSharingAvailable(): Boolean = false
+
+    override suspend fun qsDialogImprovementAvailable(): Boolean = false
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
index b255a4f..497d8cf 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
@@ -26,10 +26,10 @@
 import androidx.annotation.DimenRes
 import androidx.annotation.StringRes
 import androidx.annotation.VisibleForTesting
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.UiEventLogger
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast
-import com.android.settingslib.flags.Flags.audioSharingQsDialogImprovement
 import com.android.systemui.Prefs
 import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogTransitionAnimator
@@ -56,7 +56,6 @@
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
 import kotlinx.coroutines.withContext
 
 /** ViewModel for Bluetooth Dialog after clicking on the Bluetooth QS tile. */
@@ -145,7 +144,7 @@
                         bluetoothDeviceMetadataInteractor.metadataUpdate,
                         if (
                             audioSharingInteractor.audioSharingAvailable() &&
-                                audioSharingQsDialogImprovement()
+                                audioSharingInteractor.qsDialogImprovementAvailable()
                         ) {
                             audioSharingInteractor.audioSourceStateUpdate
                         } else {
@@ -165,7 +164,7 @@
                     .launchIn(this)
 
                 if (audioSharingInteractor.audioSharingAvailable()) {
-                    if (audioSharingQsDialogImprovement()) {
+                    if (audioSharingInteractor.qsDialogImprovementAvailable()) {
                         launch { audioSharingInteractor.handleAudioSourceWhenReady() }
                     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/dagger/AudioSharingModule.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/dagger/AudioSharingModule.kt
index 8b5fde3..afe9a1e 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/dagger/AudioSharingModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/dagger/AudioSharingModule.kt
@@ -55,7 +55,10 @@
             settingsLibAudioSharingRepository: SettingsLibAudioSharingRepository,
             @Background backgroundDispatcher: CoroutineDispatcher,
         ): AudioSharingRepository =
-            if (Flags.enableLeAudioSharing() && localBluetoothManager != null) {
+            if (
+                (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) &&
+                    localBluetoothManager != null
+            ) {
                 AudioSharingRepositoryImpl(
                     localBluetoothManager,
                     settingsLibAudioSharingRepository,
@@ -72,7 +75,10 @@
             impl: Lazy<AudioSharingInteractorImpl>,
             emptyImpl: Lazy<AudioSharingInteractorEmptyImpl>,
         ): AudioSharingInteractor =
-            if (Flags.enableLeAudioSharing() && localBluetoothManager != null) {
+            if (
+                (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) &&
+                    localBluetoothManager != null
+            ) {
                 impl.get()
             } else {
                 emptyImpl.get()
@@ -85,7 +91,10 @@
             audioSharingImpl: Lazy<AudioSharingDeviceItemActionInteractorImpl>,
             impl: Lazy<DeviceItemActionInteractorImpl>,
         ): DeviceItemActionInteractor =
-            if (Flags.enableLeAudioSharing() && localBluetoothManager != null) {
+            if (
+                (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) &&
+                    localBluetoothManager != null
+            ) {
                 audioSharingImpl.get()
             } else {
                 impl.get()
@@ -97,7 +106,10 @@
             localBluetoothManager: LocalBluetoothManager?
         ): List<DeviceItemFactory> = buildList {
             add(ActiveMediaDeviceItemFactory())
-            if (Flags.enableLeAudioSharing() && localBluetoothManager != null) {
+            if (
+                (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) &&
+                    localBluetoothManager != null
+            ) {
                 add(AudioSharingMediaDeviceItemFactory(localBluetoothManager))
                 add(AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager))
             }
@@ -112,7 +124,10 @@
             localBluetoothManager: LocalBluetoothManager?
         ): List<DeviceItemType> = buildList {
             add(DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
-            if (Flags.enableLeAudioSharing() && localBluetoothManager != null) {
+            if (
+                (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) &&
+                    localBluetoothManager != null
+            ) {
                 add(DeviceItemType.AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE)
                 add(DeviceItemType.AVAILABLE_AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt
index 79a11ee..ad49fd0 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt
@@ -17,11 +17,13 @@
 package com.android.systemui.bouncer.ui
 
 import android.content.Context
+import android.graphics.Typeface
 import android.util.AttributeSet
 import android.widget.LinearLayout
 import com.android.keyguard.BouncerKeyguardMessageArea
 import com.android.keyguard.KeyguardMessageArea
 import com.android.keyguard.KeyguardMessageAreaController
+import com.android.systemui.Flags
 import com.android.systemui.res.R
 
 class BouncerMessageView : LinearLayout {
@@ -37,10 +39,20 @@
     var secondaryMessageView: BouncerKeyguardMessageArea? = null
     var primaryMessage: KeyguardMessageAreaController<KeyguardMessageArea>? = null
     var secondaryMessage: KeyguardMessageAreaController<KeyguardMessageArea>? = null
+
     override fun onFinishInflate() {
         super.onFinishInflate()
         primaryMessageView = findViewById(R.id.bouncer_primary_message_area)
         secondaryMessageView = findViewById(R.id.bouncer_secondary_message_area)
+
+        if (Flags.gsfBouncer()) {
+            primaryMessageView?.apply {
+                typeface = Typeface.create("gsf-title-large-emphasized", Typeface.NORMAL)
+            }
+            secondaryMessageView?.apply {
+                typeface = Typeface.create("gsf-title-medium-emphasized", Typeface.NORMAL)
+            }
+        }
     }
 
     fun init(factory: KeyguardMessageAreaController.Factory) {
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
index ccd953d..5bad9fc 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.brightness.ui.compose
 
+import android.view.MotionEvent
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.gestures.Orientation
@@ -41,6 +42,7 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.pointer.pointerInteropFilter
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.colorResource
 import androidx.compose.ui.res.stringResource
@@ -221,7 +223,16 @@
                     )
                     .then(if (viewModel.showMirror) Modifier.drawInOverlay() else Modifier)
                     .sliderBackground(containerColor)
-                    .fillMaxWidth(),
+                    .fillMaxWidth()
+                    .pointerInteropFilter {
+                        if (
+                            it.actionMasked == MotionEvent.ACTION_UP ||
+                                it.actionMasked == MotionEvent.ACTION_CANCEL
+                        ) {
+                            viewModel.emitBrightnessTouchForFalsing()
+                        }
+                        false
+                    },
             formatter = viewModel::formatValue,
             hapticsViewModelFactory = viewModel.hapticsViewModelFactory,
         )
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
index 1630ee5..7df7155 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
@@ -16,12 +16,14 @@
 
 package com.android.systemui.brightness.ui.viewmodel
 
-import androidx.compose.runtime.getValue
 import android.content.Context
 import androidx.annotation.StringRes
+import androidx.compose.runtime.getValue
 import com.android.systemui.brightness.domain.interactor.BrightnessPolicyEnforcementInteractor
 import com.android.systemui.brightness.domain.interactor.ScreenBrightnessInteractor
 import com.android.systemui.brightness.shared.model.GammaBrightness
+import com.android.systemui.classifier.Classifier
+import com.android.systemui.classifier.domain.interactor.FalsingInteractor
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.Text
@@ -52,6 +54,7 @@
     private val brightnessPolicyEnforcementInteractor: BrightnessPolicyEnforcementInteractor,
     val hapticsViewModelFactory: SliderHapticsViewModel.Factory,
     private val brightnessMirrorShowingInteractor: BrightnessMirrorShowingInteractor,
+    private val falsingInteractor: FalsingInteractor,
     @Assisted private val supportsMirroring: Boolean,
     private val brightnessWarningToast: BrightnessWarningToast,
 ) : ExclusiveActivatable() {
@@ -87,6 +90,10 @@
         brightnessWarningToast.show(viewContext, resId)
     }
 
+    fun emitBrightnessTouchForFalsing() {
+        falsingInteractor.isFalseTouch(Classifier.BRIGHTNESS_SLIDER)
+    }
+
     /**
      * As a brightness slider is dragged, the corresponding events should be sent using this method.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt b/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt
index 57e9ade..074b64e 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.classifier.FalsingCollectorActual
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.FalsingManager.Penalty
 import javax.inject.Inject
 
 /**
@@ -63,12 +64,13 @@
      * Inserts the given [result] into the falsing system, affecting future runs of the classifier
      * as if this was a result that had organically happened before.
      */
-    fun updateFalseConfidence(
-        result: FalsingClassifier.Result,
-    ) = collector.updateFalseConfidence(result)
+    fun updateFalseConfidence(result: FalsingClassifier.Result) =
+        collector.updateFalseConfidence(result)
 
     /** Returns `true` if the gesture should be rejected. */
-    fun isFalseTouch(
-        @Classifier.InteractionType interactionType: Int,
-    ): Boolean = manager.isFalseTouch(interactionType)
+    fun isFalseTouch(@Classifier.InteractionType interactionType: Int): Boolean =
+        manager.isFalseTouch(interactionType)
+
+    /** Returns `true` if the tap gesture should be rejected */
+    fun isFalseTap(@Penalty penalty: Int): Boolean = manager.isFalseTap(penalty)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index 4f9443e..d648b9c 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -18,16 +18,19 @@
 
 import android.os.UserHandle
 import android.provider.Settings
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.compose.animation.scene.SceneKey
 import com.android.compose.animation.scene.TransitionKey
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.CoreStartable
+import com.android.systemui.Flags.communalHubOnMobile
 import com.android.systemui.Flags.communalSceneKtfRefactor
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
 import com.android.systemui.communal.shared.log.CommunalUiEvent
 import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.communal.shared.model.CommunalScenes.isCommunal
 import com.android.systemui.communal.shared.model.CommunalTransitionKeys
 import com.android.systemui.communal.shared.model.EditModeState
 import com.android.systemui.dagger.SysUISingleton
@@ -35,7 +38,6 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dock.DockManager
-import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -62,7 +64,6 @@
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
 import kotlinx.coroutines.withContext
 
 /**
@@ -83,7 +84,6 @@
     private val systemSettings: SystemSettings,
     centralSurfacesOpt: Optional<CentralSurfaces>,
     private val notificationShadeWindowController: NotificationShadeWindowController,
-    private val featureFlagsClassic: FeatureFlagsClassic,
     @Application private val applicationScope: CoroutineScope,
     @Background private val bgScope: CoroutineScope,
     @Main private val mainDispatcher: CoroutineDispatcher,
@@ -168,7 +168,7 @@
                     communalInteractor.userActivity.emitOnStart(),
                 ) { scene, _ ->
                     // Only timeout if we're on the hub is open.
-                    scene == CommunalScenes.Communal
+                    scene.isCommunal()
                 }
                 .collectLatest { shouldTimeout ->
                     cancelHubTimeout()
@@ -182,7 +182,7 @@
                 .sample(communalSceneInteractor.currentScene, ::Pair)
                 .collectLatest { (isDreaming, scene) ->
                     this@CommunalSceneStartable.isDreaming = isDreaming
-                    if (scene == CommunalScenes.Communal && isDreaming && timeoutJob == null) {
+                    if (scene.isCommunal() && isDreaming && timeoutJob == null) {
                         // If dreaming starts after timeout has expired, ex. if dream restarts under
                         // the hub, just close the hub immediately.
                         communalSceneInteractor.changeScene(
@@ -217,6 +217,9 @@
                         communalSceneInteractor.changeScene(
                             newScene = CommunalScenes.Blank,
                             loggingReason = "hub timeout",
+                            transitionKey =
+                                if (communalHubOnMobile()) CommunalTransitionKeys.SimpleFade
+                                else null,
                         )
                         uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_TIMEOUT)
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
index 428b83d..ae08f2b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
@@ -98,16 +98,17 @@
         transitionKey: TransitionKey? = null,
         keyguardState: KeyguardState? = null,
     ) {
-        if (SceneContainerFlag.isEnabled) {
-            return sceneInteractor.changeScene(
-                toScene = newScene.toSceneContainerSceneKey(),
-                loggingReason = loggingReason,
-                transitionKey = transitionKey,
-                sceneState = keyguardState,
-            )
-        }
-
         applicationScope.launch("$TAG#changeScene") {
+            if (SceneContainerFlag.isEnabled) {
+                sceneInteractor.changeScene(
+                    toScene = newScene.toSceneContainerSceneKey(),
+                    loggingReason = loggingReason,
+                    transitionKey = transitionKey,
+                    sceneState = keyguardState,
+                )
+                return@launch
+            }
+
             if (currentScene.value == newScene) return@launch
             logger.logSceneChangeRequested(
                 from = currentScene.value,
@@ -125,16 +126,17 @@
         newScene: SceneKey,
         loggingReason: String,
         delayMillis: Long = 0,
-        keyguardState: KeyguardState? = null
+        keyguardState: KeyguardState? = null,
     ) {
-        if (SceneContainerFlag.isEnabled) {
-            return sceneInteractor.snapToScene(
-                toScene = newScene.toSceneContainerSceneKey(),
-                loggingReason = loggingReason,
-            )
-        }
-
         applicationScope.launch("$TAG#snapToScene") {
+            if (SceneContainerFlag.isEnabled) {
+                sceneInteractor.snapToScene(
+                    toScene = newScene.toSceneContainerSceneKey(),
+                    loggingReason = loggingReason,
+                )
+                return@launch
+            }
+
             delay(delayMillis)
             if (currentScene.value == newScene) return@launch
             logger.logSceneChangeRequested(
@@ -161,10 +163,7 @@
         } else {
             repository.currentScene
                 .pairwiseBy(initialValue = repository.currentScene.value) { from, to ->
-                    logger.logSceneChangeCommitted(
-                        from = from,
-                        to = to,
-                    )
+                    logger.logSceneChangeCommitted(from = from, to = to)
                     to
                 }
                 .stateIn(
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt
index e562dfc..7f15944 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt
@@ -18,9 +18,16 @@
 
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 
 /** Definition of the possible scenes for the communal UI. */
+@Deprecated(
+    "CommunalScenes are deprecated when SceneContainerFlag is enabled. " +
+        "Use com.android.systemui.scene.shared.model.Scenes instead. " +
+        "Use SceneKey.toSceneContainerSceneKey() to map legacy scenes to scene container scenes. " +
+        "Use SceneKey.isCommunal() to check whether a scene is a communal scene."
+)
 object CommunalScenes {
     /** The default scene, shows nothing and is only there to allow swiping to communal. */
     @JvmField val Blank = SceneKey("blank")
@@ -40,9 +47,8 @@
      * The rules are simple:
      * - A legacy communal scene maps to a communal scene in the Scene Transition Framework (STF).
      * - A legacy blank scene means that the communal scene layout does not render anything so
-     *   whatever is beneath the layout is shown. That usually means lockscreen or dream, both of
-     *   which are represented by the lockscreen scene in STF (but different keyguard states in
-     *   KTF).
+     *   whatever is beneath the layout is shown. That usually means lockscreen or dream, both in
+     *   STL are represented by the home scene family.
      */
     fun SceneKey.toSceneContainerSceneKey(): SceneKey {
         if (!isCommunalScene() || !SceneContainerFlag.isEnabled) {
@@ -51,8 +57,13 @@
 
         return when (this) {
             Communal -> Scenes.Communal
-            Blank -> Scenes.Lockscreen
+            Blank -> SceneFamilies.Home
             else -> throw Throwable("Unrecognized communal scene: $this")
         }
     }
+
+    /** Checks whether this is a communal scene based on whether [SceneContainerFlag] is enabled. */
+    fun SceneKey.isCommunal(): Boolean {
+        return if (SceneContainerFlag.isEnabled) this == Scenes.Communal else this == Communal
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
index 5ecf2e6b..a339af3 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
@@ -195,7 +195,7 @@
     open fun onDismissCtaTile() {}
 
     /** Called as the user starts dragging a widget to reorder. */
-    open fun onReorderWidgetStart() {}
+    open fun onReorderWidgetStart(draggingItemKey: String) {}
 
     /** Called as the user finishes dragging a widget to reorder. */
     open fun onReorderWidgetEnd() {}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
index 736ed5c..52bf000 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
@@ -164,9 +164,8 @@
         )
     }
 
-    override fun onReorderWidgetStart() {
-        // Clear selection status
-        setSelectedKey(null)
+    override fun onReorderWidgetStart(draggingItemKey: String) {
+        setSelectedKey(draggingItemKey)
         _reorderingWidgets.value = true
         uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_REORDER_WIDGET_START)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index 2e323d4..1fc5494 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -75,7 +75,7 @@
 import com.android.systemui.statusbar.notification.dagger.ReferenceNotificationsModule;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.DozeServiceHost;
-import com.android.systemui.statusbar.phone.HeadsUpModule;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpModule;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentStartableModule;
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 4cdf286..fcc3ea9 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -25,10 +25,13 @@
 import com.android.systemui.biometrics.BiometricNotificationService
 import com.android.systemui.bouncer.domain.startable.BouncerStartable
 import com.android.systemui.clipboardoverlay.ClipboardListener
+import com.android.systemui.complication.ComplicationTypesUpdater
+import com.android.systemui.complication.DreamClockTimeComplication
 import com.android.systemui.controls.dagger.StartControlsStartableModule
 import com.android.systemui.dagger.qualifiers.PerUser
 import com.android.systemui.dreams.AssistantAttentionMonitor
 import com.android.systemui.dreams.DreamMonitor
+import com.android.systemui.dreams.DreamOverlayRegistrant
 import com.android.systemui.dreams.homecontrols.system.HomeControlsDreamStartable
 import com.android.systemui.globalactions.GlobalActionsComponent
 import com.android.systemui.haptics.msdl.MSDLCoreStartable
@@ -51,7 +54,7 @@
 import com.android.systemui.statusbar.ImmersiveModeConfirmation
 import com.android.systemui.statusbar.gesture.GesturePointerEventListener
 import com.android.systemui.statusbar.notification.InstantAppNotifier
-import com.android.systemui.statusbar.phone.StatusBarHeadsUpChangeListener
+import com.android.systemui.statusbar.notification.headsup.StatusBarHeadsUpChangeListener
 import com.android.systemui.statusbar.policy.BatteryControllerStartable
 import com.android.systemui.stylus.StylusUsiPowerStartable
 import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
@@ -328,4 +331,26 @@
     @IntoMap
     @ClassKey(MSDLCoreStartable::class)
     abstract fun bindMSDLCoreStartable(impl: MSDLCoreStartable): CoreStartable
+
+    /** Inject into DreamOverlay. */
+    @Binds
+    @IntoMap
+    @ClassKey(DreamOverlayRegistrant::class)
+    abstract fun bindDreamOverlayRegistrant(
+        dreamOverlayRegistrant: DreamOverlayRegistrant
+    ): CoreStartable
+
+    /** Inject into DreamClockTimeComplication.Registrant */
+    @Binds
+    @IntoMap
+    @ClassKey(DreamClockTimeComplication.Registrant::class)
+    abstract fun bindDreamClockTimeComplicationRegistrant(
+        registrant: DreamClockTimeComplication.Registrant
+    ): CoreStartable
+
+    /** Inject into ComplicationTypesUpdater. */
+    @Binds
+    @IntoMap
+    @ClassKey(ComplicationTypesUpdater::class)
+    abstract fun bindComplicationTypesUpdater(updater: ComplicationTypesUpdater): CoreStartable
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index b7d3c92..d6f8957 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -32,6 +32,7 @@
 import com.android.systemui.CameraProtectionModule;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.SystemUISecondaryUserService;
+import com.android.systemui.activity.ActivityManagerModule;
 import com.android.systemui.ambient.dagger.AmbientModule;
 import com.android.systemui.appops.dagger.AppOpsModule;
 import com.android.systemui.assist.AssistModule;
@@ -140,7 +141,7 @@
 import com.android.systemui.statusbar.phone.ConfigurationControllerModule;
 import com.android.systemui.statusbar.phone.LetterboxModule;
 import com.android.systemui.statusbar.pipeline.dagger.StatusBarPipelineModule;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.PolicyModule;
 import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController;
@@ -198,6 +199,7 @@
  * may not appreciate that.
  */
 @Module(includes = {
+        ActivityManagerModule.class,
         AmbientModule.class,
         AppOpsModule.class,
         AssistModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index 400d097..2e1096f 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -84,30 +84,53 @@
             )
 
     /**
+     * Emits `true` when the current scene switches to [Scenes.Gone] for the first time after having
+     * been on [Scenes.Lockscreen].
+     *
+     * Different from [isDeviceEntered] such that the current scene must actually go through
+     * [Scenes.Gone] to produce a `true`. [isDeviceEntered] also takes into account the navigation
+     * back stack and will produce a `true` value even when the current scene is still not
+     * [Scenes.Gone] but the bottommost entry of the navigation back stack switched from
+     * [Scenes.Lockscreen] to [Scenes.Gone] while the user is staring at another scene.
+     */
+    val isDeviceEnteredDirectly: StateFlow<Boolean> =
+        sceneInteractor.currentScene
+            .filter { currentScene ->
+                currentScene == Scenes.Gone || currentScene == Scenes.Lockscreen
+            }
+            .mapLatestConflated { scene ->
+                if (scene == Scenes.Gone) {
+                    // Make sure device unlock status is definitely unlocked before we
+                    // consider the device "entered".
+                    deviceUnlockedInteractor.deviceUnlockStatus.first { it.isUnlocked }
+                    true
+                } else {
+                    false
+                }
+            }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = false,
+            )
+
+    /**
      * Whether the device has been entered (i.e. the lockscreen has been dismissed, by any method).
      * This can be `false` when the device is unlocked, e.g. when the user still needs to swipe away
      * the non-secure lockscreen, even though they've already authenticated.
      *
      * Note: This does not imply that the lockscreen is visible or not.
+     *
+     * Different from [isDeviceEnteredDirectly] such that the current scene doesn't actually have to
+     * go through [Scenes.Gone] to produce a `true`. [isDeviceEnteredDirectly] doesn't take the
+     * navigation back stack into account and will only produce a `true` value even when the current
+     * scene is actually [Scenes.Gone].
      */
     val isDeviceEntered: StateFlow<Boolean> =
         combine(
                 // This flow emits true when the currentScene switches to Gone for the first time
                 // after having been on Lockscreen.
-                sceneInteractor.currentScene
-                    .filter { currentScene ->
-                        currentScene == Scenes.Gone || currentScene == Scenes.Lockscreen
-                    }
-                    .mapLatestConflated { scene ->
-                        if (scene == Scenes.Gone) {
-                            // Make sure device unlock status is definitely unlocked before we
-                            // consider the device "entered".
-                            deviceUnlockedInteractor.deviceUnlockStatus.first { it.isUnlocked }
-                            true
-                        } else {
-                            false
-                        }
-                    },
+                isDeviceEnteredDirectly,
                 // This flow emits true only if the bottom of the navigation back stack has been
                 // switched from Lockscreen to Gone. In other words, only if the device was unlocked
                 // while visiting at least one scene "above" the Lockscreen scene.
diff --git a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
index e862525..9b181be 100644
--- a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
@@ -30,6 +30,7 @@
 import com.android.systemui.display.data.repository.FocusedDisplayRepositoryImpl
 import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
 import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractorImpl
+import com.android.systemui.display.domain.interactor.DisplayWindowPropertiesInteractorModule
 import com.android.systemui.display.domain.interactor.RearDisplayStateInteractor
 import com.android.systemui.display.domain.interactor.RearDisplayStateInteractorImpl
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
@@ -41,7 +42,7 @@
 import dagger.multibindings.IntoMap
 
 /** Module binding display related classes. */
-@Module
+@Module(includes = [DisplayWindowPropertiesInteractorModule::class])
 interface DisplayModule {
     @Binds
     fun bindConnectedDisplayInteractor(
diff --git a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
new file mode 100644
index 0000000..22e467b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.display.domain.interactor
+
+import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
+import com.android.systemui.display.shared.model.DisplayWindowProperties
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
+
+/** Provides per display instances of [DisplayWindowProperties]. */
+interface DisplayWindowPropertiesInteractor {
+
+    /**
+     * Returns a [DisplayWindowProperties] instance for a given display id, to be used for the
+     * status bar.
+     *
+     * @throws IllegalArgumentException if no display with the given display id exists.
+     */
+    fun getForStatusBar(displayId: Int): DisplayWindowProperties
+}
+
+@SysUISingleton
+class DisplayWindowPropertiesInteractorImpl
+@Inject
+constructor(private val repo: DisplayWindowPropertiesRepository) :
+    DisplayWindowPropertiesInteractor {
+
+    override fun getForStatusBar(displayId: Int): DisplayWindowProperties {
+        return repo.get(displayId, TYPE_STATUS_BAR)
+    }
+}
+
+@Module
+interface DisplayWindowPropertiesInteractorModule {
+
+    @Binds
+    fun interactor(impl: DisplayWindowPropertiesInteractorImpl): DisplayWindowPropertiesInteractor
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
deleted file mode 100644
index 80e68cf..0000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams;
-
-import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_SERVICE_COMPONENT;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.os.PatternMatcher;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.service.dreams.DreamService;
-import android.service.dreams.IDreamManager;
-import android.util.Log;
-
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.SystemUser;
-import com.android.systemui.shared.condition.Monitor;
-import com.android.systemui.util.condition.ConditionalCoreStartable;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * {@link DreamOverlayRegistrant} is responsible for telling system server that SystemUI should be
- * the designated dream overlay component.
- */
-public class DreamOverlayRegistrant extends ConditionalCoreStartable {
-    private static final String TAG = "DreamOverlayRegistrant";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    private final IDreamManager mDreamManager;
-    private final ComponentName mOverlayServiceComponent;
-    private final Context mContext;
-    private final Resources mResources;
-    private boolean mCurrentRegisteredState = false;
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (DEBUG) {
-                Log.d(TAG, "package changed receiver - onReceive");
-            }
-
-            registerOverlayService();
-        }
-    };
-
-    private void registerOverlayService() {
-        // Check to see if the service has been disabled by the user. In this case, we should not
-        // proceed modifying the enabled setting.
-        final PackageManager packageManager = mContext.getPackageManager();
-        final int enabledState =
-                packageManager.getComponentEnabledSetting(mOverlayServiceComponent);
-
-        // The overlay service is only registered when its component setting is enabled.
-        boolean register = false;
-
-        try {
-            register = packageManager.getServiceInfo(mOverlayServiceComponent,
-                PackageManager.GET_META_DATA).enabled;
-        } catch (NameNotFoundException e) {
-            Log.e(TAG, "could not find dream overlay service");
-        }
-
-        if (mCurrentRegisteredState == register) {
-            return;
-        }
-
-        mCurrentRegisteredState = register;
-
-        try {
-            if (DEBUG) {
-                Log.d(TAG, mCurrentRegisteredState
-                        ? "registering dream overlay service:" + mOverlayServiceComponent
-                        : "clearing dream overlay service");
-            }
-
-            mDreamManager.registerDreamOverlayService(
-                    mCurrentRegisteredState ? mOverlayServiceComponent : null);
-        } catch (RemoteException e) {
-            Log.e(TAG, "could not register dream overlay service:" + e);
-        }
-    }
-
-    @Inject
-    public DreamOverlayRegistrant(Context context, @Main Resources resources,
-            @Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent,
-            @SystemUser Monitor monitor) {
-        super(monitor);
-        mContext = context;
-        mResources = resources;
-        mDreamManager = IDreamManager.Stub.asInterface(
-                ServiceManager.getService(DreamService.DREAM_SERVICE));
-        mOverlayServiceComponent = dreamOverlayServiceComponent;
-    }
-
-    @Override
-    protected void onStart() {
-        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
-        filter.addDataScheme("package");
-        filter.addDataSchemeSpecificPart(mOverlayServiceComponent.getPackageName(),
-                PatternMatcher.PATTERN_LITERAL);
-        // Note that we directly register the receiver here as data schemes are not supported by
-        // BroadcastDispatcher.
-        mContext.registerReceiver(mReceiver, filter);
-
-        registerOverlayService();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt
new file mode 100644
index 0000000..e76fd47
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt
@@ -0,0 +1,201 @@
+/*
+ * 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.dreams
+
+import android.content.BroadcastReceiver
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.PackageManager
+import android.os.PatternMatcher
+import android.os.RemoteException
+import android.service.dreams.IDreamManager
+import android.util.Log
+import com.android.systemui.Flags
+import com.android.systemui.dagger.qualifiers.SystemUser
+import com.android.systemui.dreams.dagger.DreamModule
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.dagger.DreamLog
+import com.android.systemui.shared.condition.Monitor
+import com.android.systemui.util.condition.ConditionalCoreStartable
+import javax.inject.Inject
+import javax.inject.Named
+
+/**
+ * [DreamOverlayRegistrant] is responsible for telling system server that SystemUI should be the
+ * designated dream overlay component.
+ */
+class DreamOverlayRegistrant
+@Inject
+constructor(
+    private val context: Context,
+    @param:Named(DreamModule.DREAM_OVERLAY_SERVICE_COMPONENT)
+    private val overlayServiceComponent: ComponentName,
+    @SystemUser monitor: Monitor,
+    private val packageManager: PackageManager,
+    private val dreamManager: IDreamManager,
+    @DreamLog private val logBuffer: LogBuffer,
+) : ConditionalCoreStartable(monitor) {
+    private var currentRegisteredState = false
+    private val logger: DreamLogger = DreamLogger(logBuffer, TAG)
+
+    private val receiver: BroadcastReceiver =
+        object : BroadcastReceiver() {
+            override fun onReceive(context: Context, intent: Intent) {
+                if (DEBUG) {
+                    Log.d(TAG, "package changed receiver - onReceive")
+                }
+
+                registerOverlayService()
+            }
+        }
+
+    internal val enabledInManifest: Boolean
+        get() {
+            return packageManager
+                .getServiceInfo(
+                    overlayServiceComponent,
+                    PackageManager.GET_META_DATA or PackageManager.MATCH_DISABLED_COMPONENTS,
+                )
+                .enabled
+        }
+
+    internal val enabled: Boolean
+        get() {
+            // Always disabled via setting
+            if (
+                packageManager.getComponentEnabledSetting(overlayServiceComponent) ==
+                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+            ) {
+                return false
+            }
+
+            // If the overlay is available in the manifest, then it is already available
+            if (enabledInManifest) {
+                return true
+            }
+
+            if (
+                Flags.communalHubOnMobile() &&
+                    packageManager.getComponentEnabledSetting(overlayServiceComponent) ==
+                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+            ) {
+                return true
+            }
+
+            return false
+        }
+
+    /**
+     * This method enables the dream overlay at runtime. This method allows expanding the eligible
+     * device pool during development before enabling the component in said devices' manifest.
+     */
+    internal fun enableIfAvailable() {
+        // If the overlay is available in the manifest, then it is already available
+        if (enabledInManifest) {
+            return
+        }
+
+        // Enable for hub on mobile
+        if (Flags.communalHubOnMobile()) {
+            // Not available on TV or auto
+            if (
+                packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
+                    packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) ||
+                    packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)
+            ) {
+                if (DEBUG) {
+                    Log.d(TAG, "unsupported platform")
+                }
+                return
+            }
+
+            // If the component is not in the default enabled state, then don't update
+            if (
+                packageManager.getComponentEnabledSetting(overlayServiceComponent) !=
+                    PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+            ) {
+                return
+            }
+
+            packageManager.setComponentEnabledSetting(
+                overlayServiceComponent,
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                PackageManager.DONT_KILL_APP,
+            )
+        }
+    }
+
+    private fun registerOverlayService() {
+        // The overlay service is only registered when its component setting is enabled.
+        var register = false
+
+        try {
+            Log.d(TAG, "trying to find component:" + overlayServiceComponent)
+            // Check to see if the service has been disabled by the user. In this case, we should
+            // not proceed modifying the enabled setting.
+            register = enabled
+        } catch (e: PackageManager.NameNotFoundException) {
+            Log.e(TAG, "could not find dream overlay service")
+        }
+
+        if (currentRegisteredState == register) {
+            return
+        }
+
+        currentRegisteredState = register
+
+        try {
+            if (DEBUG) {
+                Log.d(
+                    TAG,
+                    if (currentRegisteredState)
+                        "registering dream overlay service:$overlayServiceComponent"
+                    else "clearing dream overlay service",
+                )
+            }
+
+            dreamManager.registerDreamOverlayService(
+                if (currentRegisteredState) overlayServiceComponent else null
+            )
+            logger.logDreamOverlayEnabled(currentRegisteredState)
+        } catch (e: RemoteException) {
+            Log.e(TAG, "could not register dream overlay service:$e")
+        }
+    }
+
+    override fun onStart() {
+        val filter = IntentFilter(Intent.ACTION_PACKAGE_CHANGED)
+        filter.addDataScheme("package")
+        filter.addDataSchemeSpecificPart(
+            overlayServiceComponent.packageName,
+            PatternMatcher.PATTERN_LITERAL,
+        )
+        // Note that we directly register the receiver here as data schemes are not supported by
+        // BroadcastDispatcher.
+        context.registerReceiver(receiver, filter)
+
+        registerOverlayService()
+
+        enableIfAvailable()
+    }
+
+    companion object {
+        private const val TAG = "DreamOverlayRegistrant"
+        private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 408fe83..43b7ced 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -18,6 +18,7 @@
 
 import static android.service.dreams.Flags.dreamWakeRedirect;
 
+import static com.android.systemui.Flags.communalHubOnMobile;
 import static com.android.systemui.Flags.glanceableHubAllowKeyguardWhenDreaming;
 import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_WINDOW_TITLE;
 import static com.android.systemui.dreams.dagger.DreamModule.DREAM_TOUCH_INSET_MANAGER;
@@ -54,12 +55,14 @@
 import com.android.internal.policy.PhoneWindow;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.ambient.touch.TouchHandler;
 import com.android.systemui.ambient.touch.TouchMonitor;
 import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent;
 import com.android.systemui.ambient.touch.scrim.ScrimManager;
 import com.android.systemui.communal.domain.interactor.CommunalInteractor;
 import com.android.systemui.communal.shared.log.CommunalUiEvent;
 import com.android.systemui.communal.shared.model.CommunalScenes;
+import com.android.systemui.communal.shared.model.CommunalTransitionKeys;
 import com.android.systemui.complication.dagger.ComplicationComponent;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
@@ -76,8 +79,8 @@
 import kotlinx.coroutines.Job;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashSet;
+import java.util.List;
 import java.util.concurrent.CancellationException;
 import java.util.function.Consumer;
 
@@ -483,11 +486,16 @@
         final DreamOverlayComponent dreamOverlayComponent = mDreamOverlayComponentFactory.create(
                 mLifecycleOwner, complicationComponent.getComplicationHostViewController(),
                 mTouchInsetManager);
+
+        final ArrayList<TouchHandler> touchHandlers = new ArrayList<>(
+                List.of(dreamComplicationComponent.getHideComplicationTouchHandler()));
+        if (!communalHubOnMobile()) {
+            // Do not add the communal touch handler for glanceable hub v2 since there is no dream
+            // to hub swipe gesture.
+            touchHandlers.add(dreamOverlayComponent.getCommunalTouchHandler());
+        }
         final AmbientTouchComponent ambientTouchComponent = mAmbientTouchComponentFactory.create(
-                mLifecycleOwner,
-                new HashSet<>(Arrays.asList(
-                        dreamComplicationComponent.getHideComplicationTouchHandler(),
-                        dreamOverlayComponent.getCommunalTouchHandler())), TAG);
+                mLifecycleOwner, new HashSet<>(touchHandlers), TAG);
 
         setLifecycleStateLocked(Lifecycle.State.STARTED);
 
@@ -568,7 +576,7 @@
         } else {
             mCommunalInteractor.changeScene(CommunalScenes.Communal,
                     "dream wake requested",
-                    null);
+                    communalHubOnMobile() ? CommunalTransitionKeys.INSTANCE.getSimpleFade() : null);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
index 7015cc9..bd1fda7 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.dreams;
 
-import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_ENABLED;
-
 import android.service.dreams.DreamService;
 
 import androidx.annotation.NonNull;
@@ -46,7 +44,6 @@
 import java.util.stream.Collectors;
 
 import javax.inject.Inject;
-import javax.inject.Named;
 
 /**
  * {@link DreamOverlayStateController} is the source of truth for Dream overlay configurations and
@@ -103,7 +100,6 @@
     }
 
     private final Executor mExecutor;
-    private final boolean mOverlayEnabled;
     private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>();
 
     @Complication.ComplicationType
@@ -123,12 +119,10 @@
     @VisibleForTesting
     @Inject
     public DreamOverlayStateController(@Main Executor executor,
-            @Named(DREAM_OVERLAY_ENABLED) boolean overlayEnabled,
             FeatureFlags featureFlags,
             @DreamLog LogBuffer logBuffer,
             WeakReferenceFactory weakReferenceFactory) {
         mExecutor = executor;
-        mOverlayEnabled = overlayEnabled;
         mLogger = new DreamLogger(logBuffer, TAG);
         mFeatureFlags = featureFlags;
         mWeakReferenceFactory = weakReferenceFactory;
@@ -138,18 +132,12 @@
         } else {
             mSupportedTypes = Complication.COMPLICATION_TYPE_NONE;
         }
-        mLogger.logDreamOverlayEnabled(mOverlayEnabled);
     }
 
     /**
      * Adds a complication to be included on the dream overlay.
      */
     public void addComplication(Complication complication) {
-        if (!mOverlayEnabled) {
-            mLogger.logIgnoreAddComplication("overlay disabled", complication.toString());
-            return;
-        }
-
         mExecutor.execute(() -> {
             if (mComplications.add(complication)) {
                 mLogger.logAddComplication(complication.toString());
@@ -162,11 +150,6 @@
      * Removes a complication from inclusion on the dream overlay.
      */
     public void removeComplication(Complication complication) {
-        if (!mOverlayEnabled) {
-            mLogger.logIgnoreRemoveComplication("overlay disabled", complication.toString());
-            return;
-        }
-
         mExecutor.execute(() -> {
             if (mComplications.remove(complication)) {
                 mLogger.logRemoveComplication(complication.toString());
@@ -264,7 +247,7 @@
      * @return {@code true} if overlay is active, {@code false} otherwise.
      */
     public boolean isOverlayActive() {
-        return mOverlayEnabled && containsState(STATE_DREAM_OVERLAY_ACTIVE);
+        return containsState(STATE_DREAM_OVERLAY_ACTIVE);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
index 5a9e52a..160574fa 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
@@ -19,8 +19,8 @@
 import com.android.compose.animation.scene.Swipe
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
-import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -39,6 +39,7 @@
 class DreamUserActionsViewModel
 @AssistedInject
 constructor(
+    private val communalInteractor: CommunalInteractor,
     private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
     private val shadeInteractor: ShadeInteractor,
 ) : UserActionsViewModel() {
@@ -51,18 +52,18 @@
                 } else {
                     combine(
                         deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked },
+                        communalInteractor.isCommunalAvailable,
                         shadeInteractor.shadeMode,
-                    ) { isDeviceUnlocked, shadeMode ->
+                    ) { isDeviceUnlocked, isCommunalAvailable, shadeMode ->
                         buildList {
-                                add(Swipe.Start to Scenes.Communal)
+                                if (isCommunalAvailable) {
+                                    add(Swipe.Start to Scenes.Communal)
+                                }
 
                                 val bouncerOrGone =
                                     if (isDeviceUnlocked) Scenes.Gone else Scenes.Bouncer
                                 add(Swipe.Up to bouncerOrGone)
 
-                                // "Home" is either Dream, Lockscreen, or Gone.
-                                add(Swipe.End to SceneFamilies.Home)
-
                                 addAll(
                                     when (shadeMode) {
                                         ShadeMode.Single -> singleShadeActions()
diff --git a/packages/SystemUI/src/com/android/systemui/education/ui/view/ContextualEduUiCoordinator.kt b/packages/SystemUI/src/com/android/systemui/education/ui/view/ContextualEduUiCoordinator.kt
index 2a3729b..c49ba80 100644
--- a/packages/SystemUI/src/com/android/systemui/education/ui/view/ContextualEduUiCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/ui/view/ContextualEduUiCoordinator.kt
@@ -27,6 +27,7 @@
 import android.os.UserHandle
 import android.view.accessibility.AccessibilityManager
 import androidx.core.app.NotificationCompat
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -39,7 +40,6 @@
 import com.android.systemui.res.R
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /**
  * A class to show contextual education on UI based on the edu produced from
@@ -107,6 +107,7 @@
     }
 
     private fun showDialog(model: ContextualEduToastViewModel) {
+        dialog?.dismiss()
         dialog = createDialog(model)
         dialog?.show()
     }
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
index 2e79249790..b82aa81 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
+++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
@@ -215,6 +215,21 @@
         return true
     }
 
+    fun onTileLongClick(): Boolean {
+        if (state == State.IDLE) {
+            // This case represents a long-click detected outside of the QSLongPressEffect. This can
+            // be due to accessibility services
+            qsTile?.longClick(expandable)
+            logEvent(
+                qsTile?.tileSpec,
+                state,
+                "long click action triggered from OnLongClickListener",
+            )
+            return true
+        }
+        return false
+    }
+
     /**
      * Get the appropriate state for a click action.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderQuantization.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderQuantization.kt
deleted file mode 100644
index 033d55c..0000000
--- a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderQuantization.kt
+++ /dev/null
@@ -1,26 +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.haptics.slider
-
-interface SliderQuantization {
-    /** What is the step size between discrete steps of the slider */
-    val stepSize: Float
-
-    data class Continuous(override val stepSize: Float = Float.MIN_VALUE) : SliderQuantization
-
-    data class Discrete(override val stepSize: Float) : SliderQuantization
-}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
index 092a25a..7bd09b9 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
@@ -20,6 +20,7 @@
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
+import android.os.Build
 import android.os.UserHandle
 import com.android.systemui.CoreStartable
 import com.android.systemui.broadcast.BroadcastDispatcher
@@ -52,13 +53,13 @@
             receiver =
                 object : BroadcastReceiver() {
                     override fun onReceive(context: Context, intent: Intent) {
-                        applicationContext.startActivityAsUser(
-                            Intent(
-                                applicationContext,
-                                KeyboardTouchpadTutorialActivity::class.java
-                            ),
-                            UserHandle.SYSTEM
-                        )
+                        val activityIntent =
+                            Intent(applicationContext, KeyboardTouchpadTutorialActivity::class.java)
+                        if (Build.IS_DEBUGGABLE) {
+                            // helpful for testing different cases but pointless for public builds
+                            intent.extras?.let { activityIntent.putExtras(it) }
+                        }
+                        applicationContext.startActivityAsUser(activityIntent, UserHandle.SYSTEM)
                     }
                 },
             filter = IntentFilter("com.android.systemui.action.KEYBOARD_TOUCHPAD_TUTORIAL"),
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialMetricsLogger.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialMetricsLogger.kt
index 144c5ead..ae6cbbc 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialMetricsLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialMetricsLogger.kt
@@ -18,8 +18,8 @@
 
 import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_ENTRY_POINT_CONTEXTUAL_EDU
 import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEYBOARD
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD
 import com.android.systemui.shared.system.SysUiStatsLog
 import javax.inject.Inject
 
@@ -37,9 +37,9 @@
 
         val tutorialType =
             when (tutorialTypeExtra) {
-                INTENT_TUTORIAL_TYPE_KEYBOARD ->
+                INTENT_TUTORIAL_SCOPE_KEYBOARD ->
                     SysUiStatsLog.PERIPHERAL_TUTORIAL_LAUNCHED__TUTORIAL_TYPE__KEYBOARD
-                INTENT_TUTORIAL_TYPE_TOUCHPAD ->
+                INTENT_TUTORIAL_SCOPE_TOUCHPAD ->
                     SysUiStatsLog.PERIPHERAL_TUTORIAL_LAUNCHED__TUTORIAL_TYPE__TOUCHPAD
                 else -> SysUiStatsLog.PERIPHERAL_TUTORIAL_LAUNCHED__TUTORIAL_TYPE__BOTH
             }
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt
index 9dae649..3cba70e 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt
@@ -34,10 +34,10 @@
 import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity
 import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_ENTRY_POINT_KEY
 import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_BOTH
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEY
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEYBOARD
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_ALL
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEY
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD
 import com.android.systemui.res.R
 import com.android.systemui.settings.UserTracker
 import javax.inject.Inject
@@ -108,7 +108,7 @@
     private fun createPendingIntent(tutorialType: String): PendingIntent {
         val intent =
             Intent(context, KeyboardTouchpadTutorialActivity::class.java).apply {
-                putExtra(INTENT_TUTORIAL_TYPE_KEY, tutorialType)
+                putExtra(INTENT_TUTORIAL_SCOPE_KEY, tutorialType)
                 putExtra(INTENT_TUTORIAL_ENTRY_POINT_KEY, INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER)
                 flags = Intent.FLAG_ACTIVITY_NEW_TASK
             }
@@ -128,13 +128,13 @@
                 NotificationInfo(
                     context.getString(R.string.launch_keyboard_tutorial_notification_title),
                     context.getString(R.string.launch_keyboard_tutorial_notification_content),
-                    INTENT_TUTORIAL_TYPE_KEYBOARD,
+                    INTENT_TUTORIAL_SCOPE_KEYBOARD,
                 )
             TutorialType.TOUCHPAD ->
                 NotificationInfo(
                     context.getString(R.string.launch_touchpad_tutorial_notification_title),
                     context.getString(R.string.launch_touchpad_tutorial_notification_content),
-                    INTENT_TUTORIAL_TYPE_TOUCHPAD,
+                    INTENT_TUTORIAL_SCOPE_TOUCHPAD,
                 )
             TutorialType.BOTH ->
                 NotificationInfo(
@@ -144,7 +144,7 @@
                     context.getString(
                         R.string.launch_keyboard_touchpad_tutorial_notification_content
                     ),
-                    INTENT_TUTORIAL_TYPE_BOTH,
+                    INTENT_TUTORIAL_SCOPE_ALL,
                 )
             TutorialType.NONE -> null
         }
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 2be619b..abd39cc 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
@@ -23,13 +23,16 @@
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.fadeOut
 import androidx.compose.animation.togetherWith
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.node.Ref
@@ -93,13 +96,19 @@
     animationProperties: LottieDynamicProperties,
 ) {
     val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(educationAnimationId))
+    var isPlaying by remember { mutableStateOf(true) }
     val progress by
-        animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)
+        animateLottieCompositionAsState(
+            composition,
+            iterations = LottieConstants.IterateForever,
+            isPlaying = isPlaying,
+            restartOnPlay = false,
+        )
     LottieAnimation(
         composition = composition,
         progress = { progress },
         dynamicProperties = animationProperties,
-        modifier = Modifier.fillMaxSize(),
+        modifier = Modifier.fillMaxSize().clickable { isPlaying = !isPlaying },
     )
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
index fee08b3..67b307f 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
@@ -56,10 +56,13 @@
 ) : ComponentActivity() {
 
     companion object {
-        const val INTENT_TUTORIAL_TYPE_KEY = "tutorial_type"
-        const val INTENT_TUTORIAL_TYPE_TOUCHPAD = "touchpad"
-        const val INTENT_TUTORIAL_TYPE_KEYBOARD = "keyboard"
-        const val INTENT_TUTORIAL_TYPE_BOTH = "both"
+        const val INTENT_TUTORIAL_SCOPE_KEY = "tutorial_scope"
+        const val INTENT_TUTORIAL_SCOPE_TOUCHPAD = "touchpad"
+        const val INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK = "touchpad_back"
+        const val INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME = "touchpad_home"
+        const val INTENT_TUTORIAL_SCOPE_KEYBOARD = "keyboard"
+        const val INTENT_TUTORIAL_SCOPE_ALL = "all"
+
         const val INTENT_TUTORIAL_ENTRY_POINT_KEY = "entry_point"
         const val INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER = "scheduler"
         const val INTENT_TUTORIAL_ENTRY_POINT_CONTEXTUAL_EDU = "contextual_edu"
@@ -94,7 +97,7 @@
         if (savedInstanceState == null) {
             metricsLogger.logPeripheralTutorialLaunched(
                 intent.getStringExtra(INTENT_TUTORIAL_ENTRY_POINT_KEY),
-                intent.getStringExtra(INTENT_TUTORIAL_TYPE_KEY),
+                intent.getStringExtra(INTENT_TUTORIAL_SCOPE_KEY),
             )
             logger.logOpenTutorial(TutorialContext.KEYBOARD_TOUCHPAD_TUTORIAL)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
index 896bdc0..eeb4b69 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
@@ -22,15 +22,21 @@
 import androidx.lifecycle.SavedStateHandle
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
 import com.android.systemui.inputdevice.tutorial.domain.interactor.ConnectionState
 import com.android.systemui.inputdevice.tutorial.domain.interactor.KeyboardTouchpadConnectionInteractor
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEY
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_ALL
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEY
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME
 import com.android.systemui.inputdevice.tutorial.ui.viewmodel.RequiredHardware.KEYBOARD
 import com.android.systemui.inputdevice.tutorial.ui.viewmodel.RequiredHardware.TOUCHPAD
 import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.ACTION_KEY
 import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.BACK_GESTURE
+import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.HOME_GESTURE
 import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
@@ -42,27 +48,23 @@
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.filterNot
 import kotlinx.coroutines.flow.runningFold
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 class KeyboardTouchpadTutorialViewModel(
     private val gesturesInteractor: Optional<TouchpadGesturesInteractor>,
     private val keyboardTouchpadConnectionInteractor: KeyboardTouchpadConnectionInteractor,
     private val hasTouchpadTutorialScreens: Boolean,
     private val logger: InputDeviceTutorialLogger,
-    handle: SavedStateHandle
+    handle: SavedStateHandle,
 ) : ViewModel(), DefaultLifecycleObserver {
 
-    private fun startingScreen(handle: SavedStateHandle): Screen {
-        val tutorialType: String? = handle[INTENT_TUTORIAL_TYPE_KEY]
-        return if (tutorialType == INTENT_TUTORIAL_TYPE_KEYBOARD) ACTION_KEY else BACK_GESTURE
-    }
-
     private val _screen = MutableStateFlow(startingScreen(handle))
     val screen: Flow<Screen> = _screen.filter { it.canBeShown() }
 
     private val _closeActivity: MutableStateFlow<Boolean> = MutableStateFlow(false)
     val closeActivity: StateFlow<Boolean> = _closeActivity
 
+    private val screenSequence: ScreenSequence = chooseScreenSequence(handle)
+
     private val screensBackStack = ArrayDeque(listOf(_screen.value))
 
     private var connectionState: ConnectionState =
@@ -105,6 +107,33 @@
         }
     }
 
+    private fun startingScreen(handle: SavedStateHandle): Screen {
+        val scope: String? = handle[INTENT_TUTORIAL_SCOPE_KEY]
+        return when (scope) {
+            INTENT_TUTORIAL_SCOPE_KEYBOARD -> ACTION_KEY
+            INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME -> HOME_GESTURE
+            INTENT_TUTORIAL_SCOPE_TOUCHPAD,
+            INTENT_TUTORIAL_SCOPE_ALL,
+            INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK -> BACK_GESTURE
+            else -> {
+                logger.w("Intent didn't specify tutorial scope, starting with default")
+                BACK_GESTURE
+            }
+        }
+    }
+
+    private fun chooseScreenSequence(handle: SavedStateHandle): ScreenSequence {
+        val scope: String? = handle[INTENT_TUTORIAL_SCOPE_KEY]
+        return if (
+            scope == INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME ||
+                scope == INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK
+        ) {
+            SingleScreenOnly
+        } else {
+            AllSupportedScreens
+        }
+    }
+
     override fun onCleared() {
         // this shouldn't be needed as onTutorialInvisible should already clear device state but
         // it'd be really bad if we'd block gestures/shortcuts after leaving tutorial so just to be
@@ -121,13 +150,13 @@
     }
 
     fun onDoneButtonClicked() {
-        var nextScreen = _screen.value.next()
+        var nextScreen = screenSequence.nextScreen(_screen.value)
         while (nextScreen != null) {
             if (requiredHardwarePresent(nextScreen)) {
                 break
             }
             logger.logNextScreenMissingHardware(nextScreen)
-            nextScreen = nextScreen.next()
+            nextScreen = screenSequence.nextScreen(nextScreen)
         }
         if (nextScreen == null) {
             logger.d("Final screen reached, closing tutorial")
@@ -192,33 +221,44 @@
         override fun <T : ViewModel> create(
             key: String,
             modelClass: Class<T>,
-            handle: SavedStateHandle
+            handle: SavedStateHandle,
         ): T =
             KeyboardTouchpadTutorialViewModel(
                 gesturesInteractor,
                 keyboardTouchpadConnected,
                 hasTouchpadTutorialScreens,
                 logger,
-                handle
+                handle,
             )
                 as T
     }
+
+    private interface ScreenSequence {
+        fun nextScreen(current: Screen): Screen?
+    }
+
+    private object AllSupportedScreens : ScreenSequence {
+        override fun nextScreen(current: Screen): Screen? {
+            return when (current) {
+                BACK_GESTURE -> HOME_GESTURE
+                HOME_GESTURE -> ACTION_KEY
+                ACTION_KEY -> null
+            }
+        }
+    }
+
+    private object SingleScreenOnly : ScreenSequence {
+        override fun nextScreen(current: Screen): Screen? = null
+    }
 }
 
 enum class RequiredHardware {
     TOUCHPAD,
-    KEYBOARD
+    KEYBOARD,
 }
 
 enum class Screen(val requiredHardware: RequiredHardware) {
     BACK_GESTURE(requiredHardware = TOUCHPAD),
     HOME_GESTURE(requiredHardware = TOUCHPAD),
-    ACTION_KEY(requiredHardware = KEYBOARD);
-
-    fun next(): Screen? =
-        when (this) {
-            BACK_GESTURE -> HOME_GESTURE
-            HOME_GESTURE -> ACTION_KEY
-            ACTION_KEY -> null
-        }
+    ACTION_KEY(requiredHardware = KEYBOARD),
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shared/model/ShortcutCustomizationRequestResult.kt
similarity index 78%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/SystemUI/src/com/android/systemui/keyboard/shared/model/ShortcutCustomizationRequestResult.kt
index 5a04169..bb563b1 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shared/model/ShortcutCustomizationRequestResult.kt
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.systemui.keyboard.shared.model
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+enum class ShortcutCustomizationRequestResult {
+    SUCCESS,
+    ERROR_RESERVED_COMBINATION,
+    ERROR_OTHER,
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt
index da5590a..321fd57 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt
@@ -19,23 +19,34 @@
 import android.content.Context
 import android.content.Context.INPUT_SERVICE
 import android.hardware.input.InputGestureData
+import android.hardware.input.InputGestureData.Builder
 import android.hardware.input.InputGestureData.KeyTrigger
+import android.hardware.input.InputGestureData.createKeyTrigger
 import android.hardware.input.InputManager
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_ALREADY_EXISTS
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_RESERVED_GESTURE
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS
 import android.hardware.input.InputSettings
 import android.hardware.input.KeyGestureEvent
+import android.hardware.input.KeyGestureEvent.KeyGestureType
+import android.util.Log
+import androidx.annotation.VisibleForTesting
+import androidx.compose.runtime.mutableStateOf
 import com.android.systemui.Flags.shortcutHelperKeyGlyph
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
 import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup
 import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo
 import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
 import com.android.systemui.settings.UserTracker
 import javax.inject.Inject
-import kotlinx.coroutines.CoroutineDispatcher
+import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -52,9 +63,10 @@
     stateRepository: ShortcutHelperStateRepository,
     private val userTracker: UserTracker,
     @Background private val backgroundScope: CoroutineScope,
-    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    @Background private val bgCoroutineContext: CoroutineContext,
     private val shortcutCategoriesUtils: ShortcutCategoriesUtils,
     private val context: Context,
+    private val inputGestureMaps: InputGestureMaps,
 ) : ShortcutCategoriesRepository {
 
     private val userContext: Context
@@ -66,11 +78,12 @@
         get() = userContext.getSystemService(INPUT_SERVICE) as InputManager
 
     private val _selectedKeyCombination = MutableStateFlow<KeyCombination?>(null)
+    private val _shortcutBeingCustomized = mutableStateOf<ShortcutCustomizationRequestInfo?>(null)
 
     private val activeInputDevice =
         stateRepository.state.map {
             if (it is Active) {
-                withContext(backgroundDispatcher) { inputManager.getInputDevice(it.deviceId) }
+                withContext(bgCoroutineContext) { inputManager.getInputDevice(it.deviceId) }
             } else {
                 null
             }
@@ -118,9 +131,7 @@
                     emptyList()
                 } else {
                     val customInputGesturesForUser: List<InputGestureData> =
-                        if (InputSettings.isCustomizableInputGesturesFeatureFlagEnabled()) {
-                            inputManager.getCustomInputGestures(/* filter= */ null)
-                        } else emptyList()
+                        getCustomInputGestures()
                     val sources = toInternalGroupSources(customInputGesturesForUser)
                     val supportedKeyCodes =
                         shortcutCategoriesUtils.fetchSupportedKeyCodes(
@@ -150,6 +161,150 @@
         _selectedKeyCombination.value = keyCombination
     }
 
+    fun onCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo?) {
+        _shortcutBeingCustomized.value = requestInfo
+    }
+
+    @VisibleForTesting
+    fun buildInputGestureDataForShortcutBeingCustomized(): InputGestureData? {
+        try {
+            return Builder()
+                .addKeyGestureTypeFromShortcutLabel()
+                .addTriggerFromSelectedKeyCombination()
+                .build()
+            // TODO(b/379648200) add app launch data after dynamic label/icon mapping implementation
+        } catch (e: IllegalArgumentException) {
+            Log.w(TAG, "could not add custom shortcut: $e")
+            return null
+        }
+    }
+
+    private fun retrieveInputGestureDataForShortcutBeingDeleted(): InputGestureData? {
+        val keyGestureType = getKeyGestureTypeFromShortcutBeingDeletedLabel()
+        return getCustomInputGestures().firstOrNull { it.action.keyGestureType() == keyGestureType }
+    }
+
+    suspend fun confirmAndSetShortcutCurrentlyBeingCustomized():
+        ShortcutCustomizationRequestResult {
+        return withContext(bgCoroutineContext) {
+            val inputGestureData =
+                buildInputGestureDataForShortcutBeingCustomized()
+                    ?: return@withContext ShortcutCustomizationRequestResult.ERROR_OTHER
+
+            return@withContext when (inputManager.addCustomInputGesture(inputGestureData)) {
+                CUSTOM_INPUT_GESTURE_RESULT_SUCCESS -> ShortcutCustomizationRequestResult.SUCCESS
+                CUSTOM_INPUT_GESTURE_RESULT_ERROR_ALREADY_EXISTS ->
+                    ShortcutCustomizationRequestResult.ERROR_RESERVED_COMBINATION
+
+                CUSTOM_INPUT_GESTURE_RESULT_ERROR_RESERVED_GESTURE ->
+                    ShortcutCustomizationRequestResult.ERROR_RESERVED_COMBINATION
+
+                else -> ShortcutCustomizationRequestResult.ERROR_OTHER
+            }
+        }
+    }
+
+    suspend fun deleteShortcutCurrentlyBeingCustomized():
+        ShortcutCustomizationRequestResult {
+        return withContext(bgCoroutineContext) {
+            val inputGestureData =
+                retrieveInputGestureDataForShortcutBeingDeleted()
+                    ?: return@withContext ShortcutCustomizationRequestResult.ERROR_OTHER
+            return@withContext when (
+                val result = inputManager.removeCustomInputGesture(inputGestureData)
+            ) {
+                CUSTOM_INPUT_GESTURE_RESULT_SUCCESS -> ShortcutCustomizationRequestResult.SUCCESS
+                else -> {
+                    Log.w(
+                        TAG,
+                        "Attempted to delete shortcut being customized " +
+                            "${_shortcutBeingCustomized.value} but ran into an error. InputGestureData" +
+                            " = $inputGestureData, error code: $result",
+                    )
+                    ShortcutCustomizationRequestResult.ERROR_OTHER
+                }
+            }
+        }
+    }
+
+    private fun getCustomInputGestures(): List<InputGestureData> {
+        return if (InputSettings.isCustomizableInputGesturesFeatureFlagEnabled()) {
+            inputManager.getCustomInputGestures(/* filter= */ InputGestureData.Filter.KEY)
+        } else emptyList()
+    }
+
+    private fun Builder.addKeyGestureTypeFromShortcutLabel(): Builder {
+        val keyGestureType = getKeyGestureTypeFromShortcutBeingCustomizedLabel()
+
+        if (keyGestureType == null) {
+            Log.w(
+                TAG,
+                "Could not find KeyGestureType for shortcut ${_shortcutBeingCustomized.value}",
+            )
+            return this
+        }
+
+        return setKeyGestureType(keyGestureType)
+    }
+
+    @KeyGestureType
+    private fun getKeyGestureTypeFromShortcutBeingCustomizedLabel(): Int? {
+        val shortcutBeingCustomized =
+            getShortcutBeingCustomized() as? ShortcutCustomizationRequestInfo.Add
+
+        if (shortcutBeingCustomized == null) {
+            Log.w(
+                TAG,
+                "Requested key gesture type from label but shortcut being customized is null",
+            )
+            return null
+        }
+
+        return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label]
+    }
+
+    @KeyGestureType
+    private fun getKeyGestureTypeFromShortcutBeingDeletedLabel(): Int? {
+        val shortcutBeingCustomized =
+            getShortcutBeingCustomized() as? ShortcutCustomizationRequestInfo.Delete
+
+        if (shortcutBeingCustomized == null) {
+            Log.w(
+                TAG,
+                "Requested key gesture type from label but shortcut being customized is null",
+            )
+            return null
+        }
+
+        return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label]
+    }
+
+    private fun Builder.addTriggerFromSelectedKeyCombination(): Builder {
+        val selectedKeyCombination = _selectedKeyCombination.value
+        if (selectedKeyCombination?.keyCode == null) {
+            Log.w(
+                TAG,
+                "User requested to set shortcut but selected key combination is " +
+                    "$selectedKeyCombination",
+            )
+            return this
+        }
+
+        return setTrigger(
+            createKeyTrigger(
+                /* keycode = */ selectedKeyCombination.keyCode,
+                /* modifierState = */ shortcutCategoriesUtils.removeUnsupportedModifiers(
+                    selectedKeyCombination.modifiers
+                ),
+            )
+        )
+    }
+
+    @VisibleForTesting
+    fun getShortcutBeingCustomized(): ShortcutCustomizationRequestInfo? {
+        return _shortcutBeingCustomized.value
+    }
+
     private fun toInternalGroupSources(
         inputGestures: List<InputGestureData>
     ): List<InternalGroupsSource> {
@@ -194,7 +349,7 @@
     private fun fetchGroupLabelByGestureType(
         @KeyGestureEvent.KeyGestureType keyGestureType: Int
     ): String? {
-        InputGestures.gestureToInternalKeyboardShortcutGroupLabelResIdMap[keyGestureType]?.let {
+        inputGestureMaps.gestureToInternalKeyboardShortcutGroupLabelResIdMap[keyGestureType]?.let {
             return context.getString(it)
         } ?: return null
     }
@@ -202,7 +357,7 @@
     private fun fetchShortcutInfoLabelByGestureType(
         @KeyGestureEvent.KeyGestureType keyGestureType: Int
     ): String? {
-        InputGestures.gestureToInternalKeyboardShortcutInfoLabelResIdMap[keyGestureType]?.let {
+        inputGestureMaps.gestureToInternalKeyboardShortcutInfoLabelResIdMap[keyGestureType]?.let {
             return context.getString(it)
         } ?: return null
     }
@@ -210,11 +365,15 @@
     private fun fetchShortcutCategoryTypeByGestureType(
         @KeyGestureEvent.KeyGestureType keyGestureType: Int
     ): ShortcutCategoryType? {
-        return InputGestures.gestureToShortcutCategoryTypeMap[keyGestureType]
+        return inputGestureMaps.gestureToShortcutCategoryTypeMap[keyGestureType]
     }
 
     private data class InternalGroupsSource(
         val groups: List<InternalKeyboardShortcutGroup>,
         val type: ShortcutCategoryType,
     )
+
+    private companion object {
+        private const val TAG = "CustomShortcutCategoriesRepository"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt
rename to packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
index 7bb294d..ecc0761 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyboard.shortcut.data.repository
 
+import android.content.Context
 import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
 import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_BACK
 import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT
@@ -45,8 +46,9 @@
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
 import com.android.systemui.res.R
+import javax.inject.Inject
 
-object InputGestures {
+class InputGestureMaps @Inject constructor(private val context: Context) {
     val gestureToShortcutCategoryTypeMap =
         mapOf(
             // System Category
@@ -174,4 +176,12 @@
             KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING to
                 R.string.keyboard_shortcut_group_applications_sms,
         )
+
+    val shortcutLabelToKeyGestureTypeMap: Map<String, Int>
+        get() =
+            gestureToInternalKeyboardShortcutInfoLabelResIdMap.entries.associateBy({
+                context.getString(it.value)
+            }) {
+                it.key
+            }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
index 3988d1f1..a0897f2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
@@ -47,6 +47,11 @@
     @Background private val backgroundCoroutineContext: CoroutineContext,
     private val inputManager: InputManager,
 ) {
+
+    fun removeUnsupportedModifiers(modifierMask: Int): Int {
+        return SUPPORTED_MODIFIERS.reduce { acc, modifier -> acc or modifier } and modifierMask
+    }
+
     fun fetchShortcutCategory(
         type: ShortcutCategoryType?,
         groups: List<InternalKeyboardShortcutGroup>,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
index 0201f40..5ef869e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
@@ -16,24 +16,34 @@
 
 package com.android.systemui.keyboard.shortcut.data.source
 
+import android.content.Context
 import android.content.res.Resources
 import android.view.KeyEvent.KEYCODE_D
 import android.view.KeyEvent.KEYCODE_DPAD_LEFT
 import android.view.KeyEvent.KEYCODE_DPAD_RIGHT
 import android.view.KeyEvent.KEYCODE_DPAD_UP
+import android.view.KeyEvent.KEYCODE_EQUALS
+import android.view.KeyEvent.KEYCODE_LEFT_BRACKET
+import android.view.KeyEvent.KEYCODE_MINUS
+import android.view.KeyEvent.KEYCODE_RIGHT_BRACKET
 import android.view.KeyEvent.KEYCODE_TAB
 import android.view.KeyEvent.META_ALT_ON
 import android.view.KeyEvent.META_CTRL_ON
 import android.view.KeyEvent.META_META_ON
 import android.view.KeyEvent.META_SHIFT_ON
 import android.view.KeyboardShortcutGroup
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
 import com.android.systemui.res.R
 import com.android.window.flags.Flags.enableMoveToNextDisplayShortcut
+import com.android.window.flags.Flags.enableTaskResizingKeyboardShortcuts
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import javax.inject.Inject
 
-class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) :
+class MultitaskingShortcutsSource
+@Inject
+constructor(@Main private val resources: Resources, @Application private val context: Context) :
     KeyboardShortcutGroupsSource {
 
     override suspend fun shortcutGroups(deviceId: Int) =
@@ -95,6 +105,40 @@
                 }
             )
         }
+        if (
+            DesktopModeStatus.canEnterDesktopMode(context) && enableTaskResizingKeyboardShortcuts()
+        ) {
+            // Snap a freeform window to the left
+            //  - Meta + Left bracket
+            add(
+                shortcutInfo(resources.getString(R.string.system_desktop_mode_snap_left_window)) {
+                    command(META_META_ON, KEYCODE_LEFT_BRACKET)
+                }
+            )
+            // Snap a freeform window to the right
+            //  - Meta + Right bracket
+            add(
+                shortcutInfo(resources.getString(R.string.system_desktop_mode_snap_right_window)) {
+                    command(META_META_ON, KEYCODE_RIGHT_BRACKET)
+                }
+            )
+            // Toggle maximize a freeform window
+            //  - Meta + Equals
+            add(
+                shortcutInfo(
+                    resources.getString(R.string.system_desktop_mode_toggle_maximize_window)
+                ) {
+                    command(META_META_ON, KEYCODE_EQUALS)
+                }
+            )
+            // Minimize a freeform window
+            //  - Meta + Minus
+            add(
+                shortcutInfo(resources.getString(R.string.system_desktop_mode_minimize_window)) {
+                    command(META_META_ON, KEYCODE_MINUS)
+                }
+            )
+        }
     }
 
     private fun recentsShortcuts() =
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
index aad55dc..7743c53 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
@@ -16,9 +16,11 @@
 
 package com.android.systemui.keyboard.shortcut.domain.interactor
 
+import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
 import com.android.systemui.keyboard.shortcut.data.repository.CustomShortcutCategoriesRepository
 import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys
 import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
 import javax.inject.Inject
 
@@ -34,4 +36,18 @@
     fun getDefaultCustomShortcutModifierKey(): ShortcutKey.Icon.ResIdIcon {
         return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.metaModifierIconResId)
     }
+
+    fun onCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo?) {
+        customShortcutRepository.onCustomizationRequested(requestInfo)
+    }
+
+    suspend fun confirmAndSetShortcutCurrentlyBeingCustomized():
+        ShortcutCustomizationRequestResult {
+        return customShortcutRepository.confirmAndSetShortcutCurrentlyBeingCustomized()
+    }
+
+    suspend fun deleteShortcutCurrentlyBeingCustomized():
+        ShortcutCustomizationRequestResult {
+        return customShortcutRepository.deleteShortcutCurrentlyBeingCustomized()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
index 813a1fca..4648053 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
@@ -18,25 +18,31 @@
 
 sealed interface ShortcutCategoryType {
     val isTrusted: Boolean
+    val includeInCustomization: Boolean
 
     data object System : ShortcutCategoryType {
         override val isTrusted: Boolean = true
+        override val includeInCustomization: Boolean = true
     }
 
     data object MultiTasking : ShortcutCategoryType {
         override val isTrusted: Boolean = true
+        override val includeInCustomization: Boolean = true
     }
 
     data object InputMethodEditor : ShortcutCategoryType {
         override val isTrusted: Boolean = false
+        override val includeInCustomization: Boolean = false
     }
 
     data object AppCategories : ShortcutCategoryType {
         override val isTrusted: Boolean = true
+        override val includeInCustomization: Boolean = true
     }
 
     data class CurrentApp(val packageName: String) : ShortcutCategoryType {
         override val isTrusted: Boolean = false
+        override val includeInCustomization: Boolean = false
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCustomizationRequestInfo.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCustomizationRequestInfo.kt
index 203228b..2d3e7f6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCustomizationRequestInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCustomizationRequestInfo.kt
@@ -18,8 +18,14 @@
 
 sealed interface ShortcutCustomizationRequestInfo {
     data class Add(
-        val label: String,
-        val categoryType: ShortcutCategoryType,
-        val subCategoryLabel: String,
+        val label: String = "",
+        val categoryType: ShortcutCategoryType = ShortcutCategoryType.System,
+        val subCategoryLabel: String = "",
+    ) : ShortcutCustomizationRequestInfo
+
+    data class Delete(
+        val label: String = "",
+        val categoryType: ShortcutCategoryType = ShortcutCategoryType.System,
+        val subCategoryLabel: String = "",
     ) : ShortcutCustomizationRequestInfo
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
index e44bfe3..f28618b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
@@ -17,22 +17,28 @@
 package com.android.systemui.keyboard.shortcut.ui
 
 import android.app.Dialog
+import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
-import com.android.systemui.keyboard.shortcut.ui.composable.AssignNewShortcutDialog
+import com.android.systemui.keyboard.shortcut.ui.composable.ShortcutCustomizationDialog
 import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState.AddShortcutDialog
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState.DeleteShortcutDialog
 import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutCustomizationViewModel
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.statusbar.phone.SystemUIDialogFactory
 import com.android.systemui.statusbar.phone.create
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.launch
 
 class ShortcutCustomizationDialogStarter
 @AssistedInject
@@ -46,34 +52,44 @@
 
     override suspend fun onActivated(): Nothing {
         viewModel.shortcutCustomizationUiState.collect { uiState ->
-            if (
-                uiState is ShortcutCustomizationUiState.AddShortcutDialog &&
-                    !uiState.isDialogShowing
-            ) {
-                dialog = createAddShortcutDialog().also { it.show() }
-                viewModel.onAddShortcutDialogShown()
+            val shouldShowAddDialog = uiState is AddShortcutDialog && !uiState.isDialogShowing
+            val shouldShowDeleteDialog = uiState is DeleteShortcutDialog && !uiState.isDialogShowing
+            if (shouldShowDeleteDialog || shouldShowAddDialog) {
+                dialog = createDialog().also { it.show() }
+                viewModel.onDialogShown()
             } else if (uiState is ShortcutCustomizationUiState.Inactive) {
                 dialog?.dismiss()
                 dialog = null
             }
         }
+        awaitCancellation()
     }
 
     fun onShortcutCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo) {
         viewModel.onShortcutCustomizationRequested(requestInfo)
     }
 
-    private fun createAddShortcutDialog(): Dialog {
+    private fun createDialog(): Dialog {
         return dialogFactory.create(dialogDelegate = ShortcutCustomizationDialogDelegate()) { dialog
             ->
-            val uiState by viewModel.shortcutCustomizationUiState.collectAsStateWithLifecycle()
-            AssignNewShortcutDialog(
+            val uiState by
+                viewModel.shortcutCustomizationUiState.collectAsStateWithLifecycle(
+                    initialValue = ShortcutCustomizationUiState.Inactive
+                )
+            val coroutineScope = rememberCoroutineScope()
+            ShortcutCustomizationDialog(
                 uiState = uiState,
                 modifier = Modifier.width(364.dp).wrapContentHeight().padding(vertical = 24.dp),
                 onKeyPress = { viewModel.onKeyPressed(it) },
                 onCancel = { dialog.dismiss() },
+                onConfirmSetShortcut = { coroutineScope.launch { viewModel.onSetShortcut() } },
+                onConfirmDeleteShortcut = { coroutineScope.launch { viewModel.deleteShortcutCurrentlyBeingCustomized() } },
             )
-            dialog.setOnDismissListener { viewModel.onAddShortcutDialogDismissed() }
+            dialog.setOnDismissListener { viewModel.onDialogDismissed() }
+
+            // By default, apps cannot intercept action key. The system always handles it. This
+            // flag is needed to enable customisation dialog window to intercept action key
+            dialog.window?.addPrivateFlags(PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
index 43f0f20..20040c6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
@@ -24,6 +24,7 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.RowScope
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
@@ -39,57 +40,106 @@
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.input.key.KeyEvent
-import androidx.compose.ui.input.key.onPreviewKeyEvent
+import androidx.compose.ui.input.key.onKeyEvent
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
+import com.android.compose.ui.graphics.painter.rememberDrawablePainter
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
 import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
 import com.android.systemui.res.R
 
 @Composable
-fun AssignNewShortcutDialog(
+fun ShortcutCustomizationDialog(
     uiState: ShortcutCustomizationUiState,
     modifier: Modifier = Modifier,
     onKeyPress: (KeyEvent) -> Boolean,
     onCancel: () -> Unit,
+    onConfirmSetShortcut: () -> Unit,
+    onConfirmDeleteShortcut: () -> Unit,
 ) {
-    if (uiState is ShortcutCustomizationUiState.AddShortcutDialog) {
-        Column(modifier = modifier) {
-            Title(
-                uiState.shortcutLabel,
-                modifier = Modifier.padding(horizontal = 24.dp).width(316.dp),
-            )
-            Description(
-                modifier = Modifier.padding(top = 24.dp, start = 24.dp, end = 24.dp).width(316.dp)
-            )
-            PromptShortcutModifier(
-                modifier =
-                    Modifier.padding(top = 24.dp, start = 116.5.dp, end = 116.5.dp)
-                        .width(131.dp)
-                        .height(48.dp),
-                defaultModifierKey = uiState.defaultCustomShortcutModifierKey,
-            )
-            SelectedKeyCombinationContainer(
-                shouldShowErrorMessage = uiState.shouldShowErrorMessage,
-                onKeyPress = onKeyPress,
-            )
-            KeyCombinationAlreadyInUseErrorMessage(uiState.shouldShowErrorMessage)
-            DialogButtons(onCancel, isValidKeyCombination = uiState.isValidKeyCombination)
+    when (uiState) {
+        is ShortcutCustomizationUiState.AddShortcutDialog -> {
+            Column(modifier = modifier) {
+                Title(uiState.shortcutLabel)
+                Description(
+                    text =
+                        stringResource(
+                            id = R.string.shortcut_customize_mode_add_shortcut_description
+                        )
+                )
+                PromptShortcutModifier(
+                    modifier =
+                        Modifier.padding(top = 24.dp, start = 116.5.dp, end = 116.5.dp)
+                            .width(131.dp)
+                            .height(48.dp),
+                    defaultModifierKey = uiState.defaultCustomShortcutModifierKey,
+                )
+                SelectedKeyCombinationContainer(
+                    shouldShowError = uiState.errorMessage.isNotEmpty(),
+                    onKeyPress = onKeyPress,
+                    pressedKeys = uiState.pressedKeys,
+                )
+                ErrorMessageContainer(uiState.errorMessage)
+                DialogButtons(
+                    onCancel,
+                    isConfirmButtonEnabled = uiState.pressedKeys.isNotEmpty(),
+                    onConfirm = onConfirmSetShortcut,
+                    confirmButtonText =
+                        stringResource(
+                            R.string.shortcut_helper_customize_dialog_set_shortcut_button_label
+                        ),
+                )
+            }
+        }
+        is ShortcutCustomizationUiState.DeleteShortcutDialog -> {
+            Column(modifier) {
+                Title(
+                    title =
+                        stringResource(
+                            id = R.string.shortcut_customize_mode_remove_shortcut_dialog_title
+                        )
+                )
+                Description(
+                    text =
+                        stringResource(
+                            id = R.string.shortcut_customize_mode_remove_shortcut_description
+                        )
+                )
+                DialogButtons(
+                    onCancel = onCancel,
+                    onConfirm = onConfirmDeleteShortcut,
+                    confirmButtonText =
+                        stringResource(
+                            R.string.shortcut_helper_customize_dialog_remove_button_label
+                        ),
+                )
+            }
+        }
+        else -> {
+            /* No-Op */
         }
     }
 }
 
 @Composable
-fun DialogButtons(onCancel: () -> Unit, isValidKeyCombination: Boolean) {
+fun DialogButtons(
+    onCancel: () -> Unit,
+    isConfirmButtonEnabled: Boolean = true,
+    onConfirm: () -> Unit,
+    confirmButtonText: String,
+) {
     Row(
         modifier =
             Modifier.padding(top = 24.dp, start = 24.dp, end = 24.dp)
@@ -107,23 +157,22 @@
         )
         Spacer(modifier = Modifier.width(8.dp))
         ShortcutHelperButton(
-            onClick = {},
+            onClick = onConfirm,
             color = MaterialTheme.colorScheme.primary,
             width = 116.dp,
             contentColor = MaterialTheme.colorScheme.onPrimary,
-            text =
-                stringResource(R.string.shortcut_helper_customize_dialog_set_shortcut_button_label),
-            enabled = isValidKeyCombination,
+            text = confirmButtonText,
+            enabled = isConfirmButtonEnabled,
         )
     }
 }
 
 @Composable
-fun KeyCombinationAlreadyInUseErrorMessage(shouldShowErrorMessage: Boolean) {
-    if (shouldShowErrorMessage) {
+fun ErrorMessageContainer(errorMessage: String) {
+    if (errorMessage.isNotEmpty()) {
         Box(modifier = Modifier.padding(horizontal = 16.dp).width(332.dp).height(40.dp)) {
             Text(
-                text = stringResource(R.string.shortcut_helper_customize_dialog_error_message),
+                text = errorMessage,
                 style = MaterialTheme.typography.bodyMedium,
                 fontSize = 14.sp,
                 lineHeight = 20.sp,
@@ -137,17 +186,19 @@
 
 @Composable
 fun SelectedKeyCombinationContainer(
-    keyCombination: String =
-        stringResource(R.string.shortcut_helper_add_shortcut_dialog_placeholder),
-    shouldShowErrorMessage: Boolean,
+    shouldShowError: Boolean,
     onKeyPress: (KeyEvent) -> Boolean,
+    pressedKeys: List<ShortcutKey>,
 ) {
     val interactionSource = remember { MutableInteractionSource() }
     val isFocused by interactionSource.collectIsFocusedAsState()
     val outlineColor =
         if (!isFocused) MaterialTheme.colorScheme.outline
-        else if (shouldShowErrorMessage) MaterialTheme.colorScheme.error
+        else if (shouldShowError) MaterialTheme.colorScheme.error
         else MaterialTheme.colorScheme.primary
+    val focusRequester = remember { FocusRequester() }
+
+    LaunchedEffect(Unit) { focusRequester.requestFocus() }
 
     ClickableShortcutSurface(
         onClick = {},
@@ -157,24 +208,21 @@
             Modifier.padding(all = 16.dp)
                 .sizeIn(minWidth = 332.dp, minHeight = 56.dp)
                 .border(width = 2.dp, color = outlineColor, shape = RoundedCornerShape(50.dp))
-                .onPreviewKeyEvent { onKeyPress(it) },
+                .onKeyEvent { onKeyPress(it) }
+                .focusRequester(focusRequester),
         interactionSource = interactionSource,
     ) {
         Row(
             modifier = Modifier.padding(start = 24.dp, top = 16.dp, end = 16.dp, bottom = 16.dp),
             verticalAlignment = Alignment.CenterVertically,
         ) {
-            Text(
-                text = keyCombination,
-                style = MaterialTheme.typography.headlineSmall,
-                fontSize = 16.sp,
-                lineHeight = 24.sp,
-                fontWeight = FontWeight.W500,
-                color = MaterialTheme.colorScheme.onSurfaceVariant,
-                modifier = Modifier.width(252.dp),
-            )
+            if (pressedKeys.isEmpty()) {
+                PressKeyPrompt()
+            } else {
+                PressedKeysTextContainer(pressedKeys)
+            }
             Spacer(modifier = Modifier.weight(1f))
-            if (shouldShowErrorMessage) {
+            if (shouldShowError) {
                 Icon(
                     imageVector = Icons.Default.ErrorOutline,
                     contentDescription = null,
@@ -187,25 +235,89 @@
 }
 
 @Composable
-private fun Title(title: String, modifier: Modifier = Modifier) {
+private fun RowScope.PressedKeysTextContainer(pressedKeys: List<ShortcutKey>) {
+    pressedKeys.forEachIndexed { keyIndex, key ->
+        if (keyIndex > 0) {
+            ShortcutKeySeparator()
+        }
+        if (key is ShortcutKey.Text) {
+            ShortcutTextKey(key)
+        } else if (key is ShortcutKey.Icon) {
+            ShortcutIconKey(key)
+        }
+    }
+}
+
+@Composable
+private fun ShortcutKeySeparator() {
     Text(
-        text = title,
-        style = MaterialTheme.typography.headlineSmall,
-        fontSize = 24.sp,
-        modifier = modifier.wrapContentSize(Alignment.Center),
-        color = MaterialTheme.colorScheme.onSurface,
-        lineHeight = 32.sp,
+        text = stringResource(id = R.string.shortcut_helper_plus_symbol),
+        style = MaterialTheme.typography.titleSmall,
+        fontSize = 16.sp,
+        lineHeight = 24.sp,
+        color = MaterialTheme.colorScheme.onSurfaceVariant,
     )
 }
 
 @Composable
-private fun Description(modifier: Modifier = Modifier) {
+private fun RowScope.ShortcutIconKey(key: ShortcutKey.Icon) {
+    Icon(
+        painter =
+            when (key) {
+                is ShortcutKey.Icon.ResIdIcon -> painterResource(key.drawableResId)
+                is ShortcutKey.Icon.DrawableIcon -> rememberDrawablePainter(drawable = key.drawable)
+            },
+        contentDescription = null,
+        modifier = Modifier.align(Alignment.CenterVertically).height(24.dp),
+        tint = MaterialTheme.colorScheme.onSurfaceVariant,
+    )
+}
+
+@Composable
+private fun PressKeyPrompt() {
     Text(
-        text = stringResource(id = R.string.shortcut_helper_customize_mode_sub_title),
+        text = stringResource(id = R.string.shortcut_helper_add_shortcut_dialog_placeholder),
+        style = MaterialTheme.typography.titleSmall,
+        fontSize = 16.sp,
+        lineHeight = 24.sp,
+        color = MaterialTheme.colorScheme.onSurfaceVariant,
+    )
+}
+
+@Composable
+private fun ShortcutTextKey(key: ShortcutKey.Text) {
+    Text(
+        text = key.value,
+        style = MaterialTheme.typography.titleSmall,
+        fontSize = 16.sp,
+        lineHeight = 24.sp,
+        color = MaterialTheme.colorScheme.onSurfaceVariant,
+    )
+}
+
+@Composable
+private fun Title(title: String) {
+    Text(
+        text = title,
+        style = MaterialTheme.typography.headlineSmall,
+        fontSize = 24.sp,
+        modifier =
+            Modifier.padding(horizontal = 24.dp).width(316.dp).wrapContentSize(Alignment.Center),
+        color = MaterialTheme.colorScheme.onSurface,
+        lineHeight = 32.sp,
+        fontWeight = FontWeight.W400,
+    )
+}
+
+@Composable
+private fun Description(text: String) {
+    Text(
+        text = text,
         style = MaterialTheme.typography.bodyMedium,
-        fontSize = 14.sp,
-        lineHeight = 20.sp,
-        modifier = modifier.wrapContentSize(Alignment.Center),
+        modifier =
+            Modifier.padding(top = 24.dp, start = 24.dp, end = 24.dp)
+                .width(316.dp)
+                .wrapContentSize(Alignment.Center),
         color = MaterialTheme.colorScheme.onSurfaceVariant,
     )
 }
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 b6b5d17..e3675de 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
@@ -111,7 +111,6 @@
 import androidx.compose.ui.util.fastForEachIndexed
 import com.android.compose.modifiers.thenIf
 import com.android.compose.ui.graphics.painter.rememberDrawablePainter
-import com.android.systemui.keyboard.shortcut.shared.model.Shortcut as ShortcutModel
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
@@ -122,6 +121,7 @@
 import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCategoryUi
 import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
 import com.android.systemui.res.R
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut as ShortcutModel
 import kotlinx.coroutines.delay
 
 @Composable
@@ -461,15 +461,19 @@
             SubCategoryContainerDualPane(
                 searchQuery = searchQuery,
                 subCategory = subcategory,
-                isCustomizing = isCustomizing,
-                onCustomizationRequested = { label, subCategoryLabel ->
-                    onCustomizationRequested(
-                        ShortcutCustomizationRequestInfo.Add(
-                            label = label,
-                            subCategoryLabel = subCategoryLabel,
-                            categoryType = category.type,
-                        )
-                    )
+                isCustomizing = isCustomizing and category.type.includeInCustomization,
+                onCustomizationRequested = { requestInfo ->
+                    when (requestInfo) {
+                        is ShortcutCustomizationRequestInfo.Add ->
+                            onCustomizationRequested(
+                                requestInfo.copy(categoryType = category.type)
+                            )
+
+                        is ShortcutCustomizationRequestInfo.Delete ->
+                            onCustomizationRequested(
+                                requestInfo.copy(categoryType = category.type)
+                            )
+                    }
                 },
             )
             Spacer(modifier = Modifier.height(8.dp))
@@ -500,7 +504,7 @@
     searchQuery: String,
     subCategory: ShortcutSubCategory,
     isCustomizing: Boolean,
-    onCustomizationRequested: (String, String) -> Unit = { _: String, _: String -> },
+    onCustomizationRequested: (ShortcutCustomizationRequestInfo) -> Unit,
 ) {
     Surface(
         modifier = Modifier.fillMaxWidth(),
@@ -522,7 +526,19 @@
                     searchQuery = searchQuery,
                     shortcut = shortcut,
                     isCustomizing = isCustomizing,
-                    onCustomizationRequested = { onCustomizationRequested(it, subCategory.label) },
+                    onCustomizationRequested = { requestInfo ->
+                        when (requestInfo) {
+                            is ShortcutCustomizationRequestInfo.Add ->
+                                onCustomizationRequested(
+                                    requestInfo.copy(subCategoryLabel = subCategory.label)
+                                )
+
+                            is ShortcutCustomizationRequestInfo.Delete ->
+                                onCustomizationRequested(
+                                    requestInfo.copy(subCategoryLabel = subCategory.label)
+                                )
+                        }
+                    },
                 )
             }
         }
@@ -544,7 +560,7 @@
     searchQuery: String,
     shortcut: ShortcutModel,
     isCustomizing: Boolean = false,
-    onCustomizationRequested: (String) -> Unit = {},
+    onCustomizationRequested: (ShortcutCustomizationRequestInfo) -> Unit = {},
 ) {
     val interactionSource = remember { MutableInteractionSource() }
     val isFocused by interactionSource.collectIsFocusedAsState()
@@ -572,7 +588,16 @@
             modifier = Modifier.weight(.666f),
             shortcut = shortcut,
             isCustomizing = isCustomizing,
-            onAddShortcutRequested = { onCustomizationRequested(shortcut.label) },
+            onAddShortcutRequested = {
+                onCustomizationRequested(
+                    ShortcutCustomizationRequestInfo.Add(label = shortcut.label)
+                )
+            },
+            onDeleteShortcutRequested = {
+                onCustomizationRequested(
+                    ShortcutCustomizationRequestInfo.Delete(label = shortcut.label)
+                )
+            },
         )
     }
 }
@@ -761,7 +786,7 @@
     Text(
         modifier = modifier,
         text = textWithHighlightedSearchQuery(shortcut.label, searchQuery),
-        style = MaterialTheme.typography.bodyMedium,
+        style = MaterialTheme.typography.titleSmall,
         color = MaterialTheme.colorScheme.onSurface,
     )
 }
@@ -879,7 +904,7 @@
                 Text(
                     fontSize = 18.sp,
                     color = colors.textColor(selected).value,
-                    style = MaterialTheme.typography.headlineSmall,
+                    style = MaterialTheme.typography.titleSmall,
                     text = label,
                 )
             }
@@ -975,9 +1000,11 @@
     ) {
         Row(verticalAlignment = Alignment.CenterVertically) {
             Text(
-                stringResource(id = R.string.shortcut_helper_keyboard_settings_buttons_label),
+                text =
+                    stringResource(id = R.string.shortcut_helper_keyboard_settings_buttons_label),
                 color = MaterialTheme.colorScheme.onSurfaceVariant,
                 fontSize = 16.sp,
+                style = MaterialTheme.typography.titleSmall,
             )
             Spacer(modifier = Modifier.weight(1f))
             Icon(
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
index e9f2a3b..990257d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
@@ -21,11 +21,13 @@
 sealed interface ShortcutCustomizationUiState {
     data class AddShortcutDialog(
         val shortcutLabel: String,
-        val shouldShowErrorMessage: Boolean,
-        val isValidKeyCombination: Boolean,
+        val errorMessage: String = "",
         val defaultCustomShortcutModifierKey: ShortcutKey.Icon.ResIdIcon,
         val isDialogShowing: Boolean,
+        val pressedKeys: List<ShortcutKey> = emptyList(),
     ) : ShortcutCustomizationUiState
 
+    data class DeleteShortcutDialog(val isDialogShowing: Boolean) : ShortcutCustomizationUiState
+
     data object Inactive : ShortcutCustomizationUiState
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
index e86da5d..b467bb4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
@@ -16,64 +16,170 @@
 
 package com.android.systemui.keyboard.shortcut.ui.viewmodel
 
-import androidx.compose.runtime.mutableStateOf
+import android.content.Context
+import androidx.compose.ui.input.key.Key
 import androidx.compose.ui.input.key.KeyEvent
+import androidx.compose.ui.input.key.KeyEventType
+import androidx.compose.ui.input.key.isMetaPressed
+import androidx.compose.ui.input.key.key
+import androidx.compose.ui.input.key.nativeKeyCode
+import androidx.compose.ui.input.key.type
+import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
 import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutCustomizationInteractor
+import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
 import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState.AddShortcutDialog
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState.DeleteShortcutDialog
+import com.android.systemui.res.R
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.update
 
 class ShortcutCustomizationViewModel
 @AssistedInject
-constructor(private val shortcutCustomizationInteractor: ShortcutCustomizationInteractor) {
-    private val _shortcutBeingCustomized = mutableStateOf<ShortcutCustomizationRequestInfo?>(null)
-
+constructor(
+    private val context: Context,
+    private val shortcutCustomizationInteractor: ShortcutCustomizationInteractor,
+) {
     private val _shortcutCustomizationUiState =
         MutableStateFlow<ShortcutCustomizationUiState>(ShortcutCustomizationUiState.Inactive)
 
-    val shortcutCustomizationUiState = _shortcutCustomizationUiState.asStateFlow()
+    val shortcutCustomizationUiState =
+        shortcutCustomizationInteractor.pressedKeys
+            .map { keys ->
+                // Note that Action Key is excluded as it's already displayed on the UI
+                keys.filter {
+                    it != shortcutCustomizationInteractor.getDefaultCustomShortcutModifierKey()
+                }
+            }
+            .combine(_shortcutCustomizationUiState) { keys, uiState ->
+                if (uiState is AddShortcutDialog) {
+                    uiState.copy(pressedKeys = keys)
+                } else {
+                    uiState
+                }
+            }
 
     fun onShortcutCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo) {
         when (requestInfo) {
             is ShortcutCustomizationRequestInfo.Add -> {
                 _shortcutCustomizationUiState.value =
-                    ShortcutCustomizationUiState.AddShortcutDialog(
+                    AddShortcutDialog(
                         shortcutLabel = requestInfo.label,
-                        shouldShowErrorMessage = false,
-                        isValidKeyCombination = false,
                         defaultCustomShortcutModifierKey =
                             shortcutCustomizationInteractor.getDefaultCustomShortcutModifierKey(),
                         isDialogShowing = false,
+                        pressedKeys = emptyList(),
                     )
-                _shortcutBeingCustomized.value = requestInfo
+                shortcutCustomizationInteractor.onCustomizationRequested(requestInfo)
+            }
+
+            is ShortcutCustomizationRequestInfo.Delete -> {
+                _shortcutCustomizationUiState.value = DeleteShortcutDialog(isDialogShowing = false)
+                shortcutCustomizationInteractor.onCustomizationRequested(requestInfo)
             }
         }
     }
 
-    fun onAddShortcutDialogShown() {
+    fun onDialogShown() {
         _shortcutCustomizationUiState.update { uiState ->
-            (uiState as? ShortcutCustomizationUiState.AddShortcutDialog)?.copy(
-                isDialogShowing = true
-            ) ?: uiState
+            (uiState as? AddShortcutDialog)?.copy(isDialogShowing = true)
+                ?: (uiState as? DeleteShortcutDialog)?.copy(isDialogShowing = true)
+                ?: uiState
         }
     }
 
-    fun onAddShortcutDialogDismissed() {
-        _shortcutBeingCustomized.value = null
+    fun onDialogDismissed() {
         _shortcutCustomizationUiState.value = ShortcutCustomizationUiState.Inactive
+        shortcutCustomizationInteractor.onCustomizationRequested(null)
+        shortcutCustomizationInteractor.updateUserSelectedKeyCombination(null)
     }
 
     fun onKeyPressed(keyEvent: KeyEvent): Boolean {
-        // TODO Not yet implemented b/373638584
+        if ((keyEvent.isMetaPressed && keyEvent.type == KeyEventType.KeyDown)) {
+            updatePressedKeys(keyEvent)
+            return true
+        }
         return false
     }
 
+    suspend fun onSetShortcut() {
+        val result = shortcutCustomizationInteractor.confirmAndSetShortcutCurrentlyBeingCustomized()
+
+        _shortcutCustomizationUiState.update { uiState ->
+            when (result) {
+                ShortcutCustomizationRequestResult.SUCCESS -> ShortcutCustomizationUiState.Inactive
+                ShortcutCustomizationRequestResult.ERROR_RESERVED_COMBINATION -> {
+                    getUiStateWithErrorMessage(
+                        uiState = uiState,
+                        errorMessage =
+                            context.getString(
+                                R.string.shortcut_customizer_key_combination_in_use_error_message
+                            ),
+                    )
+                }
+
+                ShortcutCustomizationRequestResult.ERROR_OTHER ->
+                    getUiStateWithErrorMessage(
+                        uiState = uiState,
+                        errorMessage =
+                            context.getString(R.string.shortcut_customizer_generic_error_message),
+                    )
+            }
+        }
+    }
+
+    suspend fun deleteShortcutCurrentlyBeingCustomized() {
+        val result =
+            shortcutCustomizationInteractor.deleteShortcutCurrentlyBeingCustomized()
+
+        _shortcutCustomizationUiState.update { uiState ->
+            when (result) {
+                ShortcutCustomizationRequestResult.SUCCESS -> ShortcutCustomizationUiState.Inactive
+                else -> uiState
+            }
+        }
+    }
+
+    private fun getUiStateWithErrorMessage(
+        uiState: ShortcutCustomizationUiState,
+        errorMessage: String,
+    ): ShortcutCustomizationUiState {
+        return (uiState as? AddShortcutDialog)?.copy(errorMessage = errorMessage) ?: uiState
+    }
+
+    private fun updatePressedKeys(keyEvent: KeyEvent) {
+        val isModifier = SUPPORTED_MODIFIERS.contains(keyEvent.key)
+        val keyCombination =
+            KeyCombination(
+                modifiers = keyEvent.nativeKeyEvent.modifiers,
+                keyCode = if (!isModifier) keyEvent.key.nativeKeyCode else null,
+            )
+        shortcutCustomizationInteractor.updateUserSelectedKeyCombination(keyCombination)
+    }
+
     @AssistedFactory
     interface Factory {
         fun create(): ShortcutCustomizationViewModel
     }
+
+    companion object {
+        private val SUPPORTED_MODIFIERS =
+            listOf(
+                Key.MetaLeft,
+                Key.MetaRight,
+                Key.CtrlRight,
+                Key.CtrlLeft,
+                Key.AltLeft,
+                Key.AltRight,
+                Key.ShiftLeft,
+                Key.ShiftRight,
+                Key.Function,
+                Key.Symbol,
+            )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 7097c1d..d40fe46 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -81,7 +81,7 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardDismissInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardLockWhileAwakeInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardServiceLockNowInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardStateCallbackInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardWakeDirectlyToGoneInteractor;
 import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier;
@@ -330,8 +330,7 @@
             return new FoldGracePeriodProvider();
         }
     };
-    private final KeyguardLockWhileAwakeInteractor
-            mKeyguardLockWhileAwakeInteractor;
+    private final KeyguardServiceLockNowInteractor mKeyguardServiceLockNowInteractor;
 
     @Inject
     public KeyguardService(
@@ -357,7 +356,7 @@
             KeyguardDismissInteractor keyguardDismissInteractor,
             Lazy<DeviceEntryInteractor> deviceEntryInteractorLazy,
             KeyguardStateCallbackInteractor keyguardStateCallbackInteractor,
-            KeyguardLockWhileAwakeInteractor keyguardLockWhileAwakeInteractor) {
+            KeyguardServiceLockNowInteractor keyguardServiceLockNowInteractor) {
         super();
         mKeyguardViewMediator = keyguardViewMediator;
         mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
@@ -389,7 +388,7 @@
         mKeyguardEnabledInteractor = keyguardEnabledInteractor;
         mKeyguardWakeDirectlyToGoneInteractor = keyguardWakeDirectlyToGoneInteractor;
         mKeyguardDismissInteractor = keyguardDismissInteractor;
-        mKeyguardLockWhileAwakeInteractor = keyguardLockWhileAwakeInteractor;
+        mKeyguardServiceLockNowInteractor = keyguardServiceLockNowInteractor;
     }
 
     @Override
@@ -665,7 +664,7 @@
             if (SceneContainerFlag.isEnabled()) {
                 mDeviceEntryInteractorLazy.get().lockNow();
             } else if (KeyguardWmStateRefactor.isEnabled()) {
-                mKeyguardLockWhileAwakeInteractor.onKeyguardServiceDoKeyguardTimeout(options);
+                mKeyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(options);
             }
 
             mKeyguardViewMediator.doKeyguardTimeout(options);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 01ec4d0..9f13160 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -3943,7 +3943,7 @@
     }
 
     private void notifyDefaultDisplayCallbacks(boolean showing) {
-        if (SceneContainerFlag.isEnabled()) {
+        if (SceneContainerFlag.isEnabled() || KeyguardWmStateRefactor.isEnabled()) {
             return;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
index 80675d3..a45204d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
@@ -28,6 +28,7 @@
     const val CREATE_NOTE = "create_note"
     const val DO_NOT_DISTURB = "do_not_disturb"
     const val FLASHLIGHT = "flashlight"
+    const val GLANCEABLE_HUB = "glanceable_hub"
     const val HOME_CONTROLS = "home"
     const val MUTE = "mute"
     const val QR_CODE_SCANNER = "qr_code_scanner"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
new file mode 100644
index 0000000..8906156
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.quickaffordance
+
+import android.content.Context
+import android.util.Log
+import com.android.systemui.Flags.glanceableHubShortcutButton
+import com.android.systemui.animation.Expandable
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.communal.data.repository.CommunalSceneRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.communal.shared.model.CommunalTransitionKeys
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flow
+
+/** Lockscreen affordance that opens the glanceable hub. */
+@SysUISingleton
+class GlanceableHubQuickAffordanceConfig
+@Inject
+constructor(
+    @Application private val context: Context,
+    private val communalSceneRepository: CommunalSceneRepository,
+    private val communalInteractor: CommunalInteractor,
+    private val sceneInteractor: SceneInteractor,
+) : KeyguardQuickAffordanceConfig {
+
+    private val pickerNameResourceId = R.string.glanceable_hub_lockscreen_affordance_label
+
+    override val key: String = BuiltInKeyguardQuickAffordanceKeys.GLANCEABLE_HUB
+
+    override fun pickerName(): String = context.getString(pickerNameResourceId)
+
+    override val pickerIconResourceId: Int
+        get() = R.drawable.ic_widgets
+
+    override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState>
+        get() = flow {
+            emit(
+                // TODO(b/378113263): Gate on getV2FlagEnabled() when ready.
+                if (!glanceableHubShortcutButton()) {
+                    Log.i(TAG, "Button hidden on lockscreen: flag not enabled.")
+                    KeyguardQuickAffordanceConfig.LockScreenState.Hidden
+                } else if (!communalInteractor.isCommunalEnabled.value) {
+                    Log.i(TAG, "Button hidden on lockscreen: hub not enabled in settings.")
+                    KeyguardQuickAffordanceConfig.LockScreenState.Hidden
+                } else {
+                    KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+                        icon =
+                            Icon.Resource(
+                                pickerIconResourceId,
+                                ContentDescription.Resource(pickerNameResourceId),
+                            )
+                    )
+                }
+            )
+        }
+
+    override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
+        // TODO(b/378113263): Gate on getV2FlagEnabled() when ready.
+        return if (!glanceableHubShortcutButton()) {
+            Log.i(TAG, "Button unavailable in picker: flag not enabled.")
+            KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+        } else if (!communalInteractor.isCommunalEnabled.value) {
+            Log.i(TAG, "Button disabled in picker: hub not enabled in settings.")
+            KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
+                context.getString(R.string.glanceable_hub_lockscreen_affordance_disabled_text)
+            )
+        } else {
+            KeyguardQuickAffordanceConfig.PickerScreenState.Default()
+        }
+    }
+
+    override fun onTriggered(
+        expandable: Expandable?
+    ): KeyguardQuickAffordanceConfig.OnTriggeredResult {
+        if (SceneContainerFlag.isEnabled) {
+            sceneInteractor.changeScene(Scenes.Communal, "lockscreen to communal from shortcut")
+        } else {
+            communalSceneRepository.changeScene(
+                CommunalScenes.Communal,
+                transitionKey = CommunalTransitionKeys.SimpleFade,
+            )
+        }
+        return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
+    }
+
+    companion object {
+        private const val TAG = "GlanceableHubQuickAffordanceConfig"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
index 4556195..8c6fdb9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
@@ -26,7 +26,7 @@
 interface KeyguardDataQuickAffordanceModule {
     @Binds
     fun providerClientFactory(
-        impl: KeyguardQuickAffordanceProviderClientFactoryImpl,
+        impl: KeyguardQuickAffordanceProviderClientFactoryImpl
     ): KeyguardQuickAffordanceProviderClientFactory
 
     companion object {
@@ -36,6 +36,7 @@
             camera: CameraQuickAffordanceConfig,
             doNotDisturb: DoNotDisturbQuickAffordanceConfig,
             flashlight: FlashlightQuickAffordanceConfig,
+            glanceableHub: GlanceableHubQuickAffordanceConfig,
             home: HomeControlsKeyguardQuickAffordanceConfig,
             mute: MuteQuickAffordanceConfig,
             quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
@@ -46,6 +47,7 @@
                 camera,
                 doNotDisturb,
                 flashlight,
+                glanceableHub,
                 home,
                 mute,
                 quickAccessWallet,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index 1e672e2..deef2a6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -21,11 +21,13 @@
 import android.app.DreamManager
 import com.android.app.animation.Interpolators
 import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.Flags.communalHubOnMobile
 import com.android.systemui.Flags.communalSceneKtfRefactor
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
 import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.communal.shared.model.CommunalTransitionKeys
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -48,7 +50,6 @@
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.debounce
 import kotlinx.coroutines.flow.filter
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
@@ -176,6 +177,9 @@
                         communalSceneInteractor.changeScene(
                             newScene = CommunalScenes.Communal,
                             loggingReason = "FromDreamingTransitionInteractor",
+                            transitionKey =
+                                if (communalHubOnMobile()) CommunalTransitionKeys.SimpleFade
+                                else null,
                         )
                     } else {
                         startTransitionTo(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
index 631e44a..42cbd7d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
@@ -16,39 +16,52 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
+import kotlinx.coroutines.withContext
 
 /**
- * Logic around the keyguard being enabled/disabled, per [KeyguardService]. If the keyguard is not
- * enabled, the lockscreen cannot be shown and the device will go from AOD/DOZING directly to GONE.
+ * Logic around the keyguard being enabled, disabled, or suppressed via adb. If the keyguard is
+ * disabled or suppressed, the lockscreen cannot be shown and the device will go from AOD/DOZING
+ * directly to GONE.
  *
  * Keyguard can be disabled by selecting Security: "None" in settings, or by apps that hold
  * permission to do so (such as Phone). Some CTS tests also disable keyguard in onCreate or onStart
  * rather than simply dismissing the keyguard or setting up the device to have Security: None, for
  * reasons unknown.
+ *
+ * Keyguard can be suppressed by calling "adb shell locksettings set-disabled true", which is
+ * frequently done in tests. If keyguard is suppressed, it won't show even if the keyguard is
+ * enabled. If keyguard is not suppressed, then we defer to whether keyguard is enabled or disabled.
  */
 @SysUISingleton
 class KeyguardEnabledInteractor
 @Inject
 constructor(
-    @Application scope: CoroutineScope,
+    @Application val scope: CoroutineScope,
+    @Background val backgroundDispatcher: CoroutineDispatcher,
     val repository: KeyguardRepository,
     val biometricSettingsRepository: BiometricSettingsRepository,
-    keyguardDismissTransitionInteractor: KeyguardDismissTransitionInteractor,
+    private val selectedUserInteractor: SelectedUserInteractor,
+    private val lockPatternUtils: LockPatternUtils,
+    keyguardDismissTransitionInteractor: dagger.Lazy<KeyguardDismissTransitionInteractor>,
     internalTransitionInteractor: InternalKeyguardTransitionInteractor,
 ) {
 
@@ -62,6 +75,10 @@
      * If the keyguard is disabled while we're locked, we will transition to GONE unless we're in
      * lockdown mode. If the keyguard is re-enabled, we'll transition back to LOCKSCREEN if we were
      * locked when it was disabled.
+     *
+     * Even if the keyguard is enabled, it's possible for it to be suppressed temporarily via adb.
+     * If you need to respect that adb command, you will need to use
+     * [isKeyguardEnabledAndNotSuppressed] instead of using this flow.
      */
     val isKeyguardEnabled: StateFlow<Boolean> = repository.isKeyguardEnabled
 
@@ -96,9 +113,9 @@
                         val currentTransitionInfo =
                             internalTransitionInteractor.currentTransitionInfoInternal()
                         if (currentTransitionInfo.to != KeyguardState.GONE && !inLockdown) {
-                            keyguardDismissTransitionInteractor.startDismissKeyguardTransition(
-                                "keyguard disabled"
-                            )
+                            keyguardDismissTransitionInteractor
+                                .get()
+                                .startDismissKeyguardTransition("keyguard disabled")
                         }
                     }
             }
@@ -116,4 +133,37 @@
     fun isShowKeyguardWhenReenabled(): Boolean {
         return repository.isShowKeyguardWhenReenabled()
     }
+
+    /**
+     * Whether the keyguard is enabled, and has not been suppressed via adb.
+     *
+     * There is unfortunately no callback for [isKeyguardSuppressed], which means this can't be a
+     * flow, since it's ambiguous when we would query the latest suppression value.
+     */
+    suspend fun isKeyguardEnabledAndNotSuppressed(): Boolean {
+        return isKeyguardEnabled.value && !isKeyguardSuppressed()
+    }
+
+    /**
+     * Returns whether the lockscreen has been disabled ("suppressed") via "adb shell locksettings
+     * set-disabled". If suppressed, we'll ignore all signals that would typically result in showing
+     * the keyguard, regardless of the value of [isKeyguardEnabled].
+     *
+     * It's extremely confusing to have [isKeyguardEnabled] not be the inverse of "is lockscreen
+     * disabled", so this method intentionally re-terms it as "suppressed".
+     *
+     * Note that if the lockscreen is currently showing when it's suppressed, it will remain visible
+     * until it's unlocked, at which point it will never re-appear until suppression is removed.
+     */
+    suspend fun isKeyguardSuppressed(
+        userId: Int = selectedUserInteractor.getSelectedUserId()
+    ): Boolean {
+        // isLockScreenDisabled returns true whenever keyguard is not enabled, even if the adb
+        // command was not used to disable/suppress the lockscreen. To make these booleans as clear
+        // as possible, only return true if keyguard is suppressed when it otherwise would have
+        // been enabled.
+        return withContext(backgroundDispatcher) {
+            isKeyguardEnabled.value && lockPatternUtils.isLockScreenDisabled(userId)
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractor.kt
index 0ab3e5c..ce84e71 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractor.kt
@@ -16,27 +16,16 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
-import android.os.Bundle
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.merge
 
-/**
- * Emitted when we receive a [KeyguardLockWhileAwakeInteractor.onKeyguardServiceDoKeyguardTimeout]
- * call.
- *
- * Includes a timestamp so it's not conflated by the StateFlow.
- */
-data class KeyguardTimeoutWhileAwakeEvent(val timestamp: Long, val options: Bundle?)
-
 /** The reason we're locking while awake, used for logging. */
 enum class LockWhileAwakeReason(private val logReason: String) {
     LOCKDOWN("Lockdown initiated."),
@@ -71,10 +60,8 @@
 constructor(
     biometricSettingsRepository: BiometricSettingsRepository,
     keyguardEnabledInteractor: KeyguardEnabledInteractor,
+    keyguardServiceLockNowInteractor: KeyguardServiceLockNowInteractor,
 ) {
-    /** Emits whenever a timeout event is received by [KeyguardService]. */
-    private val timeoutEvents: MutableStateFlow<KeyguardTimeoutWhileAwakeEvent?> =
-        MutableStateFlow(null)
 
     /** Emits whenever the current user is in lockdown mode. */
     private val inLockdown: Flow<LockWhileAwakeReason> =
@@ -97,25 +84,19 @@
     /** Emits whenever we should lock while the screen is on, for any reason. */
     val lockWhileAwakeEvents: Flow<LockWhileAwakeReason> =
         merge(
-            inLockdown,
-            keyguardReenabled,
-            timeoutEvents.filterNotNull().map {
-                LockWhileAwakeReason.KEYGUARD_TIMEOUT_WHILE_SCREEN_ON
-            },
+            // We're in lockdown, and the keyguard is enabled. If the keyguard is disabled, the
+            // lockdown button is hidden in the UI, but it's still possible to trigger lockdown in
+            // tests.
+            inLockdown
+                .filter { keyguardEnabledInteractor.isKeyguardEnabledAndNotSuppressed() }
+                .map { LockWhileAwakeReason.LOCKDOWN },
+            // The keyguard was re-enabled, and it was showing when it was originally disabled.
+            // Tests currently expect that if the keyguard is re-enabled, it will show even if it's
+            // suppressed, so we don't check for isKeyguardEnabledAndNotSuppressed() on this flow.
+            keyguardReenabled.map { LockWhileAwakeReason.KEYGUARD_REENABLED },
+            // KeyguardService says we need to lock now, and the lockscreen is enabled.
+            keyguardServiceLockNowInteractor.lockNowEvents
+                .filter { keyguardEnabledInteractor.isKeyguardEnabledAndNotSuppressed() }
+                .map { LockWhileAwakeReason.KEYGUARD_TIMEOUT_WHILE_SCREEN_ON },
         )
-
-    /**
-     * Called by [KeyguardService] when it receives a doKeyguardTimeout() call. This indicates that
-     * the device locked while the screen was on.
-     *
-     * [options] appears to be no longer used, but we'll keep it in this interactor in case that
-     * turns out not to be true.
-     */
-    fun onKeyguardServiceDoKeyguardTimeout(options: Bundle?) {
-        timeoutEvents.value =
-            KeyguardTimeoutWhileAwakeEvent(
-                timestamp = System.currentTimeMillis(),
-                options = options,
-            )
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceLockNowInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceLockNowInteractor.kt
new file mode 100644
index 0000000..9ed53ea
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceLockNowInteractor.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.domain.interactor
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.launch
+
+/**
+ * Emitted when we receive a [KeyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout]
+ * call.
+ */
+data class KeyguardLockNowEvent(val options: Bundle?)
+
+/**
+ * Logic around requests by [KeyguardService] to lock the device right now, even though the device
+ * is awake and not going to sleep.
+ *
+ * This can happen if WM#lockNow() is called, or if the screen is forced to stay awake but the lock
+ * timeout elapses.
+ *
+ * This is not the only way for the device to lock while the screen is on. The other cases, which do
+ * not directly involve [KeyguardService], are handled in [KeyguardLockWhileAwakeInteractor].
+ */
+@SysUISingleton
+class KeyguardServiceLockNowInteractor
+@Inject
+constructor(@Background val backgroundScope: CoroutineScope) {
+
+    /**
+     * Emits whenever [KeyguardService] receives a call that indicates we should lock the device
+     * right now, even though the device is awake and not going to sleep.
+     *
+     * WARNING: This is only one of multiple reasons the device might need to lock while not going
+     * to sleep. Unless you're dealing with keyguard internals that specifically need to know that
+     * we're locking due to a call to doKeyguardTimeout, use
+     * [KeyguardLockWhileAwakeInteractor.lockWhileAwakeEvents].
+     *
+     * This is fundamentally an event flow, hence the SharedFlow.
+     */
+    @SuppressLint("SharedFlowCreation")
+    val lockNowEvents: MutableSharedFlow<KeyguardLockNowEvent> = MutableSharedFlow()
+
+    /**
+     * Called by [KeyguardService] when it receives a doKeyguardTimeout() call. This indicates that
+     * the device locked while the screen was on.
+     *
+     * [options] appears to be no longer used, but we'll keep it in this interactor in case that
+     * turns out not to be true.
+     */
+    fun onKeyguardServiceDoKeyguardTimeout(options: Bundle?) {
+        backgroundScope.launch { lockNowEvents.emit(KeyguardLockNowEvent(options = options)) }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt
index fbc7e2a..8641dfa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt
@@ -25,6 +25,7 @@
 import android.content.IntentFilter
 import android.provider.Settings
 import android.provider.Settings.Secure
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -48,20 +49,21 @@
 import kotlin.math.max
 import kotlin.math.min
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.distinctUntilChangedBy
 import kotlinx.coroutines.flow.map
-import com.android.app.tracing.coroutines.launchTraced as launch
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onStart
 
 /**
  * Logic related to the ability to wake directly to GONE from asleep (AOD/DOZING), without going
  * through LOCKSCREEN or a BOUNCER state.
  *
  * This is possible in the following scenarios:
- * - The lockscreen is disabled, either from an app request (SUW does this), or by the security
+ * - The keyguard is not enabled, either from an app request (SUW does this), or by the security
  *   "None" setting.
+ * - The keyguard was suppressed via adb.
  * - A biometric authentication event occurred while we were asleep (fingerprint auth, etc). This
  *   specifically is referred to throughout the codebase as "wake and unlock".
  * - The screen timed out, but the "lock after screen timeout" duration has not elapsed.
@@ -86,43 +88,44 @@
     private val lockPatternUtils: LockPatternUtils,
     private val systemSettings: SystemSettings,
     private val selectedUserInteractor: SelectedUserInteractor,
+    keyguardEnabledInteractor: KeyguardEnabledInteractor,
+    keyguardServiceLockNowInteractor: KeyguardServiceLockNowInteractor,
 ) {
 
     /**
-     * Whether the lockscreen was disabled as of the last wake/sleep event, according to
-     * LockPatternUtils.
-     *
-     * This will always be true if [repository.isKeyguardServiceEnabled]=false, but it can also be
-     * true when the keyguard service is enabled if the lockscreen has been disabled via adb using
-     * the `adb shell locksettings set-disabled true` command, which is often done in tests.
-     *
-     * Unlike keyguardServiceEnabled, changes to this value should *not* immediately show or hide
-     * the keyguard. If the lockscreen is disabled in this way, it will just not show on the next
-     * sleep/wake.
+     * Whether the keyguard was suppressed as of the most recent wakefulness event or lockNow
+     * command. Keyguard suppression can only be queried (there is no callback available), and
+     * legacy code only queried the value in onStartedGoingToSleep and doKeyguardTimeout. Tests now
+     * depend on that behavior, so for now, we'll replicate it here.
      */
-    private val isLockscreenDisabled: Flow<Boolean> =
-        powerInteractor.isAwake.map { isLockscreenDisabled() }
+    private val shouldSuppressKeyguard =
+        merge(powerInteractor.isAwake, keyguardServiceLockNowInteractor.lockNowEvents)
+            .map { keyguardEnabledInteractor.isKeyguardSuppressed() }
+            // Default to false, so that flows that combine this one emit prior to the first
+            // wakefulness emission.
+            .onStart { emit(false) }
 
     /**
      * Whether we can wake from AOD/DOZING directly to GONE, bypassing LOCKSCREEN/BOUNCER states.
      *
      * This is possible in the following cases:
      * - Keyguard is disabled, either from an app request or from security being set to "None".
+     * - Keyguard is suppressed, via adb locksettings.
      * - We're wake and unlocking (fingerprint auth occurred while asleep).
      * - We're allowed to ignore auth and return to GONE, due to timeouts not elapsing.
      */
     val canWakeDirectlyToGone =
         combine(
                 repository.isKeyguardEnabled,
-                isLockscreenDisabled,
+                shouldSuppressKeyguard,
                 repository.biometricUnlockState,
                 repository.canIgnoreAuthAndReturnToGone,
             ) {
                 keyguardEnabled,
-                isLockscreenDisabled,
+                shouldSuppressKeyguard,
                 biometricUnlockState,
                 canIgnoreAuthAndReturnToGone ->
-                (!keyguardEnabled || isLockscreenDisabled) ||
+                (!keyguardEnabled || shouldSuppressKeyguard) ||
                     BiometricUnlockMode.isWakeAndUnlock(biometricUnlockState.mode) ||
                     canIgnoreAuthAndReturnToGone
             }
@@ -186,9 +189,9 @@
                 .sample(
                     transitionInteractor.isCurrentlyIn(
                         Scenes.Gone,
-                        stateWithoutSceneContainer = KeyguardState.GONE
+                        stateWithoutSceneContainer = KeyguardState.GONE,
                     ),
-                    ::Pair
+                    ::Pair,
                 )
                 .collect { (wakefulness, finishedInGone) ->
                     // Save isAwake for use in onDreamingStarted/onDreamingStopped.
@@ -260,7 +263,7 @@
             delayedActionFilter,
             SYSTEMUI_PERMISSION,
             null /* scheduler */,
-            Context.RECEIVER_EXPORTED_UNAUDITED
+            Context.RECEIVER_EXPORTED_UNAUDITED,
         )
     }
 
@@ -282,7 +285,7 @@
                 context,
                 0,
                 intent,
-                PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
+                PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE,
             )
 
         val time = systemClock.elapsedRealtime() + getCanIgnoreAuthAndReturnToGoneDuration()
@@ -311,16 +314,6 @@
     }
 
     /**
-     * Returns whether the lockscreen is disabled, either because the keyguard service is disabled
-     * or because an adb command has disabled the lockscreen.
-     */
-    private fun isLockscreenDisabled(
-        userId: Int = selectedUserInteractor.getSelectedUserId()
-    ): Boolean {
-        return lockPatternUtils.isLockScreenDisabled(userId)
-    }
-
-    /**
      * Returns the duration within which we can return to GONE without auth after a screen timeout
      * (or power button press, if lock instantly is disabled).
      *
@@ -336,7 +329,7 @@
                 .getIntForUser(
                     Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
                     KEYGUARD_CAN_IGNORE_AUTH_DURATION,
-                    userId
+                    userId,
                 )
                 .toLong()
 
@@ -352,7 +345,7 @@
                     .getIntForUser(
                         Settings.System.SCREEN_OFF_TIMEOUT,
                         KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT,
-                        userId
+                        userId,
                     )
                     .toLong()
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index f473a82..9df293b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -112,8 +112,10 @@
             }
             .distinctUntilChanged()
 
-    private val isDeviceEntered by lazy { deviceEntryInteractor.get().isDeviceEntered }
-    private val isDeviceNotEntered by lazy { isDeviceEntered.map { !it } }
+    private val isDeviceEnteredDirectly by lazy {
+        deviceEntryInteractor.get().isDeviceEnteredDirectly
+    }
+    private val isDeviceNotEnteredDirectly by lazy { isDeviceEnteredDirectly.map { !it } }
 
     /**
      * Surface visibility, which is either determined by the default visibility when not
@@ -126,7 +128,7 @@
                 sceneInteractor.get().transitionState.flatMapLatestConflated { state ->
                     when {
                         state.isTransitioning(from = Scenes.Lockscreen, to = Scenes.Gone) ->
-                            isDeviceEntered
+                            isDeviceEnteredDirectly
                         state.isTransitioning(from = Scenes.Bouncer, to = Scenes.Gone) ->
                             (state as Transition).progress.map { progress ->
                                 progress >
@@ -202,30 +204,6 @@
                 .distinctUntilChanged()
         }
 
-    /**
-     * Scenes that are part of the keyguard and are shown when the device is locked or when the
-     * keyguard still needs to be dismissed.
-     */
-    private val keyguardScenes = setOf(Scenes.Lockscreen, Scenes.Bouncer, Scenes.Communal)
-
-    /**
-     * Scenes that don't belong in the keyguard family and cannot show when the device is locked or
-     * when the keyguard still needs to be dismissed.
-     */
-    private val nonKeyguardScenes = setOf(Scenes.Gone)
-
-    /**
-     * Scenes that can show regardless of device lock or keyguard dismissal states. Other sources of
-     * state need to be consulted to know whether the device has been entered or not.
-     */
-    private val keyguardAgnosticScenes =
-        setOf(
-            Scenes.Shade,
-            Scenes.QuickSettings,
-            Overlays.NotificationsShade,
-            Overlays.QuickSettingsShade,
-        )
-
     private val lockscreenVisibilityWithScenes =
         combine(
                 sceneInteractor.get().transitionState.flatMapLatestConflated {
@@ -234,7 +212,7 @@
                             when (it.currentScene) {
                                 in keyguardScenes -> flowOf(true)
                                 in nonKeyguardScenes -> flowOf(false)
-                                in keyguardAgnosticScenes -> isDeviceNotEntered
+                                in keyguardAgnosticScenes -> isDeviceNotEnteredDirectly
                                 else ->
                                     throw IllegalStateException("Unknown scene: ${it.currentScene}")
                             }
@@ -244,7 +222,7 @@
                                 it.isTransitioningSets(from = keyguardScenes) -> flowOf(true)
                                 it.isTransitioningSets(from = nonKeyguardScenes) -> flowOf(false)
                                 it.isTransitioningSets(from = keyguardAgnosticScenes) ->
-                                    isDeviceNotEntered
+                                    isDeviceNotEnteredDirectly
                                 else ->
                                     throw IllegalStateException("Unknown scene: ${it.fromContent}")
                             }
@@ -355,4 +333,30 @@
                     !BiometricUnlockMode.isWakeAndUnlock(biometricUnlockState.mode)
             }
             .distinctUntilChanged()
+
+    companion object {
+        /**
+         * Scenes that are part of the keyguard and are shown when the device is locked or when the
+         * keyguard still needs to be dismissed.
+         */
+        val keyguardScenes = setOf(Scenes.Lockscreen, Scenes.Bouncer, Scenes.Communal, Scenes.Dream)
+
+        /**
+         * Scenes that don't belong in the keyguard family and cannot show when the device is locked
+         * or when the keyguard still needs to be dismissed.
+         */
+        private val nonKeyguardScenes = setOf(Scenes.Gone)
+
+        /**
+         * Scenes that can show regardless of device lock or keyguard dismissal states. Other
+         * sources of state need to be consulted to know whether the device has been entered or not.
+         */
+        private val keyguardAgnosticScenes =
+            setOf(
+                Scenes.Shade,
+                Scenes.QuickSettings,
+                Overlays.NotificationsShade,
+                Overlays.QuickSettingsShade,
+            )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
index 6c03b24..ac302dd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
@@ -17,7 +17,7 @@
 
 package com.android.systemui.keyguard.ui.binder
 
-import android.content.Context
+import android.content.res.Resources
 import android.view.View
 import android.view.View.INVISIBLE
 import android.view.View.VISIBLE
@@ -34,8 +34,8 @@
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
 import com.android.systemui.shared.clocks.ClockRegistry
-import kotlin.reflect.KSuspendFunction1
 
 /** Binder for the small clock view, large clock view. */
 object KeyguardPreviewClockViewBinder {
@@ -66,11 +66,11 @@
 
     @JvmStatic
     fun bind(
-        context: Context,
         rootView: ConstraintLayout,
         viewModel: KeyguardPreviewClockViewModel,
         clockRegistry: ClockRegistry,
-        updateClockAppearance: KSuspendFunction1<ClockController, Unit>,
+        updateClockAppearance: suspend (ClockController, Resources) -> Unit,
+        clockPreviewConfig: ClockPreviewConfig,
     ) {
         rootView.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
@@ -82,7 +82,10 @@
                                     .forEach { rootView.removeView(it) }
                             }
                             lastClock = currentClock
-                            updateClockAppearance(currentClock)
+                            updateClockAppearance(
+                                currentClock,
+                                clockPreviewConfig.previewContext.resources,
+                            )
 
                             if (viewModel.shouldHighlightSelectedAffordance) {
                                 (currentClock.largeClock.layout.views +
@@ -98,7 +101,12 @@
                                 (it.parent as? ViewGroup)?.removeView(it)
                                 rootView.addView(it)
                             }
-                            applyPreviewConstraints(context, rootView, currentClock, viewModel)
+                            applyPreviewConstraints(
+                                clockPreviewConfig,
+                                rootView,
+                                currentClock,
+                                viewModel,
+                            )
                         }
                     }
                     .invokeOnCompletion {
@@ -121,14 +129,14 @@
     }
 
     private fun applyPreviewConstraints(
-        context: Context,
+        clockPreviewConfig: ClockPreviewConfig,
         rootView: ConstraintLayout,
         previewClock: ClockController,
         viewModel: KeyguardPreviewClockViewModel,
     ) {
         val cs = ConstraintSet().apply { clone(rootView) }
-        previewClock.largeClock.layout.applyPreviewConstraints(context, cs)
-        previewClock.smallClock.layout.applyPreviewConstraints(context, cs)
+        previewClock.largeClock.layout.applyPreviewConstraints(clockPreviewConfig, cs)
+        previewClock.smallClock.layout.applyPreviewConstraints(clockPreviewConfig, cs)
 
         // When selectedClockSize is the initial value, make both clocks invisible to avoid
         // flickering
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
index baa6812..e89be5d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
@@ -17,7 +17,6 @@
 
 package com.android.systemui.keyguard.ui.binder
 
-import android.content.Context
 import android.view.View
 import androidx.core.view.isInvisible
 import androidx.lifecycle.Lifecycle
@@ -26,16 +25,16 @@
 import com.android.systemui.keyguard.shared.model.ClockSizeSetting
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewSmartspaceViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
 
 /** Binder for the small clock view, large clock view and smartspace. */
 object KeyguardPreviewSmartspaceViewBinder {
 
     @JvmStatic
     fun bind(
-        previewContext: Context,
         smartspace: View,
-        splitShadePreview: Boolean,
         viewModel: KeyguardPreviewSmartspaceViewModel,
+        clockPreviewConfig: ClockPreviewConfig,
     ) {
         smartspace.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
@@ -44,15 +43,9 @@
                         val topPadding =
                             when (it) {
                                 ClockSizeSetting.DYNAMIC ->
-                                    viewModel.getLargeClockSmartspaceTopPadding(
-                                        splitShadePreview,
-                                        previewContext,
-                                    )
+                                    viewModel.getLargeClockSmartspaceTopPadding(clockPreviewConfig)
                                 ClockSizeSetting.SMALL ->
-                                    viewModel.getSmallClockSmartspaceTopPadding(
-                                        splitShadePreview,
-                                        previewContext,
-                                    )
+                                    viewModel.getSmallClockSmartspaceTopPadding(clockPreviewConfig)
                             }
                         smartspace.setTopPadding(topPadding)
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index ab9cffc..9924a3b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -22,6 +22,7 @@
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
+import android.content.res.Resources
 import android.graphics.Rect
 import android.hardware.display.DisplayManager
 import android.os.Bundle
@@ -47,6 +48,7 @@
 import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.TOP
 import androidx.core.view.isInvisible
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.policy.SystemBarUtils
 import com.android.keyguard.ClockEventController
 import com.android.keyguard.KeyguardClockSwitch
@@ -57,6 +59,7 @@
 import com.android.systemui.communal.ui.binder.CommunalTutorialIndicatorViewBinder
 import com.android.systemui.communal.ui.viewmodel.CommunalTutorialIndicatorViewModel
 import com.android.systemui.coroutines.newTracingContext
+import com.android.systemui.customization.R as customR
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -80,9 +83,11 @@
 import com.android.systemui.monet.ColorScheme
 import com.android.systemui.monet.Style
 import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
 import com.android.systemui.plugins.clocks.ThemeConfig
 import com.android.systemui.plugins.clocks.WeatherData
 import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shared.clocks.ClockRegistry
 import com.android.systemui.shared.clocks.DefaultClockController
@@ -105,7 +110,6 @@
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.flowOf
-import com.android.app.tracing.coroutines.launchTraced as launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.withContext
 import org.json.JSONException
@@ -352,8 +356,11 @@
 
         val topPadding: Int =
             smartspaceViewModel.getLargeClockSmartspaceTopPadding(
-                previewInSplitShade(),
-                previewContext,
+                ClockPreviewConfig(
+                    previewContext,
+                    getPreviewShadeLayoutWide(display!!),
+                    SceneContainerFlag.isEnabled,
+                )
             )
         val startPadding: Int = smartspaceViewModel.getSmartspaceStartPadding(previewContext)
         val endPadding: Int = smartspaceViewModel.getSmartspaceEndPadding(previewContext)
@@ -436,11 +443,15 @@
             setUpClock(previewContext, rootView)
             if (MigrateClocksToBlueprint.isEnabled) {
                 KeyguardPreviewClockViewBinder.bind(
-                    previewContext,
                     keyguardRootView,
                     clockViewModel,
                     clockRegistry,
                     ::updateClockAppearance,
+                    ClockPreviewConfig(
+                        previewContext,
+                        getPreviewShadeLayoutWide(display!!),
+                        SceneContainerFlag.isEnabled,
+                    ),
                 )
             } else {
                 KeyguardPreviewClockViewBinder.bind(
@@ -455,10 +466,14 @@
 
         smartSpaceView?.let {
             KeyguardPreviewSmartspaceViewBinder.bind(
-                previewContext,
                 it,
-                previewInSplitShade(),
                 smartspaceViewModel,
+                clockPreviewConfig =
+                    ClockPreviewConfig(
+                        previewContext,
+                        getPreviewShadeLayoutWide(display!!),
+                        SceneContainerFlag.isEnabled,
+                    ),
             )
         }
         setupCommunalTutorialIndicator(keyguardRootView)
@@ -552,20 +567,14 @@
             val layoutParams =
                 FrameLayout.LayoutParams(
                     FrameLayout.LayoutParams.WRAP_CONTENT,
-                    resources.getDimensionPixelSize(
-                        com.android.systemui.customization.R.dimen.small_clock_height
-                    ),
+                    resources.getDimensionPixelSize(customR.dimen.small_clock_height),
                 )
             layoutParams.topMargin =
                 SystemBarUtils.getStatusBarHeight(previewContext) +
-                    resources.getDimensionPixelSize(
-                        com.android.systemui.customization.R.dimen.small_clock_padding_top
-                    )
+                    resources.getDimensionPixelSize(customR.dimen.small_clock_padding_top)
             smallClockHostView.layoutParams = layoutParams
             smallClockHostView.setPaddingRelative(
-                /* start = */ resources.getDimensionPixelSize(
-                    com.android.systemui.customization.R.dimen.clock_padding_start
-                ),
+                /* start = */ resources.getDimensionPixelSize(customR.dimen.clock_padding_start),
                 /* top = */ 0,
                 /* end = */ 0,
                 /* bottom = */ 0,
@@ -637,7 +646,7 @@
         onClockChanged()
     }
 
-    private suspend fun updateClockAppearance(clock: ClockController) {
+    private suspend fun updateClockAppearance(clock: ClockController, resources: Resources) {
         if (!MigrateClocksToBlueprint.isEnabled) {
             clockController.clock = clock
         }
@@ -667,6 +676,11 @@
         if (MigrateClocksToBlueprint.isEnabled) {
             clockController.clock = clock
         }
+        // When set clock to clockController,it will reset fontsize based on context.resources
+        // We need to override it with overlaid resources
+        clock.largeClock.events.onFontSettingChanged(
+            resources.getDimensionPixelSize(customR.dimen.large_clock_text_size).toFloat()
+        )
     }
 
     private fun onClockChanged() {
@@ -676,7 +690,7 @@
         coroutineScope.launch {
             val clock = clockRegistry.createCurrentClock()
             clockController.clock = clock
-            updateClockAppearance(clock)
+            updateClockAppearance(clock, context.resources)
             updateLargeClock(clock)
             updateSmallClock(clock)
         }
@@ -742,12 +756,14 @@
         smallClockHostView.addView(clock.smallClock.view)
     }
 
-    /*
-     * When multi_crop_preview_ui_flag is on, we can preview portrait in split shadow direction
-     * or vice versa. So we need to decide preview direction by width and height
-     */
-    private fun previewInSplitShade(): Boolean {
-        return width > height
+    private fun getPreviewShadeLayoutWide(display: Display): Boolean {
+        return if (display.displayId == 0) {
+            shadeInteractor.isShadeLayoutWide.value
+        } else {
+            // For the unfolded preview in a folded screen; it's landscape by default
+            // For the folded preview in an unfolded screen; it's portrait by default
+            display.name == "Inner Display"
+        }
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt
index 8622ffc..160380b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt
@@ -19,6 +19,7 @@
 
 import android.content.Context
 import android.view.View
+import android.view.ViewGroup
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
@@ -47,11 +48,15 @@
             visibility = View.GONE
         }
     }
+
     override fun addViews(constraintLayout: ConstraintLayout) {
         if (!MigrateClocksToBlueprint.isEnabled) {
             return
         }
-
+        if (emptyView.parent != null) {
+            // As emptyView is lazy, it might be already attached.
+            (emptyView.parent as? ViewGroup)?.removeView(emptyView)
+        }
         constraintLayout.addView(emptyView)
         burnInLayer =
             AodBurnInLayer(context).apply {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
index 6c98d5b..70bf8bc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
@@ -235,9 +235,7 @@
 
             val smallClockBottom =
                 keyguardClockViewModel.getSmallClockTopMargin() +
-                    context.resources.getDimensionPixelSize(
-                        com.android.systemui.customization.R.dimen.small_clock_height
-                    )
+                    context.resources.getDimensionPixelSize(customR.dimen.small_clock_height)
             val dateWeatherSmartspaceHeight = getDimen(context, DATE_WEATHER_VIEW_HEIGHT).toFloat()
             val marginBetweenSmartspaceAndNotification =
                 context.resources.getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index 3a7a640..6e30e48 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import android.content.Context
 import android.content.res.Resources
 import androidx.annotation.VisibleForTesting
 import androidx.constraintlayout.helper.widget.Layer
@@ -27,7 +28,8 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.shared.model.ClockSize
 import com.android.systemui.keyguard.shared.model.ClockSizeSetting
-import com.android.systemui.res.R
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
+import com.android.systemui.plugins.clocks.DefaultClockFaceLayout.Companion.getSmallClockTopPadding
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -46,6 +48,7 @@
 class KeyguardClockViewModel
 @Inject
 constructor(
+    val context: Context,
     keyguardClockInteractor: KeyguardClockInteractor,
     @Application private val applicationScope: CoroutineScope,
     aodNotificationIconViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
@@ -158,16 +161,15 @@
             )
 
     /** Calculates the top margin for the small clock. */
-    fun getSmallClockTopMargin(): Int {
-        val statusBarHeight = systemBarUtils.getStatusBarHeaderHeightKeyguard()
-        return if (shadeInteractor.isShadeLayoutWide.value) {
-            resources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin) -
-                if (SceneContainerFlag.isEnabled) statusBarHeight else 0
-        } else {
-            resources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) +
-                if (!SceneContainerFlag.isEnabled) statusBarHeight else 0
-        }
-    }
+    fun getSmallClockTopMargin(): Int =
+        getSmallClockTopPadding(
+            ClockPreviewConfig(
+                context,
+                shadeInteractor.isShadeLayoutWide.value,
+                SceneContainerFlag.isEnabled,
+            ),
+            systemBarUtils.getStatusBarHeaderHeightKeyguard(),
+        )
 
     val smallClockTopMargin =
         combine(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
index 65c0f57..1c44982 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
@@ -17,11 +17,12 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.content.Context
-import com.android.internal.policy.SystemBarUtils
 import com.android.systemui.customization.R as customR
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.shared.model.ClockSizeSetting
-import com.android.systemui.res.R
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
+import com.android.systemui.plugins.clocks.DefaultClockFaceLayout.Companion.getSmallClockTopPadding
+import com.android.systemui.statusbar.ui.SystemBarUtilsProxy
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.StateFlow
@@ -35,6 +36,7 @@
     interactor: KeyguardClockInteractor,
     val smartspaceViewModel: KeyguardSmartspaceViewModel,
     val clockViewModel: KeyguardClockViewModel,
+    private val systemBarUtils: SystemBarUtilsProxy,
 ) {
 
     val selectedClockSize: StateFlow<ClockSizeSetting> = interactor.selectedClockSize
@@ -59,29 +61,18 @@
         return KeyguardSmartspaceViewModel.getSmartspaceEndMargin(context)
     }
 
-    fun getSmallClockSmartspaceTopPadding(splitShadePreview: Boolean, context: Context): Int {
-        return getSmallClockTopPadding(splitShadePreview, context) +
-            context.resources.getDimensionPixelSize(
-                com.android.systemui.customization.R.dimen.small_clock_height
-            )
-    }
-
-    fun getLargeClockSmartspaceTopPadding(splitShadePreview: Boolean, context: Context): Int {
-        return getSmallClockTopPadding(splitShadePreview, context)
-    }
-
     /*
      * SmallClockTopPadding decides the top position of smartspace
      */
-    private fun getSmallClockTopPadding(splitShadePreview: Boolean, context: Context): Int {
-        return with(context.resources) {
-            if (splitShadePreview) {
-                getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin)
-            } else {
-                getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) +
-                    SystemBarUtils.getStatusBarHeight(context) +
-                    getDimensionPixelSize(customR.dimen.keyguard_smartspace_top_offset)
-            }
-        }
+    fun getSmallClockSmartspaceTopPadding(config: ClockPreviewConfig): Int {
+        return getSmallClockTopPadding(config, systemBarUtils.getStatusBarHeaderHeightKeyguard()) +
+            config.previewContext.resources.getDimensionPixelSize(customR.dimen.small_clock_height)
+    }
+
+    fun getLargeClockSmartspaceTopPadding(clockPreviewConfig: ClockPreviewConfig): Int {
+        return getSmallClockTopPadding(
+            clockPreviewConfig,
+            systemBarUtils.getStatusBarHeaderHeightKeyguard(),
+        )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
index 6adf3e9..a249793 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow.FlowBuilder
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import javax.inject.Inject
@@ -50,9 +51,7 @@
                 duration = FromLockscreenTransitionInteractor.TO_GONE_DURATION,
                 edge = Edge.create(from = LOCKSCREEN, to = Scenes.Gone),
             )
-            .setupWithoutSceneContainer(
-                edge = Edge.create(from = LOCKSCREEN, to = GONE),
-            )
+            .setupWithoutSceneContainer(edge = Edge.create(from = LOCKSCREEN, to = GONE))
 
     val shortcutsAlpha: Flow<Float> =
         transitionAnimation.sharedFlow(
@@ -65,6 +64,10 @@
     fun notificationAlpha(viewState: ViewStateAccessor): Flow<Float> {
         var startAlpha = 1f
         var leaveShadeOpen = false
+        val endAction: (() -> Float)? =
+            if (SceneContainerFlag.isEnabled) {
+                { 1f }
+            } else null
 
         return transitionAnimation.sharedFlow(
             duration = 80.milliseconds,
@@ -79,6 +82,8 @@
                     MathUtils.lerp(startAlpha, 0f, it)
                 }
             },
+            onFinish = endAction,
+            onCancel = endAction,
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
index 6f29004..618b047 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
@@ -23,6 +23,7 @@
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -44,6 +45,7 @@
     private val deviceEntryInteractor: DeviceEntryInteractor,
     private val communalInteractor: CommunalInteractor,
     private val shadeInteractor: ShadeInteractor,
+    private val occlusionInteractor: SceneContainerOcclusionInteractor,
 ) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
@@ -57,7 +59,8 @@
                     deviceEntryInteractor.isUnlocked,
                     communalInteractor.isCommunalAvailable,
                     shadeInteractor.shadeMode,
-                ) { isDeviceUnlocked, isCommunalAvailable, shadeMode ->
+                    occlusionInteractor.isOccludingActivityShown,
+                ) { isDeviceUnlocked, isCommunalAvailable, shadeMode, isOccluded ->
                     buildList {
                             if (isCommunalAvailable) {
                                 add(Swipe.Start to Scenes.Communal)
@@ -67,7 +70,8 @@
 
                             addAll(
                                 when (shadeMode) {
-                                    ShadeMode.Single -> singleShadeActions()
+                                    ShadeMode.Single ->
+                                        singleShadeActions(isDownFromTopEdgeEnabled = !isOccluded)
                                     ShadeMode.Split -> splitShadeActions()
                                     ShadeMode.Dual -> dualShadeActions()
                                 }
diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt
index 881228d..93ecae3 100644
--- a/packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt
@@ -21,11 +21,11 @@
 import androidx.compose.runtime.snapshots.StateFactoryMarker
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.app.tracing.coroutines.traceCoroutine
+import com.android.systemui.log.table.TableLogBuffer
 import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.StateFlow
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /**
  * Keeps snapshot/Compose [State]s up-to-date.
@@ -47,6 +47,12 @@
      * concatenation or templating.
      */
     private val traceName: String,
+    /**
+     * An optional [TableLogBuffer] to log emissions to the states. [traceName] will be used as the
+     * prefix for the columns logged by this [Hydrator], allowing to aggregate multiple hydrators in
+     * the same table.
+     */
+    private val tableLogBuffer: TableLogBuffer? = null,
 ) : ExclusiveActivatable() {
 
     private val children = mutableListOf<NamedActivatable>()
@@ -62,15 +68,8 @@
      *   automatically set on the returned [State].
      */
     @StateFactoryMarker
-    fun <T> hydratedStateOf(
-        traceName: String,
-        source: StateFlow<T>,
-    ): State<T> {
-        return hydratedStateOf(
-            traceName = traceName,
-            initialValue = source.value,
-            source = source,
-        )
+    fun <T> hydratedStateOf(traceName: String, source: StateFlow<T>): State<T> {
+        return hydratedStateOf(traceName = traceName, initialValue = source.value, source = source)
     }
 
     /**
@@ -81,26 +80,44 @@
      *   performance findings with actual code. One recommendation: prefer whole string literals
      *   instead of some complex concatenation or templating scheme. Use `null` to disable
      *   performance tracing for this state.
+     *
+     *   If a [TableLogBuffer] was provided, every emission to the flow will be logged using the
+     *   [traceName] as the column name. For this to work correctly, all the states in the same
+     *   hydrator should have different [traceName]. Use `null` to disable logging for this state.
+     *
      * @param initialValue The first value to place on the [State]
      * @param source The upstream [Flow] to collect from; values emitted to it will be automatically
      *   set on the returned [State].
      */
     @StateFactoryMarker
-    fun <T> hydratedStateOf(
-        traceName: String?,
-        initialValue: T,
-        source: Flow<T>,
-    ): State<T> {
+    fun <T> hydratedStateOf(traceName: String?, initialValue: T, source: Flow<T>): State<T> {
         check(!isActive) { "Cannot call hydratedStateOf after Hydrator is already active." }
 
         val mutableState = mutableStateOf(initialValue)
+        traceName?.let { name ->
+            tableLogBuffer?.logChange(
+                prefix = this.traceName,
+                columnName = name,
+                value = initialValue?.toString(),
+                isInitial = true,
+            )
+        }
         children.add(
             NamedActivatable(
                 traceName = traceName,
                 activatable =
                     object : ExclusiveActivatable() {
                         override suspend fun onActivated(): Nothing {
-                            source.collect { mutableState.value = it }
+                            source.collect {
+                                traceName?.let { name ->
+                                    tableLogBuffer?.logChange(
+                                        prefix = this@Hydrator.traceName,
+                                        columnName = name,
+                                        value = it?.toString(),
+                                    )
+                                }
+                                mutableState.value = it
+                            }
                             awaitCancellation()
                         }
                     },
@@ -122,8 +139,5 @@
         }
     }
 
-    private data class NamedActivatable(
-        val traceName: String?,
-        val activatable: Activatable,
-    )
+    private data class NamedActivatable(val traceName: String?, val activatable: Activatable)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
index 35efd75..7d30948 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
@@ -20,6 +20,7 @@
 import android.hardware.display.DisplayManager
 import android.media.projection.MediaProjectionInfo
 import android.media.projection.MediaProjectionManager
+import android.media.projection.StopReason
 import android.os.Handler
 import android.view.ContentRecordingSession
 import android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY
@@ -72,7 +73,7 @@
         }
     }
 
-    override suspend fun stopProjecting() {
+    override suspend fun stopProjecting(@StopReason stopReason: Int) {
         withContext(backgroundDispatcher) {
             logger.log(
                 TAG,
@@ -80,7 +81,7 @@
                 {},
                 { "Requesting MediaProjectionManager#stopActiveProjection" },
             )
-            mediaProjectionManager.stopActiveProjection()
+            mediaProjectionManager.stopActiveProjection(stopReason)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt
index 50182d7..a01d8c2 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.mediaprojection.data.repository
 
 import android.app.ActivityManager.RunningTaskInfo
+import android.media.projection.StopReason
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import kotlinx.coroutines.flow.Flow
 
@@ -27,7 +28,7 @@
     suspend fun switchProjectedTask(task: RunningTaskInfo)
 
     /** Stops the currently active projection. */
-    suspend fun stopProjecting()
+    suspend fun stopProjecting(@StopReason stopReason: Int)
 
     /** Represents the current [MediaProjectionState]. */
     val mediaProjectionState: Flow<MediaProjectionState>
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index a3b7590..d2b1d54 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -56,7 +56,7 @@
 import com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.AutoHideControllerStore;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.Utils;
@@ -124,7 +124,7 @@
             TaskbarDelegate taskbarDelegate,
             NavigationBarComponent.Factory navigationBarComponentFactory,
             DumpManager dumpManager,
-            AutoHideController autoHideController,
+            AutoHideControllerStore autoHideControllerStore,
             LightBarController lightBarController,
             TaskStackChangeListeners taskStackChangeListeners,
             Optional<Pip> pipOptional,
@@ -146,8 +146,9 @@
         mTaskbarDelegate = taskbarDelegate;
         mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService,
                 navBarHelper, navigationModeController, sysUiFlagsContainer,
-                dumpManager, autoHideController, lightBarController, pipOptional,
-                backAnimation.orElse(null), taskStackChangeListeners);
+                dumpManager, autoHideControllerStore.forDisplay(mContext.getDisplayId()),
+                lightBarController, pipOptional, backAnimation.orElse(null),
+                taskStackChangeListeners);
         mIsLargeScreen = isLargeScreen(mContext);
         mIsPhone = determineIfPhone(mContext, deviceStateManager);
         dumpManager.registerDumpable(this);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 80ac2fc..0a4e8c6 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -18,6 +18,7 @@
 import static android.content.pm.ActivityInfo.CONFIG_FONT_SCALE;
 import static android.view.InputDevice.SOURCE_MOUSE;
 import static android.view.InputDevice.SOURCE_TOUCHPAD;
+import static android.view.MotionEvent.TOOL_TYPE_FINGER;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
 
 import static com.android.systemui.Flags.edgebackGestureHandlerGetRunningTasksBackground;
@@ -216,6 +217,7 @@
     private final int mDisplayId;
 
     private final UiThreadContext mUiThreadContext;
+    private final Handler mBgHandler;
     private final Executor mBackgroundExecutor;
 
     private final Rect mPipExcludedBounds = new Rect();
@@ -378,11 +380,14 @@
         @Override
         public void onInputDeviceAdded(int deviceId) {
             if (isTrackpadDevice(deviceId)) {
-                boolean wasEmpty = mTrackpadsConnected.isEmpty();
-                mTrackpadsConnected.add(deviceId);
-                if (wasEmpty) {
-                    update();
-                }
+                // This updates the gesture handler state and should be running on the main thread.
+                mUiThreadContext.getHandler().post(() -> {
+                    boolean wasEmpty = mTrackpadsConnected.isEmpty();
+                    mTrackpadsConnected.add(deviceId);
+                    if (wasEmpty) {
+                        update();
+                    }
+                });
             }
         }
 
@@ -391,10 +396,13 @@
 
         @Override
         public void onInputDeviceRemoved(int deviceId) {
-            mTrackpadsConnected.remove(deviceId);
-            if (mTrackpadsConnected.isEmpty()) {
-                update();
-            }
+            // This updates the gesture handler state and should be running on the main thread.
+            mUiThreadContext.getHandler().post(() -> {
+                mTrackpadsConnected.remove(deviceId);
+                if (mTrackpadsConnected.isEmpty()) {
+                    update();
+                }
+            });
         }
 
         private void update() {
@@ -408,12 +416,12 @@
         }
 
         private boolean isTrackpadDevice(int deviceId) {
+            // This is a blocking binder call that should run on a bg thread.
             InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
             if (inputDevice == null) {
                 return false;
             }
-            return inputDevice.getSources() == (InputDevice.SOURCE_MOUSE
-                    | InputDevice.SOURCE_TOUCHPAD);
+            return inputDevice.getSources() == (SOURCE_MOUSE | SOURCE_TOUCHPAD);
         }
     };
 
@@ -457,6 +465,7 @@
         mDisplayId = context.getDisplayId();
         mUiThreadContext = uiThreadContext;
         mBackgroundExecutor = backgroundExecutor;
+        mBgHandler = bgHandler;
         mUserTracker = userTracker;
         mOverviewProxyService = overviewProxyService;
         mSysUiState = sysUiState;
@@ -611,9 +620,7 @@
         mIsAttached = true;
         mOverviewProxyService.addCallback(mQuickSwitchListener);
         mSysUiState.addCallback(mSysUiStateCallback);
-        mInputManager.registerInputDeviceListener(
-                mInputDeviceListener,
-                mUiThreadContext.getHandler());
+        mInputManager.registerInputDeviceListener(mInputDeviceListener, mBgHandler);
         int[] inputDevices = mInputManager.getInputDeviceIds();
         for (int inputDeviceId : inputDevices) {
             mInputDeviceListener.onInputDeviceAdded(inputDeviceId);
@@ -1089,8 +1096,8 @@
                         && isValidTrackpadBackGesture(true /* isTrackpadEvent */);
             } else {
                 mAllowGesture = isBackAllowedCommon && !mUsingThreeButtonNav && isWithinInsets
-                    && isWithinTouchRegion((int) ev.getX(), (int) ev.getY())
-                    && !isButtonPressFromTrackpad(ev);
+                        && isWithinTouchRegion((int) ev.getX(), (int) ev.getY())
+                        && !isButtonPressFromTrackpad(ev);
             }
             if (mAllowGesture) {
                 mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
@@ -1202,10 +1209,8 @@
     }
 
     private boolean isButtonPressFromTrackpad(MotionEvent ev) {
-        // We don't allow back for button press from the trackpad, and yet we do with a mouse.
-        int sources = InputManager.getInstance().getInputDevice(ev.getDeviceId()).getSources();
-        int sourceTrackpad = (SOURCE_MOUSE | SOURCE_TOUCHPAD);
-        return (sources & sourceTrackpad) == sourceTrackpad && ev.getButtonState() != 0;
+        return ev.getSource() == (SOURCE_MOUSE | SOURCE_TOUCHPAD)
+                && ev.getToolType(ev.getActionIndex()) == TOOL_TYPE_FINGER;
     }
 
     private void dispatchToBackAnimation(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
index 40613c0..c895732 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -149,9 +149,9 @@
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.data.repository.LightBarControllerStore;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.AutoHideControllerStore;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -259,10 +259,10 @@
     private boolean mTransientShownFromGestureOnSystemBar;
     private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
     private LightBarController mLightBarController;
-    private final LightBarControllerStore mLightBarControllerStore;
+    private final LightBarController mMainLightBarController;
+    private final LightBarController.Factory mLightBarControllerFactory;
     private AutoHideController mAutoHideController;
-    private final AutoHideController mMainAutoHideController;
-    private final AutoHideController.Factory mAutoHideControllerFactory;
+    private final AutoHideControllerStore mAutoHideControllerStore;
     private final Optional<TelecomManager> mTelecomManagerOptional;
     private final InputMethodManager mInputMethodManager;
     private final TaskStackChangeListeners mTaskStackChangeListeners;
@@ -580,9 +580,9 @@
             @Background Executor bgExecutor,
             UiEventLogger uiEventLogger,
             NavBarHelper navBarHelper,
-            LightBarControllerStore lightBarControllerStore,
-            AutoHideController mainAutoHideController,
-            AutoHideController.Factory autoHideControllerFactory,
+            LightBarController mainLightBarController,
+            LightBarController.Factory lightBarControllerFactory,
+            AutoHideControllerStore autoHideControllerStore,
             Optional<TelecomManager> telecomManagerOptional,
             InputMethodManager inputMethodManager,
             DeadZone deadZone,
@@ -627,9 +627,9 @@
         mUiEventLogger = uiEventLogger;
         mNavBarHelper = navBarHelper;
         mNotificationShadeDepthController = notificationShadeDepthController;
-        mLightBarControllerStore = lightBarControllerStore;
-        mMainAutoHideController = mainAutoHideController;
-        mAutoHideControllerFactory = autoHideControllerFactory;
+        mMainLightBarController = mainLightBarController;
+        mLightBarControllerFactory = lightBarControllerFactory;
+        mAutoHideControllerStore = autoHideControllerStore;
         mTelecomManagerOptional = telecomManagerOptional;
         mInputMethodManager = inputMethodManager;
         mUserContextProvider = userContextProvider;
@@ -840,16 +840,11 @@
         // Unfortunately, we still need it because status bar needs LightBarController
         // before notifications creation. We cannot directly use getLightBarController()
         // from NavigationBarFragment directly.
-        LightBarController lightBarController = mLightBarControllerStore.forDisplay(mDisplayId);
+        LightBarController lightBarController = mIsOnDefaultDisplay
+                ? mMainLightBarController : mLightBarControllerFactory.create(mContext);
         setLightBarController(lightBarController);
 
-        // TODO(b/118592525): to support multi-display, we start to add something which is
-        //                    per-display, while others may be global. I think it's time to
-        //                    add a new class maybe named DisplayDependency to solve
-        //                    per-display Dependency problem.
-        // Alternative: this is a good case for a Dagger subcomponent. Same with LightBarController.
-        AutoHideController autoHideController = mIsOnDefaultDisplay
-                ? mMainAutoHideController : mAutoHideControllerFactory.create(mContext);
+        AutoHideController autoHideController = mAutoHideControllerStore.forDisplay(mDisplayId);
         setAutoHideController(autoHideController);
         restoreAppearanceAndTransientState();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index a615963..ad1f370 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -43,6 +43,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
 import com.android.systemui.log.DebugLogger.debugLog
+import com.android.systemui.notetask.NoteTaskEntryPoint.KEYBOARD_SHORTCUT
 import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
 import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
 import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
@@ -117,7 +118,6 @@
             } else {
                 getUserForHandlingNotesTaking(entryPoint)
             }
-
         activityContext.startActivityAsUser(createNotesRoleHolderSettingsIntent(), user)
     }
 
@@ -206,9 +206,17 @@
         try {
             // TODO(b/266686199): We should handle when app not available. For now, we log.
             debugLog { "onShowNoteTask - start: $info on user#${user.identifier}" }
+            val useStylusMode =
+                when {
+                    info.entryPoint == TAIL_BUTTON -> true
+                    info.entryPoint == KEYBOARD_SHORTCUT -> false
+                    else ->
+                        context.resources.getInteger(R.integer.config_preferredNotesMode) ==
+                            PREFERRED_NOTES_MODE_STYLUS
+                }
             when (info.launchMode) {
                 is NoteTaskLaunchMode.AppBubble -> {
-                    val intent = createNoteTaskIntent(info)
+                    val intent = createNoteTaskIntent(info, useStylusMode)
                     val icon =
                         Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
                     noteTaskBubblesController.showOrHideAppBubble(
@@ -229,7 +237,7 @@
                         eventLogger.logNoteTaskClosed(info)
                         debugLog { "onShowNoteTask - closed as activity: $info" }
                     } else {
-                        val intent = createNoteTaskIntent(info)
+                        val intent = createNoteTaskIntent(info, useStylusMode)
                         context.startActivityAsUser(intent, user)
                         eventLogger.logNoteTaskOpened(info)
                         debugLog { "onShowNoteTask - opened as activity: $info" }
@@ -393,6 +401,8 @@
          */
         const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package"
 
+        const val PREFERRED_NOTES_MODE_STYLUS = 1
+
         /** Returns notes role holder settings intent. */
         fun createNotesRoleHolderSettingsIntent() =
             Intent(Intent.ACTION_MANAGE_DEFAULT_APP).putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NOTES)
@@ -400,13 +410,12 @@
 }
 
 /** Creates an [Intent] for [ROLE_NOTES]. */
-private fun createNoteTaskIntent(info: NoteTaskInfo): Intent =
+private fun createNoteTaskIntent(info: NoteTaskInfo, useStylusMode: Boolean): Intent =
     Intent(Intent.ACTION_CREATE_NOTE).apply {
         setPackage(info.packageName)
 
         // EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint
         // was used to start the note task.
-        val useStylusMode = info.entryPoint != NoteTaskEntryPoint.KEYBOARD_SHORTCUT
         putExtra(Intent.EXTRA_USE_STYLUS_MODE, useStylusMode)
 
         addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index d715f42..dc188c2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -16,8 +16,11 @@
 
 package com.android.systemui.qs;
 
+import static com.android.systemui.Flags.gsfQuickSettings;
+
 import android.content.ClipData;
 import android.content.ClipboardManager;
+import android.graphics.Typeface;
 import android.text.TextUtils;
 import android.view.View;
 import android.widget.TextView;
@@ -64,6 +67,9 @@
         mRetailModeInteractor = retailModeInteractor;
 
         mBuildText = mView.findViewById(R.id.build);
+        if (gsfQuickSettings()) {
+            mBuildText.setTypeface(Typeface.create("gsf-body-medium", Typeface.NORMAL));
+        }
         mPageIndicator = mView.findViewById(R.id.footer_page_indicator);
         mEditButton = mView.findViewById(android.R.id.edit);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index 21c45c5..9dc21fb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -233,6 +233,7 @@
                 // Only allow scrolling when we are fully expanded. That way, we don't intercept
                 // swipes in lockscreen (when somehow QS is receiving touches).
                 { (scrollState.canScrollForward && viewModel.isQsFullyExpanded) || isCustomizing },
+                viewModel::emitMotionEventForFalsingSwipeNested,
             )
         frame.addView(
             composeView,
@@ -628,11 +629,7 @@
                                         id = R.string.accessibility_quick_settings_expand
                                     )
                                 )
-                                .padding(
-                                    horizontal = {
-                                        QuickSettingsShade.Dimensions.Padding.roundToPx()
-                                    }
-                                )
+                                .padding(horizontal = qsHorizontalMargin())
                     ) {
                         QuickQuickSettingsLayout(
                             tiles = Tiles,
@@ -718,7 +715,6 @@
                                                     max =
                                                         QuickSettingsShade.Dimensions.GridMaxHeight
                                                 ),
-                                        containerViewModel.editModeViewModel::startEditing,
                                     )
                                 }
                             }
@@ -737,8 +733,8 @@
                                     .sysuiResTag(ResIdTags.quickSettingsPanel)
                                     .padding(
                                         top = QuickSettingsShade.Dimensions.Padding,
-                                        start = QuickSettingsShade.Dimensions.Padding,
-                                        end = QuickSettingsShade.Dimensions.Padding,
+                                        start = qsHorizontalMargin(),
+                                        end = qsHorizontalMargin(),
                                     )
                         ) {
                             QuickSettingsLayout(
@@ -951,6 +947,7 @@
     private val clippingEnabledProvider: () -> Boolean,
     private val clippingTopProvider: () -> Int,
     private val canScrollForwardQs: () -> Boolean,
+    private val emitMotionEventForFalsing: () -> Unit,
 ) : FrameLayout(context) {
     override fun isTransformedTouchPointInView(
         x: Float,
@@ -967,6 +964,32 @@
 
     val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
     var downY = 0f
+    var preventingIntercept = false
+
+    override fun onTouchEvent(event: MotionEvent): Boolean {
+        val action = event.actionMasked
+        when (action) {
+            MotionEvent.ACTION_DOWN -> {
+                preventingIntercept = false
+                if (canScrollVertically(1)) {
+                    // If we can scroll down, make sure we're not intercepted by the parent
+                    preventingIntercept = true
+                    parent?.requestDisallowInterceptTouchEvent(true)
+                } else if (!canScrollVertically(-1)) {
+                    // Don't pass on the touch to the view, because scrolling will unconditionally
+                    // disallow interception even if we can't scroll.
+                    // if a user can't scroll at all, we should never listen to the touch.
+                    return false
+                }
+            }
+            MotionEvent.ACTION_UP -> {
+                if (preventingIntercept) {
+                    emitMotionEventForFalsing()
+                }
+            }
+        }
+        return super.onTouchEvent(event)
+    }
 
     override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
         // If there's a touch on this view and we can scroll down, we don't want to be intercepted
@@ -974,8 +997,10 @@
 
         when (action) {
             MotionEvent.ACTION_DOWN -> {
+                preventingIntercept = false
                 // If we can scroll down, make sure none of our parents intercepts us.
                 if (canScrollForwardQs()) {
+                    preventingIntercept = true
                     parent?.requestDisallowInterceptTouchEvent(true)
                 }
                 downY = ev.y
@@ -1098,6 +1123,8 @@
     const val qsFooterActions = "qs_footer_actions"
 }
 
+@Composable private fun qsHorizontalMargin() = dimensionResource(id = R.dimen.qs_horizontal_margin)
+
 @Composable
 private fun interactionsConfig() =
     InteractionsConfig(
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeLog.kt
similarity index 75%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeLog.kt
index 5a04169..5f151eb 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeLog.kt
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.systemui.qs.composefragment.dagger
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+import javax.inject.Qualifier
+
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class QSFragmentComposeLog
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
index 2ec7292..4c9df11 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
@@ -18,7 +18,8 @@
 
 import android.content.Context
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.TableLogBufferFactory
 import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.util.Utils
@@ -38,5 +39,14 @@
         fun providesUsingMedia(@ShadeDisplayAware context: Context): Boolean {
             return QSComposeFragment.isEnabled && Utils.useQsMediaPlayer(context)
         }
+
+        @Provides
+        @SysUISingleton
+        @QSFragmentComposeLog
+        fun providesQSFragmentComposeViewModelTableLog(
+            factory: TableLogBufferFactory
+        ): TableLogBuffer {
+            return factory.create("QSFragmentComposeViewModel", 200)
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
index e3de6d5..02498d6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
@@ -31,6 +31,8 @@
 import com.android.keyguard.BouncerPanelExpansionCalculator
 import com.android.systemui.Dumpable
 import com.android.systemui.animation.ShadeInterpolation
+import com.android.systemui.classifier.Classifier
+import com.android.systemui.classifier.domain.interactor.FalsingInteractor
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
@@ -39,6 +41,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
 import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QQS
 import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
@@ -48,6 +51,7 @@
 import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.FooterActionsController
+import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeLog
 import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
 import com.android.systemui.qs.panels.domain.interactor.TileSquishinessInteractor
@@ -100,7 +104,9 @@
     @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
     private val largeScreenHeaderHelper: LargeScreenHeaderHelper,
     private val squishinessInteractor: TileSquishinessInteractor,
+    private val falsingInteractor: FalsingInteractor,
     private val inFirstPageViewModel: InFirstPageViewModel,
+    @QSFragmentComposeLog private val tableLogBuffer: TableLogBuffer,
     mediaInRowInLandscapeViewModelFactory: MediaInRowInLandscapeViewModel.Factory,
     @Named(QUICK_QS_PANEL) val qqsMediaHost: MediaHost,
     @Named(QS_PANEL) val qsMediaHost: MediaHost,
@@ -112,7 +118,7 @@
     private val qqsMediaInRowViewModel = mediaInRowInLandscapeViewModelFactory.create(LOCATION_QQS)
     private val qsMediaInRowViewModel = mediaInRowInLandscapeViewModelFactory.create(LOCATION_QS)
 
-    private val hydrator = Hydrator("QSFragmentComposeViewModel.hydrator")
+    private val hydrator = Hydrator("QSFragmentComposeViewModel.hydrator", tableLogBuffer)
 
     val footerActionsViewModel =
         footerActionsViewModelFactory.create(lifecycleScope).also {
@@ -434,6 +440,10 @@
         }
     }
 
+    fun emitMotionEventForFalsingSwipeNested() {
+        falsingInteractor.isFalseTouch(Classifier.QS_SWIPE_NESTED)
+    }
+
     override suspend fun onActivated(): Nothing {
         initMediaHosts() // init regardless of using media (same as current QS).
         coroutineScope {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index f8d4080..0e64820 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -15,6 +15,8 @@
  */
 package com.android.systemui.qs.customize;
 
+import static com.android.systemui.Flags.gsfQuickSettings;
+
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorListenerAdapter;
@@ -81,6 +83,10 @@
         mToolbar.getMenu().add(Menu.NONE, MENU_RESET, 0, com.android.internal.R.string.reset)
                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
         mToolbar.setTitle(R.string.qs_edit);
+        if (gsfQuickSettings()) {
+            mToolbar.setTitleTextAppearance(context, R.style.TextAppearance_QSEditTitle);
+        }
+
         mRecyclerView = findViewById(android.R.id.list);
         mTransparentView = findViewById(R.id.customizer_transparent_view);
         DefaultItemAnimator animator = new DefaultItemAnimator();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 829c419..db778a2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -14,12 +14,15 @@
 
 package com.android.systemui.qs.customize;
 
+import static com.android.systemui.Flags.gsfQuickSettings;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.view.LayoutInflater;
@@ -309,6 +312,10 @@
         if (viewType == TYPE_HEADER) {
             View v = inflater.inflate(R.layout.qs_customize_header, parent, false);
             v.setMinimumHeight(calculateHeaderMinHeight(context));
+            if (gsfQuickSettings()) {
+                ((TextView) v.findViewById(android.R.id.title)).setTypeface(
+                        Typeface.create("gsf-label-large", Typeface.NORMAL));
+            }
             return new Holder(v);
         }
         if (viewType == TYPE_DIVIDER) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt
new file mode 100644
index 0000000..c2764f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.compose
+
+import androidx.compose.foundation.shape.CornerSize
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.EditModeButtonViewModel
+import com.android.systemui.qs.ui.compose.borderOnFocus
+import com.android.systemui.res.R
+
+@Composable
+fun EditModeButton(
+    viewModelFactory: EditModeButtonViewModel.Factory,
+    modifier: Modifier = Modifier,
+) {
+    val viewModel = rememberViewModel(traceName = "EditModeButton") { viewModelFactory.create() }
+    CompositionLocalProvider(
+        value = LocalContentColor provides MaterialTheme.colorScheme.onSurface
+    ) {
+        IconButton(
+            onClick = viewModel::onButtonClick,
+            shape = RoundedCornerShape(CornerSize(28.dp)),
+            modifier =
+                modifier.borderOnFocus(
+                    color = MaterialTheme.colorScheme.secondary,
+                    cornerSize = CornerSize(24.dp),
+                ),
+        ) {
+            Icon(
+                imageVector = Icons.Default.Edit,
+                contentDescription = stringResource(id = R.string.qs_edit),
+            )
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
index c729c7c..14abfa2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
@@ -68,29 +68,16 @@
         return _tiles.indexOfFirst { it is TileGridCell && it.tile.tileSpec == tileSpec }
     }
 
-    /**
-     * Whether the tile with this [TileSpec] is currently an icon in the [EditTileListState]
-     *
-     * @return true if the tile is an icon, false if it's large, null if the tile isn't in the list
-     */
-    fun isIcon(tileSpec: TileSpec): Boolean? {
-        val index = indexOf(tileSpec)
-        return if (index != -1) {
-            val cell = _tiles[index]
-            cell as TileGridCell
-            return cell.isIcon
-        } else {
-            null
-        }
-    }
-
-    /** Toggle the size of the tile corresponding to the [TileSpec] */
-    fun toggleSize(tileSpec: TileSpec) {
+    /** Resize the tile corresponding to the [TileSpec] to [toIcon] */
+    fun resizeTile(tileSpec: TileSpec, toIcon: Boolean) {
         val fromIndex = indexOf(tileSpec)
         if (fromIndex != -1) {
-            val cell = _tiles.removeAt(fromIndex)
-            cell as TileGridCell
-            _tiles.add(fromIndex, cell.copy(width = if (cell.isIcon) largeTilesSpan else 1))
+            val cell = _tiles[fromIndex] as TileGridCell
+
+            if (cell.isIcon == toIcon) return
+
+            _tiles.removeAt(fromIndex)
+            _tiles.add(fromIndex, cell.copy(width = if (toIcon) 1 else largeTilesSpan))
             regenerateGrid(fromIndex)
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
index 0d37581..a22eb3a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
@@ -27,12 +27,7 @@
 
 /** A layout of tiles, indicating how they should be composed when showing in QS or in edit mode. */
 interface GridLayout {
-    @Composable
-    fun SceneScope.TileGrid(
-        tiles: List<TileViewModel>,
-        modifier: Modifier,
-        editModeStart: () -> Unit,
-    )
+    @Composable fun SceneScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier)
 
     @Composable
     fun EditTileGrid(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
index 789fdeb..b6dbf4d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs.panels.ui.compose
 
+import android.view.MotionEvent
 import androidx.compose.foundation.layout.Arrangement.spacedBy
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
@@ -29,22 +30,15 @@
 import androidx.compose.foundation.pager.PagerState
 import androidx.compose.foundation.pager.rememberPagerState
 import androidx.compose.foundation.shape.CornerSize
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Edit
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
-import androidx.compose.material3.LocalContentColor
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.snapshotFlow
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.input.pointer.pointerInteropFilter
 import androidx.compose.ui.unit.dp
 import com.android.compose.animation.scene.SceneScope
 import com.android.compose.modifiers.padding
@@ -55,10 +49,10 @@
 import com.android.systemui.qs.panels.dagger.PaginatedBaseLayoutType
 import com.android.systemui.qs.panels.ui.compose.Dimensions.FooterHeight
 import com.android.systemui.qs.panels.ui.compose.Dimensions.InterPageSpacing
+import com.android.systemui.qs.panels.ui.viewmodel.EditModeButtonViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.PaginatedGridViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
 import com.android.systemui.qs.ui.compose.borderOnFocus
-import com.android.systemui.res.R
 import javax.inject.Inject
 
 class PaginatedGridLayout
@@ -68,11 +62,7 @@
     @PaginatedBaseLayoutType private val delegateGridLayout: PaginatableGridLayout,
 ) : GridLayout by delegateGridLayout {
     @Composable
-    override fun SceneScope.TileGrid(
-        tiles: List<TileViewModel>,
-        modifier: Modifier,
-        editModeStart: () -> Unit,
-    ) {
+    override fun SceneScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) {
         val viewModel =
             rememberViewModel(traceName = "PaginatedGridLayout-TileGrid") {
                 viewModelFactory.create()
@@ -115,7 +105,13 @@
                 state = pagerState,
                 modifier =
                     Modifier.sysuiResTag("qs_pager")
-                        .padding(horizontal = { -contentPaddingValue.roundToPx() }),
+                        .padding(horizontal = { -contentPaddingValue.roundToPx() })
+                        .pointerInteropFilter { event ->
+                            if (event.actionMasked == MotionEvent.ACTION_UP) {
+                                viewModel.registerSideSwipeGesture()
+                            }
+                            false
+                        },
                 contentPadding = contentPadding,
                 pageSpacing = if (pages.size > 1) InterPageSpacing else 0.dp,
                 beyondViewportPageCount = 1,
@@ -123,14 +119,12 @@
             ) {
                 val page = pages[it]
 
-                with(delegateGridLayout) {
-                    TileGrid(tiles = page, modifier = Modifier, editModeStart = {})
-                }
+                with(delegateGridLayout) { TileGrid(tiles = page, modifier = Modifier) }
             }
             FooterBar(
                 buildNumberViewModelFactory = viewModel.buildNumberViewModelFactory,
                 pagerState = pagerState,
-                editModeStart = editModeStart,
+                editButtonViewModelFactory = viewModel.editModeButtonViewModelFactory,
             )
         }
     }
@@ -145,7 +139,7 @@
 private fun FooterBar(
     buildNumberViewModelFactory: BuildNumberViewModel.Factory,
     pagerState: PagerState,
-    editModeStart: () -> Unit,
+    editButtonViewModelFactory: EditModeButtonViewModel.Factory,
 ) {
     // Use requiredHeight so it won't be squished if the view doesn't quite fit. As this is
     // expected to be inside a scrollable container, this should not be an issue.
@@ -181,24 +175,7 @@
         )
         Row(Modifier.weight(1f)) {
             Spacer(modifier = Modifier.weight(1f))
-            CompositionLocalProvider(
-                value = LocalContentColor provides MaterialTheme.colorScheme.onSurface
-            ) {
-                IconButton(
-                    onClick = editModeStart,
-                    shape = RoundedCornerShape(CornerSize(28.dp)),
-                    modifier =
-                        Modifier.borderOnFocus(
-                            color = MaterialTheme.colorScheme.secondary,
-                            cornerSize = CornerSize(FooterHeight / 2),
-                        ),
-                ) {
-                    Icon(
-                        imageVector = Icons.Default.Edit,
-                        contentDescription = stringResource(id = R.string.qs_edit),
-                    )
-                }
-            }
+            EditModeButton(viewModelFactory = editButtonViewModelFactory)
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
index ca28ab3..2928ad1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
@@ -75,6 +75,8 @@
                 coroutineScope = scope,
                 bounceableInfo = bounceables.bounceableInfo(it, spanIndex, column, columns),
                 tileHapticsViewModelFactoryProvider = viewModel.tileHapticsViewModelFactoryProvider,
+                // There should be no QuickQuickSettings when the details view is enabled.
+                detailsViewModel = null,
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
new file mode 100644
index 0000000..1bfbbe1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
@@ -0,0 +1,121 @@
+/*
+ * 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.compose
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.filled.ArrowBack
+import androidx.compose.material.icons.filled.Settings
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.em
+import com.android.systemui.qs.flags.QsDetailedView
+import com.android.systemui.qs.panels.ui.viewmodel.DetailsViewModel
+
+@Composable
+fun TileDetails(detailsViewModel: DetailsViewModel) {
+
+    if (!QsDetailedView.isEnabled) {
+        throw IllegalStateException("QsDetailedView should be enabled")
+    }
+
+    val tileDetailedViewModel = detailsViewModel.activeTileDetails ?: return
+
+    DisposableEffect(Unit) { onDispose { detailsViewModel.closeDetailedView() } }
+
+    Column(
+        modifier = Modifier
+            .fillMaxWidth()
+            // The height of the details view is TBD.
+            .fillMaxHeight()
+    ) {
+        CompositionLocalProvider(
+            value = LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant
+        ) {
+            Row(
+                modifier = Modifier.fillMaxWidth(),
+                horizontalArrangement = Arrangement.SpaceBetween,
+                verticalAlignment = Alignment.CenterVertically
+            ) {
+
+                IconButton(
+                    onClick = { detailsViewModel.closeDetailedView() },
+                    modifier = Modifier
+                        .align(Alignment.CenterVertically)
+                        .height(TileDetailsDefaults.IconHeight)
+                        .padding(start = TileDetailsDefaults.IconPadding),
+                ) {
+                    Icon(
+                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,
+                        // Description is TBD
+                        contentDescription = "Back to QS panel",
+                    )
+                }
+                Text(
+                    text = tileDetailedViewModel.getTitle(),
+                    modifier = Modifier
+                        .align(Alignment.CenterVertically),
+                    textAlign = TextAlign.Center,
+                    style = MaterialTheme.typography.titleLarge
+                )
+                IconButton(
+                    onClick = { tileDetailedViewModel.clickOnSettingsButton() },
+                    modifier = Modifier
+                        .align(Alignment.CenterVertically)
+                        .height(TileDetailsDefaults.IconHeight)
+                        .padding(end = TileDetailsDefaults.IconPadding),
+                ) {
+                    Icon(
+                        imageVector = Icons.Default.Settings,
+                        // Description is TBD
+                        contentDescription = "Go to Settings",
+                    )
+                }
+            }
+            Text(
+                text = tileDetailedViewModel.getSubTitle(),
+                modifier = Modifier
+                    .fillMaxWidth(),
+                textAlign = TextAlign.Center,
+                style = MaterialTheme.typography.titleSmall
+
+            )
+        }
+        tileDetailedViewModel.GetContentView()
+    }
+}
+
+private object TileDetailsDefaults {
+    val IconHeight = 48.dp
+    val IconPadding = 4.dp
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
index 1a5297b..6c1906b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
@@ -24,13 +24,9 @@
 import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
 
 @Composable
-fun SceneScope.TileGrid(
-    viewModel: TileGridViewModel,
-    modifier: Modifier = Modifier,
-    editModeStart: () -> Unit,
-) {
+fun SceneScope.TileGrid(viewModel: TileGridViewModel, modifier: Modifier = Modifier) {
     val gridLayout by viewModel.gridLayout.collectAsStateWithLifecycle()
     val tiles by viewModel.tileViewModels.collectAsStateWithLifecycle(emptyList())
 
-    with(gridLayout) { TileGrid(tiles, modifier, editModeStart) }
+    with(gridLayout) { TileGrid(tiles, modifier) }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
index 31ea60e..c6141a1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
@@ -20,7 +20,6 @@
 
 import androidx.compose.animation.AnimatedContent
 import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.animateDpAsState
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.animation.fadeIn
@@ -75,7 +74,6 @@
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.runtime.setValue
-import androidx.compose.runtime.snapshotFlow
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
@@ -124,8 +122,12 @@
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.CurrentTilesGridPadding
 import com.android.systemui.qs.panels.ui.compose.selection.MutableSelectionState
 import com.android.systemui.qs.panels.ui.compose.selection.ResizableTileContainer
-import com.android.systemui.qs.panels.ui.compose.selection.TileWidths
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.FinalResizeOperation
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.TemporaryResizeOperation
 import com.android.systemui.qs.panels.ui.compose.selection.clearSelectionTile
+import com.android.systemui.qs.panels.ui.compose.selection.rememberResizingState
 import com.android.systemui.qs.panels.ui.compose.selection.rememberSelectionState
 import com.android.systemui.qs.panels.ui.compose.selection.selectableTile
 import com.android.systemui.qs.panels.ui.model.GridCell
@@ -136,10 +138,10 @@
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.shared.model.groupAndSort
 import com.android.systemui.res.R
+import kotlin.math.max
 import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.collectLatest
 
 object TileType
 
@@ -181,15 +183,7 @@
     onStopEditing: () -> Unit,
     onReset: (() -> Unit)?,
 ) {
-    val currentListState by rememberUpdatedState(listState)
-    val selectionState =
-        rememberSelectionState(
-            onResize = { currentListState.toggleSize(it) },
-            onResizeEnd = { spec ->
-                // Commit the size currently in the list
-                currentListState.isIcon(spec)?.let { onResize(spec, it) }
-            },
-        )
+    val selectionState = rememberSelectionState()
     val reset: (() -> Unit)? =
         if (onReset != null) {
             {
@@ -349,10 +343,21 @@
                 }
                 .testTag(CURRENT_TILES_GRID_TEST_TAG),
     ) {
-        EditTiles(cells, columns, listState, selectionState, coroutineScope, largeTilesSpan) { spec
-            ->
-            // Toggle the current size of the tile
-            currentListState.isIcon(spec)?.let { onResize(spec, !it) }
+        EditTiles(cells, columns, listState, selectionState, coroutineScope, largeTilesSpan) {
+            resizingOperation ->
+            when (resizingOperation) {
+                is TemporaryResizeOperation -> {
+                    currentListState.resizeTile(resizingOperation.spec, resizingOperation.toIcon)
+                }
+                is FinalResizeOperation -> {
+                    // Commit the new size of the tile
+                    onResize(resizingOperation.spec, resizingOperation.toIcon)
+
+                    // Mark the selection as automatic in case the tile ends up moving to a
+                    // different row with its new size.
+                    selectionState.select(resizingOperation.spec, manual = false)
+                }
+            }
         }
     }
 }
@@ -373,7 +378,7 @@
 
     // Available tiles
     Column(
-        verticalArrangement = spacedBy(CommonTileDefaults.TileArrangementPadding),
+        verticalArrangement = spacedBy(TileArrangementPadding),
         horizontalAlignment = Alignment.Start,
         modifier =
             Modifier.fillMaxWidth().wrapContentHeight().testTag(AVAILABLE_TILES_GRID_TEST_TAG),
@@ -387,7 +392,7 @@
             )
             tiles.chunked(columns).forEach { row ->
                 Row(
-                    horizontalArrangement = spacedBy(CommonTileDefaults.TileArrangementPadding),
+                    horizontalArrangement = spacedBy(TileArrangementPadding),
                     modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Max),
                 ) {
                     row.forEachIndexed { index, tileGridCell ->
@@ -436,7 +441,7 @@
     selectionState: MutableSelectionState,
     coroutineScope: CoroutineScope,
     largeTilesSpan: Int,
-    onToggleSize: (spec: TileSpec) -> Unit,
+    onResize: (operation: ResizeOperation) -> Unit,
 ) {
     items(
         count = cells.size,
@@ -464,7 +469,7 @@
                         index = index,
                         dragAndDropState = dragAndDropState,
                         selectionState = selectionState,
-                        onToggleSize = onToggleSize,
+                        onResize = onResize,
                         coroutineScope = coroutineScope,
                         bounceableInfo = cells.bounceableInfo(index, columns),
                         largeTilesSpan = largeTilesSpan,
@@ -482,7 +487,7 @@
     index: Int,
     dragAndDropState: DragAndDropState,
     selectionState: MutableSelectionState,
-    onToggleSize: (spec: TileSpec) -> Unit,
+    onResize: (operation: ResizeOperation) -> Unit,
     coroutineScope: CoroutineScope,
     largeTilesSpan: Int,
     bounceableInfo: BounceableInfo,
@@ -511,28 +516,47 @@
         selected = selectionState.selection?.tileSpec == cell.tile.tileSpec
     }
 
-    // Current base, min and max width of this tile
-    var tileWidths: TileWidths? by remember { mutableStateOf(null) }
-    val padding = with(LocalDensity.current) { TileArrangementPadding.roundToPx() }
+    val state = rememberResizingState(cell.tile.tileSpec, cell.isIcon)
+
+    val progress: () -> Float = {
+        if (selected) {
+            // If selected, return the manual progress from the drag
+            state.progress()
+        } else {
+            // Else, return the target progress for the tile format
+            if (cell.isIcon) 0f else 1f
+        }
+    }
+
+    if (!selected) {
+        // Update the draggable anchor state when the tile's size is not manually toggled
+        LaunchedEffect(cell.isIcon) { state.updateCurrentValue(cell.isIcon) }
+    } else {
+        // If the tile is selected, listen to new target values from the draggable anchor to toggle
+        // the tile's size
+        LaunchedEffect(state.temporaryResizeOperation) { onResize(state.temporaryResizeOperation) }
+        LaunchedEffect(state.finalResizeOperation) { onResize(state.finalResizeOperation) }
+    }
+
+    val totalPadding =
+        with(LocalDensity.current) { (largeTilesSpan - 1) * TileArrangementPadding.roundToPx() }
 
     ResizableTileContainer(
         selected = selected,
-        selectionState = selectionState,
+        state = state,
         selectionAlpha = { selectionAlpha },
         selectionColor = selectionColor,
-        tileWidths = { tileWidths },
         modifier =
             modifier
                 .height(TileHeight)
                 .fillMaxWidth()
                 .onSizeChanged {
                     // Grab the size before the bounceable to get the idle width
-                    val totalPadding = (largeTilesSpan - 1) * padding
                     val min =
                         if (cell.isIcon) it.width else (it.width - totalPadding) / largeTilesSpan
                     val max =
                         if (cell.isIcon) (it.width * largeTilesSpan) + totalPadding else it.width
-                    tileWidths = TileWidths(it.width, min, max)
+                    state.updateAnchors(min.toFloat(), max.toFloat())
                 }
                 .bounceable(
                     bounceable = currentBounceableInfo.bounceable,
@@ -552,7 +576,7 @@
                         listOf(
                             // TODO(b/367748260): Add final accessibility actions
                             CustomAccessibilityAction("Toggle size") {
-                                onToggleSize(cell.tile.tileSpec)
+                                onResize(FinalResizeOperation(cell.tile.tileSpec, !cell.isIcon))
                                 true
                             }
                         )
@@ -567,24 +591,7 @@
                 )
                 .tileBackground(colors.background)
         ) {
-            val targetValue = if (cell.isIcon) 0f else 1f
-            val animatedProgress = remember { Animatable(targetValue) }
-
-            val resizingState = selectionState.resizingState?.takeIf { selected }
-            LaunchedEffect(targetValue, resizingState) {
-                if (resizingState == null) {
-                    animatedProgress.animateTo(targetValue)
-                } else {
-                    snapshotFlow { resizingState.progression }
-                        .collectLatest { animatedProgress.snapTo(it) }
-                }
-            }
-
-            EditTile(
-                tile = cell.tile,
-                tileWidths = { tileWidths },
-                progress = { animatedProgress.value },
-            )
+            EditTile(tile = cell.tile, state = state, progress = progress)
         }
     }
 }
@@ -651,7 +658,7 @@
 @Composable
 fun EditTile(
     tile: EditTileViewModel,
-    tileWidths: () -> TileWidths?,
+    state: ResizingState,
     progress: () -> Float,
     colors: TileColors = EditModeTileDefaults.editTileColors(),
 ) {
@@ -661,12 +668,16 @@
         verticalAlignment = Alignment.CenterVertically,
         modifier =
             Modifier.layout { measurable, constraints ->
+                    val (min, max) = state.bounds
+                    val currentProgress = progress()
                     // Always display the tile using the large size and trust the parent composable
                     // to clip the content as needed. This stop the labels from being truncated.
-                    val width = tileWidths()?.max ?: constraints.maxWidth
+                    val width =
+                        max?.roundToInt()?.takeIf { it > constraints.maxWidth }
+                            ?: constraints.maxWidth
                     val placeable =
                         measurable.measure(constraints.copy(minWidth = width, maxWidth = width))
-                    val currentProgress = progress()
+
                     val startPadding =
                         if (currentProgress == 0f) {
                             // Find the center of the max width when the tile is icon only
@@ -675,7 +686,7 @@
                             // Find the center of the minimum width to hold the same position as the
                             // tile is resized.
                             val basePadding =
-                                tileWidths()?.min?.let { iconHorizontalCenter(it) } ?: 0f
+                                min?.let { iconHorizontalCenter(it.roundToInt()) } ?: 0f
                             // Large tiles, represented with a progress of 1f, have a 0.dp padding
                             basePadding * (1f - currentProgress)
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
index 29ff171..8fd99a5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.qs.panels.ui.compose.bounceableInfo
 import com.android.systemui.qs.panels.ui.compose.rememberEditListState
 import com.android.systemui.qs.panels.ui.viewmodel.BounceableTileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.DetailsViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridViewModel
@@ -49,17 +50,14 @@
 class InfiniteGridLayout
 @Inject
 constructor(
+    private val detailsViewModel: DetailsViewModel,
     private val iconTilesViewModel: IconTilesViewModel,
     private val viewModelFactory: InfiniteGridViewModel.Factory,
     private val tileHapticsViewModelFactoryProvider: TileHapticsViewModelFactoryProvider,
 ) : PaginatableGridLayout {
 
     @Composable
-    override fun SceneScope.TileGrid(
-        tiles: List<TileViewModel>,
-        modifier: Modifier,
-        editModeStart: () -> Unit,
-    ) {
+    override fun SceneScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) {
         DisposableEffect(tiles) {
             val token = Any()
             tiles.forEach { it.startListening(token) }
@@ -104,6 +102,7 @@
                 tileHapticsViewModelFactoryProvider = tileHapticsViewModelFactoryProvider,
                 coroutineScope = scope,
                 bounceableInfo = bounceables.bounceableInfo(it, spanIndex, column, columns),
+                detailsViewModel = detailsViewModel,
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
index 0a80a19..abdf923 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
@@ -77,10 +77,12 @@
 import com.android.systemui.haptics.msdl.qs.TileHapticsViewModelFactoryProvider
 import com.android.systemui.lifecycle.rememberViewModel
 import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.qs.flags.QsDetailedView
 import com.android.systemui.qs.panels.ui.compose.BounceableInfo
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.InactiveCornerRadius
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.TileHeight
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.longPressLabel
+import com.android.systemui.qs.panels.ui.viewmodel.DetailsViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileUiState
 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.toUiState
@@ -121,6 +123,7 @@
     bounceableInfo: BounceableInfo,
     tileHapticsViewModelFactoryProvider: TileHapticsViewModelFactoryProvider,
     modifier: Modifier = Modifier,
+    detailsViewModel: DetailsViewModel?,
 ) {
     val state by tile.state.collectAsStateWithLifecycle(tile.currentState)
     val currentBounceableInfo by rememberUpdatedState(bounceableInfo)
@@ -163,12 +166,20 @@
                 .takeIf { uiState.handlesLongClick }
         TileContainer(
             onClick = {
-                tile.onClick(expandable)
-                hapticsViewModel?.setTileInteractionState(
-                    TileHapticsViewModel.TileInteractionState.CLICKED
-                )
-                if (uiState.accessibilityUiState.toggleableState != null) {
-                    coroutineScope.launch { currentBounceableInfo.bounceable.animateBounce() }
+                var hasDetails = false
+                if (QsDetailedView.isEnabled) {
+                    hasDetails = detailsViewModel?.onTileClicked(tile.spec) == true
+                }
+                if (!hasDetails) {
+                    // For those tile's who doesn't have a detailed view, process with their
+                    // `onClick` behavior.
+                    tile.onClick(expandable)
+                    hapticsViewModel?.setTileInteractionState(
+                        TileHapticsViewModel.TileInteractionState.CLICKED
+                    )
+                    if (uiState.accessibilityUiState.toggleableState != null) {
+                        coroutineScope.launch { currentBounceableInfo.bounceable.animateBounce() }
+                    }
                 }
             },
             onLongClick = longClick,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt
index 1d36aee..c6c6dca 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt
@@ -27,11 +27,8 @@
 
 /** Creates the state of the current selected tile that is remembered across compositions. */
 @Composable
-fun rememberSelectionState(
-    onResize: (TileSpec) -> Unit,
-    onResizeEnd: (TileSpec) -> Unit,
-): MutableSelectionState {
-    return remember { MutableSelectionState(onResize, onResizeEnd) }
+fun rememberSelectionState(): MutableSelectionState {
+    return remember { MutableSelectionState() }
 }
 
 /**
@@ -41,47 +38,18 @@
 data class Selection(val tileSpec: TileSpec, val manual: Boolean)
 
 /** Holds the state of the current selection. */
-class MutableSelectionState(
-    val onResize: (TileSpec) -> Unit,
-    private val onResizeEnd: (TileSpec) -> Unit,
-) {
+class MutableSelectionState {
     private var _selection = mutableStateOf<Selection?>(null)
-    private var _resizingState = mutableStateOf<ResizingState?>(null)
 
     /** The [Selection] if a tile is selected, null if not. */
     val selection by _selection
 
-    /** The [ResizingState] of the selected tile is currently being resized, null if not. */
-    val resizingState by _resizingState
-
     fun select(tileSpec: TileSpec, manual: Boolean) {
         _selection.value = Selection(tileSpec, manual)
     }
 
     fun unSelect() {
         _selection.value = null
-        onResizingDragEnd()
-    }
-
-    fun onResizingDrag(offset: Float) {
-        _resizingState.value?.onDrag(offset)
-    }
-
-    fun onResizingDragStart(tileWidths: TileWidths) {
-        _selection.value?.let {
-            _resizingState.value = ResizingState(tileWidths) { onResize(it.tileSpec) }
-        }
-    }
-
-    fun onResizingDragEnd() {
-        _resizingState.value = null
-        _selection.value?.let {
-            onResizeEnd(it.tileSpec)
-
-            // Mark the selection as automatic in case the tile ends up moving to a different
-            // row with its new size.
-            _selection.value = it.copy(manual = false)
-        }
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingState.kt
index 41c3de5..1113053 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingState.kt
@@ -16,56 +16,82 @@
 
 package com.android.systemui.qs.panels.ui.compose.selection
 
+import androidx.compose.foundation.gestures.AnchoredDraggableState
+import androidx.compose.foundation.gestures.DraggableAnchors
+import androidx.compose.foundation.gestures.animateTo
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableFloatStateOf
-import androidx.compose.runtime.mutableIntStateOf
-import androidx.compose.runtime.setValue
-import com.android.systemui.qs.panels.ui.compose.selection.ResizingDefaults.RESIZING_THRESHOLD
+import androidx.compose.runtime.remember
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.FinalResizeOperation
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.TemporaryResizeOperation
+import com.android.systemui.qs.pipeline.shared.TileSpec
 
-class ResizingState(val widths: TileWidths, private val onResize: () -> Unit) {
-    /** Total drag offset of this resize operation. */
-    private var totalOffset by mutableFloatStateOf(0f)
+@Composable
+fun rememberResizingState(tileSpec: TileSpec, startsAsIcon: Boolean): ResizingState {
+    return remember(tileSpec) { ResizingState(tileSpec, startsAsIcon) }
+}
 
-    /** Width in pixels of the resizing tile. */
-    var width by mutableIntStateOf(widths.base)
+enum class QSDragAnchor {
+    Icon,
+    Large,
+}
 
-    /** Progression between icon (0) and large (1) sizes. */
-    val progression
-        get() = calculateProgression()
+class ResizingState(tileSpec: TileSpec, startsAsIcon: Boolean) {
+    val anchoredDraggableState =
+        AnchoredDraggableState(if (startsAsIcon) QSDragAnchor.Icon else QSDragAnchor.Large)
 
-    // Whether the tile is currently over the threshold and should be a large tile
-    private var passedThreshold: Boolean = passedThreshold(progression)
+    val bounds by derivedStateOf {
+        anchoredDraggableState.anchors.minPosition().takeIf { !it.isNaN() } to
+            anchoredDraggableState.anchors.maxPosition().takeIf { !it.isNaN() }
+    }
 
-    fun onDrag(offset: Float) {
-        totalOffset += offset
-        width = (widths.base + totalOffset).toInt().coerceIn(widths.min, widths.max)
+    val temporaryResizeOperation by derivedStateOf {
+        TemporaryResizeOperation(
+            tileSpec,
+            toIcon = anchoredDraggableState.currentValue == QSDragAnchor.Icon,
+        )
+    }
 
-        passedThreshold(progression).let {
-            // Resize if we went over the threshold
-            if (passedThreshold != it) {
-                passedThreshold = it
-                onResize()
+    val finalResizeOperation by derivedStateOf {
+        FinalResizeOperation(
+            tileSpec,
+            toIcon = anchoredDraggableState.settledValue == QSDragAnchor.Icon,
+        )
+    }
+
+    fun updateAnchors(min: Float, max: Float) {
+        anchoredDraggableState.updateAnchors(
+            DraggableAnchors {
+                QSDragAnchor.Icon at min
+                QSDragAnchor.Large at max
             }
-        }
+        )
     }
 
-    private fun passedThreshold(progression: Float): Boolean {
-        return progression >= RESIZING_THRESHOLD
+    suspend fun updateCurrentValue(isIcon: Boolean) {
+        anchoredDraggableState.animateTo(if (isIcon) QSDragAnchor.Icon else QSDragAnchor.Large)
     }
 
-    /** The progression of the resizing tile between an icon tile (0f) and a large tile (1f) */
-    private fun calculateProgression(): Float {
-        return ((width - widths.min) / (widths.max - widths.min).toFloat()).coerceIn(0f, 1f)
+    suspend fun toggleCurrentValue() {
+        val isIcon = anchoredDraggableState.currentValue == QSDragAnchor.Icon
+        updateCurrentValue(!isIcon)
     }
-}
 
-/** Holds the width of a tile as well as its min and max widths */
-data class TileWidths(val base: Int, val min: Int, val max: Int) {
-    init {
-        check(max > min) { "The max width needs to be larger than the min width." }
+    fun progress(): Float = anchoredDraggableState.progress(QSDragAnchor.Icon, QSDragAnchor.Large)
+
+    /**
+     * Represents a resizing operation for a tile.
+     *
+     * @property spec The tile's [TileSpec]
+     * @property toIcon The new size for the tile.
+     */
+    sealed class ResizeOperation private constructor(val spec: TileSpec, val toIcon: Boolean) {
+        /** A temporary resizing operation, used while a resizing movement is in motion. */
+        class TemporaryResizeOperation(spec: TileSpec, toIcon: Boolean) :
+            ResizeOperation(spec, toIcon)
+
+        /** A final resizing operation, used while a resizing movement is done. */
+        class FinalResizeOperation(spec: TileSpec, toIcon: Boolean) : ResizeOperation(spec, toIcon)
     }
 }
-
-private object ResizingDefaults {
-    const val RESIZING_THRESHOLD = .25f
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
index 8a345ce..c1545e1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
@@ -19,10 +19,11 @@
 import androidx.compose.animation.core.Spring
 import androidx.compose.animation.core.animateDpAsState
 import androidx.compose.animation.core.animateFloatAsState
-import androidx.compose.animation.core.animateIntAsState
 import androidx.compose.animation.core.spring
 import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.gestures.detectHorizontalDragGestures
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.anchoredDraggable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.layout.size
@@ -30,7 +31,9 @@
 import androidx.compose.material3.LocalMinimumInteractiveComponentSize
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawWithContent
@@ -40,16 +43,16 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.SolidColor
 import androidx.compose.ui.graphics.drawscope.Stroke
-import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.layout
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.toSize
 import androidx.compose.ui.zIndex
-import com.android.compose.modifiers.thenIf
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.InactiveCornerRadius
 import com.android.systemui.qs.panels.ui.compose.selection.SelectionDefaults.ResizingDotSize
 import com.android.systemui.qs.panels.ui.compose.selection.SelectionDefaults.SelectedBorderWidth
+import kotlin.math.roundToInt
+import kotlinx.coroutines.launch
 
 /**
  * Places a dot to handle resizing drag events. Use this on tiles to resize.
@@ -58,31 +61,24 @@
  * selected.
  *
  * @param selected whether resizing drag events should be handled
- * @param selectionState the [MutableSelectionState] on the grid
+ * @param state the [ResizingState] for the tile
  * @param selectionAlpha the animated value for the dot and border alpha
  * @param selectionColor the [Color] of the dot and border
- * @param tileWidths the [TileWidths] of the selected tile
  */
 @Composable
 fun ResizableTileContainer(
     selected: Boolean,
-    selectionState: MutableSelectionState,
+    state: ResizingState,
     selectionAlpha: () -> Float,
     selectionColor: Color,
-    tileWidths: () -> TileWidths?,
     modifier: Modifier = Modifier,
     content: @Composable BoxScope.() -> Unit = {},
 ) {
-    Box(
-        modifier
-            .resizable(selected, selectionState, tileWidths)
-            .selectionBorder(selectionColor, selectionAlpha)
-    ) {
+    Box(modifier.resizable(selected, state).selectionBorder(selectionColor, selectionAlpha)) {
         content()
         ResizingHandle(
             enabled = selected,
-            selectionState = selectionState,
-            tileWidths = tileWidths,
+            state = state,
             modifier =
                 // Higher zIndex to make sure the handle is drawn above the content
                 Modifier.zIndex(2f),
@@ -91,15 +87,11 @@
 }
 
 @Composable
-private fun ResizingHandle(
-    enabled: Boolean,
-    selectionState: MutableSelectionState,
-    tileWidths: () -> TileWidths?,
-    modifier: Modifier = Modifier,
-) {
+private fun ResizingHandle(enabled: Boolean, state: ResizingState, modifier: Modifier = Modifier) {
     // Manually creating the touch target around the resizing dot to ensure that the next tile
     // does not receive the touch input accidentally.
     val minTouchTargetSize = LocalMinimumInteractiveComponentSize.current
+    val scope = rememberCoroutineScope()
     Box(
         modifier
             .layout { measurable, constraints ->
@@ -112,20 +104,14 @@
                     )
                 }
             }
-            .thenIf(enabled) {
-                Modifier.systemGestureExclusion { Rect(Offset.Zero, it.size.toSize()) }
-                    .pointerInput(Unit) {
-                        detectHorizontalDragGestures(
-                            onHorizontalDrag = { _, offset ->
-                                selectionState.onResizingDrag(offset)
-                            },
-                            onDragStart = {
-                                tileWidths()?.let { selectionState.onResizingDragStart(it) }
-                            },
-                            onDragEnd = selectionState::onResizingDragEnd,
-                            onDragCancel = selectionState::onResizingDragEnd,
-                        )
-                    }
+            .systemGestureExclusion { Rect(Offset.Zero, it.size.toSize()) }
+            .anchoredDraggable(
+                enabled = enabled,
+                state = state.anchoredDraggableState,
+                orientation = Orientation.Horizontal,
+            )
+            .clickable(enabled = enabled, interactionSource = null, indication = null) {
+                scope.launch { state.toggleCurrentValue() }
             }
     ) {
         ResizingDot(enabled = enabled, modifier = Modifier.align(Alignment.Center))
@@ -165,23 +151,15 @@
 }
 
 @Composable
-private fun Modifier.resizable(
-    selected: Boolean,
-    selectionState: MutableSelectionState,
-    tileWidths: () -> TileWidths?,
-): Modifier {
+private fun Modifier.resizable(selected: Boolean, state: ResizingState): Modifier {
     if (!selected) return zIndex(1f)
 
-    // Animated diff between the current width and the resized width of the tile. We can't use
-    // animateContentSize here as the tile is sometimes unbounded.
-    val remainingOffset by
-        animateIntAsState(
-            selectionState.resizingState?.let { tileWidths()?.base?.minus(it.width) ?: 0 } ?: 0,
-            label = "QSEditTileWidthOffset",
-        )
     return zIndex(2f).layout { measurable, constraints ->
+        val isIdle by derivedStateOf { state.progress().let { it == 0f || it == 1f } }
         // Grab the width from the resizing state if a resize is in progress
-        val width = selectionState.resizingState?.width ?: (constraints.maxWidth - remainingOffset)
+        val width =
+            state.anchoredDraggableState.requireOffset().roundToInt().takeIf { !isIdle }
+                ?: constraints.maxWidth
         val placeable = measurable.measure(constraints.copy(minWidth = width, maxWidth = width))
         layout(constraints.maxWidth, placeable.height) { placeable.place(0, 0) }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt
new file mode 100644
index 0000000..d8361f5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.viewmodel
+
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.plugins.qs.TileDetailsViewModel
+import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+@SysUISingleton
+class DetailsViewModel
+@Inject constructor(val currentTilesInteractor: CurrentTilesInteractor) {
+
+    /**
+     * The current active [TileDetailsViewModel]. If it's `null`, it means the qs overlay is not
+     * showing any details view. It changes when [onTileClicked] and [closeDetailedView].
+     */
+    private val _activeTileDetails = mutableStateOf<TileDetailsViewModel?>(null)
+    val activeTileDetails by _activeTileDetails
+
+    /**
+     * Update the active [TileDetailsViewModel] to `null`.
+     * @see activeTileDetails
+     */
+    fun closeDetailedView() {
+        _activeTileDetails.value = null
+    }
+
+    /**
+     * Update the active [TileDetailsViewModel] to the `spec`'s corresponding view model.
+     * Return if the [TileDetailsViewModel] is successfully found.
+     * @see activeTileDetails
+     */
+    fun onTileClicked(spec: TileSpec?): Boolean {
+        if (spec == null) {
+            _activeTileDetails.value = null
+            return false
+        }
+
+        _activeTileDetails.value = currentTilesInteractor
+            .currentQSTiles
+            .firstOrNull { it.tileSpec == spec.spec }
+            ?.detailsViewModel
+
+        return _activeTileDetails.value != null
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.kt
new file mode 100644
index 0000000..b033473
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.classifier.domain.interactor.FalsingInteractor
+import com.android.systemui.plugins.FalsingManager
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+class EditModeButtonViewModel
+@AssistedInject
+constructor(
+    private val editModeViewModel: EditModeViewModel,
+    private val falsingInteractor: FalsingInteractor,
+) {
+
+    fun onButtonClick() {
+        if (!falsingInteractor.isFalseTap(FalsingManager.LOW_PENALTY)) {
+            editModeViewModel.startEditing()
+        }
+    }
+
+    @AssistedFactory
+    interface Factory {
+        fun create(): EditModeButtonViewModel
+    }
+}
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 bff330b..4a18872 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
@@ -17,6 +17,8 @@
 package com.android.systemui.qs.panels.ui.viewmodel
 
 import androidx.compose.runtime.getValue
+import com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE
+import com.android.systemui.classifier.domain.interactor.FalsingInteractor
 import com.android.systemui.development.ui.viewmodel.BuildNumberViewModel
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.Hydrator
@@ -36,6 +38,8 @@
     paginatedGridInteractor: PaginatedGridInteractor,
     inFirstPageViewModel: InFirstPageViewModel,
     val buildNumberViewModelFactory: BuildNumberViewModel.Factory,
+    val editModeButtonViewModelFactory: EditModeButtonViewModel.Factory,
+    private val falsingInteractor: FalsingInteractor,
 ) : IconTilesViewModel by iconTilesViewModel, ExclusiveActivatable() {
 
     private val hydrator = Hydrator("PaginatedGridViewModel")
@@ -53,6 +57,10 @@
     val columns: Int
         get() = columnsWithMediaViewModel.columns
 
+    fun registerSideSwipeGesture() {
+        falsingInteractor.isFalseTouch(QS_SWIPE_SIDE)
+    }
+
     override suspend fun onActivated(): Nothing {
         coroutineScope {
             launch { hydrator.activate() }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 18b1f07..b7ebce2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -27,6 +27,7 @@
 import android.graphics.Color
 import android.graphics.PorterDuff
 import android.graphics.Rect
+import android.graphics.Typeface
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.GradientDrawable
 import android.graphics.drawable.LayerDrawable
@@ -308,6 +309,14 @@
         }
         setLabelColor(getLabelColorForState(QSTile.State.DEFAULT_STATE))
         setSecondaryLabelColor(getSecondaryLabelColorForState(QSTile.State.DEFAULT_STATE))
+
+        if (Flags.gsfQuickSettings()) {
+            label.apply {
+                typeface = Typeface.create("gsf-title-small-emphasized", Typeface.NORMAL)
+            }
+            secondaryLabel.apply { typeface = Typeface.create("gsf-label-medium", Typeface.NORMAL) }
+        }
+
         addView(labelContainer)
     }
 
@@ -415,7 +424,10 @@
             initLongPressEffectCallback()
             init(
                 { _: View -> longPressEffect.onTileClick() },
-                { _: View -> true }, // Haptics and long-clicks are handled by [QSLongPressEffect]
+                { _: View ->
+                    longPressEffect.onTileLongClick()
+                    true
+                }, // Haptics and long-clicks are handled by [QSLongPressEffect]
             )
         } else {
             val expandable = Expandable.fromView(this)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
index 42ef0cd..7225800 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
@@ -28,11 +28,14 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.qs.TileDetailsViewModel
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QsDetailedView
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tiles.dialog.InternetDetailsViewModel
 import com.android.systemui.qs.tiles.dialog.InternetDialogManager
 import com.android.systemui.qs.tiles.dialog.WifiStateWorker
 import com.android.systemui.res.R
@@ -90,6 +93,9 @@
     }
 
     override fun handleClick(expandable: Expandable?) {
+        if (QsDetailedView.isEnabled) {
+            return
+        }
         mainHandler.post {
             internetDialogManager.create(
                 aboveStatusBar = true,
@@ -100,6 +106,10 @@
         }
     }
 
+    override fun getDetailsViewModel(): TileDetailsViewModel {
+        return InternetDetailsViewModel { longClick(null) }
+    }
+
     override fun secondaryClick(expandable: Expandable?) {
         // TODO(b/358352265): Figure out the correct action for the secondary click
         // Toggle wifi
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailedViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailedViewModel.kt
new file mode 100644
index 0000000..f239a17
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailedViewModel.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.dialog
+
+import android.view.LayoutInflater
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.viewinterop.AndroidView
+import com.android.systemui.plugins.qs.TileDetailsViewModel
+import com.android.systemui.res.R
+
+class InternetDetailsViewModel(
+    onLongClick: () -> Unit,
+) : TileDetailsViewModel() {
+    private val _onLongClick = onLongClick
+
+    @Composable
+    override fun GetContentView() {
+        AndroidView(
+            modifier = Modifier.fillMaxWidth().fillMaxHeight(),
+            factory = { context ->
+                // Inflate with the existing dialog xml layout
+                LayoutInflater.from(context)
+                    .inflate(R.layout.internet_connectivity_dialog, null)
+                // TODO: b/377388104 - Implement the internet details view
+            },
+        )
+    }
+
+    override fun clickOnSettingsButton() {
+        _onLongClick()
+    }
+
+    override fun getTitle(): String {
+        // TODO: b/377388104 Update the placeholder text
+        return "Internet"
+    }
+
+    override fun getSubTitle(): String {
+        // TODO: b/377388104 Update the placeholder text
+        return "Tab a network to connect"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt
index 8f870d4..4806c3f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt
@@ -18,7 +18,7 @@
 
 import android.os.UserHandle
 import android.service.quicksettings.Tile
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
 import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
@@ -28,6 +28,7 @@
 import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
 import com.android.systemui.qs.tiles.impl.di.QSTileScope
 import com.android.systemui.user.data.repository.UserRepository
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -44,7 +45,6 @@
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.shareIn
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 @QSTileScope
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -64,7 +64,7 @@
     private val bindingFlow =
         mutableUserFlow
             .flatMapLatest { user ->
-                ConflatedCallbackFlow.conflatedCallbackFlow {
+                conflatedCallbackFlow {
                     serviceInteractor.setUser(user)
 
                     // Wait for the CustomTileInteractor to become initialized first, because
@@ -79,7 +79,7 @@
                             defaultsRepository.requestNewDefaults(
                                 user,
                                 tileSpec.componentName,
-                                true
+                                true,
                             )
                         }
                         .launchIn(this)
@@ -99,7 +99,7 @@
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<CustomTileDataModel> {
         tileScope.launch { mutableUserFlow.emit(user) }
         return bindingFlow.combine(triggers) { _, _ -> }.flatMapLatest { dataFlow(user) }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
index ab3862b..f9a1ad5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon
@@ -35,14 +36,17 @@
 import dagger.assisted.AssistedInject
 import java.io.PrintWriter
 import java.util.concurrent.CopyOnWriteArraySet
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.collectIndexed
 import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.takeWhile
+import kotlinx.coroutines.launch
 
 // TODO(b/http://b/299909989): Use QSTileViewModel directly after the rollout
 class QSTileViewModelAdapter
@@ -51,6 +55,7 @@
     @Application private val applicationScope: CoroutineScope,
     private val qsHost: QSHost,
     @Assisted private val qsTileViewModel: QSTileViewModel,
+    @UiBackground private val uiBgDispatcher: CoroutineDispatcher,
 ) : QSTile, Dumpable {
 
     private val context
@@ -162,19 +167,25 @@
     override fun setListening(client: Any?, listening: Boolean) {
         client ?: return
         if (listening) {
-            val clientWasNotAlreadyListening = listeningClients.add(client)
-            if (clientWasNotAlreadyListening && listeningClients.size == 1) {
-                stateJob =
-                    qsTileViewModel.state
-                        .filterNotNull()
-                        .map { mapState(context, it, qsTileViewModel.config) }
-                        .onEach { legacyState ->
-                            val changed = legacyState.copyTo(cachedState)
-                            if (changed) {
-                                callbacks.forEach { it.onStateChanged(legacyState) }
+            applicationScope.launch(uiBgDispatcher) {
+                val shouldStartMappingJob =
+                    listeningClients.add(client) // new client
+                    && listeningClients.size == 1 // first client
+
+                if (shouldStartMappingJob) {
+                    stateJob =
+                        qsTileViewModel.state
+                            .filterNotNull()
+                            .map { mapState(context, it, qsTileViewModel.config) }
+                            .onEach { legacyState ->
+                                val changed = legacyState.copyTo(cachedState)
+                                if (changed) {
+                                    callbacks.forEach { it.onStateChanged(legacyState) }
+                                }
                             }
-                        }
-                        .launchIn(applicationScope)
+                            .flowOn(uiBgDispatcher)
+                            .launchIn(applicationScope)
+                }
             }
         } else {
             listeningClients.remove(client)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
index da175c9..62b1203 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
@@ -18,6 +18,7 @@
 
 import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
 import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.qs.panels.ui.viewmodel.DetailsViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
@@ -36,6 +37,7 @@
     @Assisted supportsBrightnessMirroring: Boolean,
     val tileGridViewModel: TileGridViewModel,
     val editModeViewModel: EditModeViewModel,
+    val detailsViewModel: DetailsViewModel,
 ) : ExclusiveActivatable() {
 
     val brightnessSliderViewModel =
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
index 02b2bb1..d94f00f 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
@@ -171,9 +171,16 @@
             }
         ALL_ISSUE_TYPES.keys.forEach {
             popupMenu.menu.add(it).apply {
+                // Set this for every item in the list to ensure equal spacing. Set it to
+                // transparent for non-selected items so icon is only visible for selected element.
                 setIcon(R.drawable.arrow_pointing_down)
                 if (it != state.issueTypeRes) {
                     iconTintList = ColorStateList.valueOf(Color.TRANSPARENT)
+                } else {
+                    contentDescription =
+                        context.getString(com.android.internal.R.string.selected) +
+                            " " +
+                            context.getString(it)
                 }
                 intent = Intent().putExtra(EXTRA_ISSUE_TYPE_RES, it)
 
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractor.kt
new file mode 100644
index 0000000..d7c3b6b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractor.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.scene.domain.interactor
+
+import com.android.compose.animation.scene.ContentKey
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
+import com.android.systemui.scene.shared.model.Overlays
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.statusbar.disableflags.domain.interactor.DisableFlagsInteractor
+import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+
+class DisabledContentInteractor
+@Inject
+constructor(private val disableFlagsInteractor: DisableFlagsInteractor) {
+
+    /** Returns `true` if the given [key] is disabled; `false` if it's enabled */
+    fun isDisabled(
+        key: ContentKey,
+        disabledFlags: DisableFlagsModel = disableFlagsInteractor.disableFlags.value,
+    ): Boolean {
+        return with(disabledFlags) {
+            when (key) {
+                Scenes.Shade,
+                Overlays.NotificationsShade -> !isShadeEnabled()
+                Scenes.QuickSettings,
+                Overlays.QuickSettingsShade -> !isQuickSettingsEnabled()
+                else -> false
+            }
+        }
+    }
+
+    /** Runs the given [block] each time that [key] becomes disabled. */
+    suspend fun repeatWhenDisabled(key: ContentKey, block: suspend (disabled: ContentKey) -> Unit) {
+        disableFlagsInteractor.disableFlags
+            .map { isDisabled(key) }
+            .distinctUntilChanged()
+            .collectLatest { isDisabled ->
+                if (isDisabled) {
+                    block(key)
+                }
+            }
+    }
+
+    /**
+     * Returns a filtered version of [unfiltered], without action-result entries that would navigate
+     * to disabled scenes.
+     */
+    fun filteredUserActions(
+        unfiltered: Flow<Map<UserAction, UserActionResult>>
+    ): Flow<Map<UserAction, UserActionResult>> {
+        return combine(disableFlagsInteractor.disableFlags, unfiltered) {
+            disabledFlags,
+            unfilteredMap ->
+            unfilteredMap.filterValues { actionResult ->
+                val destination =
+                    when (actionResult) {
+                        is UserActionResult.ChangeScene -> actionResult.toScene
+                        is UserActionResult.ShowOverlay -> actionResult.overlay
+                        is UserActionResult.ReplaceByOverlay -> actionResult.overlay
+                        else -> null
+                    }
+                if (destination != null) {
+                    // results that lead to a disabled destination get filtered out.
+                    !isDisabled(key = destination, disabledFlags = disabledFlags)
+                } else {
+                    // Action results that don't lead to a destination are never filtered out.
+                    true
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index f20e5a5..d83d74e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -21,6 +21,8 @@
 import com.android.compose.animation.scene.OverlayKey
 import com.android.compose.animation.scene.SceneKey
 import com.android.compose.animation.scene.TransitionKey
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
@@ -64,6 +66,7 @@
     private val sceneFamilyResolvers: Lazy<Map<SceneKey, @JvmSuppressWildcards SceneResolver>>,
     private val deviceUnlockedInteractor: Lazy<DeviceUnlockedInteractor>,
     private val keyguardEnabledInteractor: Lazy<KeyguardEnabledInteractor>,
+    private val disabledContentInteractor: DisabledContentInteractor,
 ) {
 
     interface OnSceneAboutToChangeListener {
@@ -465,6 +468,10 @@
             return false
         }
 
+        if (disabledContentInteractor.isDisabled(to)) {
+            return false
+        }
+
         val inMidTransitionFromGone =
             (transitionState.value as? ObservableTransitionState.Transition)?.fromContent ==
                 Scenes.Gone
@@ -503,6 +510,10 @@
                 " Logging reason for overlay change was: $loggingReason"
         }
 
+        if (to != null && disabledContentInteractor.isDisabled(to)) {
+            return false
+        }
+
         val isFromValid = (from == null) || (from in currentOverlays.value)
         val isToValid =
             (to == null) || (to !in currentOverlays.value && to in repository.allContentKeys)
@@ -517,4 +528,14 @@
     /** Returns `true` if [scene] can be resolved from [family]. */
     fun isSceneInFamily(scene: SceneKey, family: SceneKey): Boolean =
         sceneFamilyResolvers.get()[family]?.includesScene(scene) == true
+
+    /**
+     * Returns a filtered version of [unfiltered], without action-result entries that would navigate
+     * to disabled scenes.
+     */
+    fun filteredUserActions(
+        unfiltered: Flow<Map<UserAction, UserActionResult>>
+    ): Flow<Map<UserAction, UserActionResult>> {
+        return disabledContentInteractor.filteredUserActions(unfiltered)
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
index ba789a0..3a07ce9 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.scene.domain.interactor
 
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
@@ -29,9 +30,9 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.NotificationPresenter
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.init.NotificationsController
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import javax.inject.Inject
 import javax.inject.Provider
 import kotlinx.coroutines.CoroutineScope
@@ -44,7 +45,6 @@
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /** Business logic about the visibility of various parts of the window root view. */
 @OptIn(ExperimentalCoroutinesApi::class)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 066fe1b..8d8c24e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -19,7 +19,6 @@
 package com.android.systemui.scene.domain.startable
 
 import android.app.StatusBarManager
-import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.internal.logging.UiEventLogger
@@ -46,6 +45,7 @@
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor.Companion.keyguardScenes
 import com.android.systemui.model.SceneContainerPlugin
 import com.android.systemui.model.SysUiState
 import com.android.systemui.model.updateFlags
@@ -55,6 +55,7 @@
 import com.android.systemui.power.shared.model.WakeSleepReason
 import com.android.systemui.scene.data.model.asIterable
 import com.android.systemui.scene.data.model.sceneStackOf
+import com.android.systemui.scene.domain.interactor.DisabledContentInteractor
 import com.android.systemui.scene.domain.interactor.SceneBackInteractor
 import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.SceneInteractor
@@ -102,6 +103,7 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapNotNull
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
 
 /**
  * Hooks up business logic that manipulates the state of the [SceneInteractor] for the system UI
@@ -143,6 +145,7 @@
     private val alternateBouncerInteractor: AlternateBouncerInteractor,
     private val vibratorHelper: VibratorHelper,
     private val msdlPlayer: MSDLPlayer,
+    private val disabledContentInteractor: DisabledContentInteractor,
 ) : CoreStartable {
     private val centralSurfaces: CentralSurfaces?
         get() = centralSurfacesOptLazy.get().getOrNull()
@@ -280,6 +283,7 @@
         handlePowerState()
         handleDreamState()
         handleShadeTouchability()
+        handleDisableFlags()
     }
 
     private fun handleBouncerImeVisibility() {
@@ -352,14 +356,13 @@
                     val isAlternateBouncerVisible = alternateBouncerInteractor.isVisibleState()
                     val isOnPrimaryBouncer = renderedScenes.contains(Scenes.Bouncer)
                     if (!deviceUnlockStatus.isUnlocked) {
-                        return@mapNotNull if (isOnLockscreen || isOnPrimaryBouncer) {
-                            // Already on lockscreen or bouncer, no need to change scenes.
+                        return@mapNotNull if (renderedScenes.any { it in keyguardScenes }) {
+                            // Already on a keyguard scene, no need to change scenes.
                             null
                         } else {
-                            // The device locked while on a scene that's not Lockscreen or Bouncer,
-                            // go to Lockscreen.
-                            Scenes.Lockscreen to
-                                "device locked in non-Lockscreen and non-Bouncer scene"
+                            // The device locked while on a scene that's not a keyguard scene, go
+                            // to Lockscreen.
+                            Scenes.Lockscreen to "device locked in a non-keyguard scene"
                         }
                     }
 
@@ -565,6 +568,38 @@
         }
     }
 
+    private fun handleDisableFlags() {
+        applicationScope.launch {
+            launch {
+                sceneInteractor.currentScene.collectLatest { currentScene ->
+                    disabledContentInteractor.repeatWhenDisabled(currentScene) {
+                        switchToScene(
+                            targetSceneKey = SceneFamilies.Home,
+                            loggingReason =
+                                "Current scene ${currentScene.debugName} became" + " disabled",
+                        )
+                    }
+                }
+            }
+
+            launch {
+                sceneInteractor.currentOverlays.collectLatest { overlays ->
+                    overlays.forEach { overlay ->
+                        launch {
+                            disabledContentInteractor.repeatWhenDisabled(overlay) {
+                                sceneInteractor.hideOverlay(
+                                    overlay = overlay,
+                                    loggingReason =
+                                        "Overlay ${overlay.debugName} became" + " disabled",
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     private fun handleDeviceEntryHapticsWhileDeviceLocked() {
         applicationScope.launch {
             deviceEntryInteractor.isDeviceEntered.collectLatest { isDeviceEntered ->
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
index 32d5cb4..c1e8032 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
@@ -280,6 +280,16 @@
         }
     }
 
+    /**
+     * Returns a filtered version of [unfiltered], without action-result entries that would navigate
+     * to disabled scenes.
+     */
+    fun filteredUserActions(
+        unfiltered: Flow<Map<UserAction, UserActionResult>>
+    ): Flow<Map<UserAction, UserActionResult>> {
+        return sceneInteractor.filteredUserActions(unfiltered)
+    }
+
     /** Defines interface for classes that can handle externally-reported [MotionEvent]s. */
     interface MotionEventHandler {
         /** Notifies that a [MotionEvent] has occurred. */
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 49ceba8..31780a5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -37,9 +37,11 @@
 import androidx.lifecycle.LifecycleRegistry
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.compose.theme.PlatformTheme
 import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.Flags
+import com.android.systemui.Flags.communalHubOnMobile
 import com.android.systemui.ambient.touch.TouchMonitor
 import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
 import com.android.systemui.communal.dagger.Communal
@@ -70,7 +72,6 @@
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /**
  * Controller that's responsible for the glanceable hub container view and its touch handling.
@@ -513,14 +514,19 @@
         val touchOnUmo = keyguardMediaController.isWithinMediaViewBounds(ev.x.toInt(), ev.y.toInt())
         val touchOnSmartspace =
             lockscreenSmartspaceController.isWithinSmartspaceBounds(ev.x.toInt(), ev.y.toInt())
-        if (!hubShowing && (touchOnNotifications || touchOnUmo || touchOnSmartspace)) {
+        val glanceableHubV2 = communalHubOnMobile()
+        if (
+            !hubShowing &&
+                (touchOnNotifications || touchOnUmo || touchOnSmartspace || glanceableHubV2)
+        ) {
             logger.d({
                 "Lockscreen touch ignored: touchOnNotifications: $bool1, touchOnUmo: $bool2, " +
-                    "touchOnSmartspace: $bool3"
+                    "touchOnSmartspace: $bool3, glanceableHubV2: $bool4"
             }) {
                 bool1 = touchOnNotifications
                 bool2 = touchOnUmo
                 bool3 = touchOnSmartspace
+                bool4 = glanceableHubV2
             }
             return false
         }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 4ccd2b9..88522d5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -186,13 +186,15 @@
 import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.ConversationNotificationManager;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
 import com.android.systemui.statusbar.notification.ViewGroupFadeHelper;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor;
 import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -217,17 +219,15 @@
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.ShadeTouchableRegionManager;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
 import com.android.systemui.statusbar.phone.TapAgainViewController;
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.policy.SplitShadeStateController;
 import com.android.systemui.unfold.SysUIUnfoldComponent;
 import com.android.systemui.util.Compile;
@@ -298,7 +298,7 @@
      * The minimum scale to "squish" the Shade and associated elements down to, for Back gesture
      */
     public static final float SHADE_BACK_ANIM_MIN_SCALE = 0.9f;
-    private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    private final ShadeTouchableRegionManager mShadeTouchableRegionManager;
     private final Resources mResources;
     private final KeyguardStateController mKeyguardStateController;
     private final SysuiStatusBarStateController mStatusBarStateController;
@@ -695,7 +695,7 @@
             ShadeLogger shadeLogger,
             @ShadeDisplayAware ConfigurationController configurationController,
             Provider<FlingAnimationUtils.Builder> flingAnimationUtilsBuilder,
-            StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+            ShadeTouchableRegionManager shadeTouchableRegionManager,
             ConversationNotificationManager conversationNotificationManager,
             MediaHierarchyManager mediaHierarchyManager,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@@ -840,7 +840,7 @@
         mVibratorHelper = vibratorHelper;
         mMSDLPlayer = msdlPlayer;
         mVibrateOnOpening = mResources.getBoolean(R.bool.config_vibrateOnIconAnimation);
-        mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
+        mShadeTouchableRegionManager = shadeTouchableRegionManager;
         mSystemClock = systemClock;
         mKeyguardMediaController = keyguardMediaController;
         mMetricsLogger = metricsLogger;
@@ -1551,7 +1551,7 @@
 
     private Rect calculateGestureExclusionRect() {
         Rect exclusionRect = null;
-        Region touchableRegion = mStatusBarTouchableRegionManager.calculateTouchableRegion();
+        Region touchableRegion = mShadeTouchableRegionManager.calculateTouchableRegion();
         if (isFullyCollapsed() && touchableRegion != null) {
             // Note: The manager also calculates the non-pinned touchable region
             exclusionRect = touchableRegion.getBounds();
@@ -3109,17 +3109,20 @@
         if (isTracking()) {
             onTrackingStopped(true);
         }
-        if (isExpanded() && mBarState != KEYGUARD && !mQsController.getExpanded()) {
-            mShadeLog.d("Status Bar was long pressed. Expanding to QS.");
-            expandToQs();
-        } else {
-            if (mBarState == KEYGUARD) {
-                mShadeLog.d("Lockscreen Status Bar was long pressed. Expanding to Notifications.");
-                mLockscreenShadeTransitionController.goToLockedShade(
-                        /* expandedView= */null, /* needsQSAnimation= */false);
+        if (!mQsController.getExpanded()) {
+            performHapticFeedback(HapticFeedbackConstants.GESTURE_START);
+            if (isExpanded() && mBarState != KEYGUARD) {
+                mShadeLog.d("Status Bar was long pressed. Expanding to QS.");
+                mQsController.flingQs(0, FLING_EXPAND);
             } else {
-                mShadeLog.d("Status Bar was long pressed. Expanding to Notifications.");
-                expandToNotifications();
+                if (mBarState == KEYGUARD) {
+                    mShadeLog.d("Lockscreen Status Bar was long pressed. Expanding to Notifications.");
+                    mLockscreenShadeTransitionController.goToLockedShade(
+                            /* expandedView= */null, /* needsQSAnimation= */true);
+                } else {
+                    mShadeLog.d("Status Bar was long pressed. Expanding to Notifications.");
+                    expandToNotifications();
+                }
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
index 830649b..0df2299 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
@@ -98,7 +98,7 @@
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.phone.ShadeTouchableRegionManager;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.SplitShadeStateController;
@@ -114,6 +114,7 @@
 import java.io.PrintWriter;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
 
 /** Handles QuickSettings touch handling, expansion and animation state
  * TODO (b/264460656) make this dumpable
@@ -140,7 +141,8 @@
     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
     private final NotificationShadeDepthController mDepthController;
     private final ShadeHeaderController mShadeHeaderController;
-    private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    private final ShadeTouchableRegionManager mShadeTouchableRegionManager;
+    private final Provider<StatusBarLongPressGestureDetector> mStatusBarLongPressGestureDetector;
     private final KeyguardStateController mKeyguardStateController;
     private final KeyguardBypassController mKeyguardBypassController;
     private final NotificationRemoteInputManager mRemoteInputManager;
@@ -315,7 +317,8 @@
             LockscreenShadeTransitionController lockscreenShadeTransitionController,
             NotificationShadeDepthController notificationShadeDepthController,
             ShadeHeaderController shadeHeaderController,
-            StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+            ShadeTouchableRegionManager shadeTouchableRegionManager,
+            Provider<StatusBarLongPressGestureDetector> statusBarLongPressGestureDetector,
             KeyguardStateController keyguardStateController,
             KeyguardBypassController keyguardBypassController,
             ScrimController scrimController,
@@ -363,7 +366,8 @@
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         mDepthController = notificationShadeDepthController;
         mShadeHeaderController = shadeHeaderController;
-        mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
+        mShadeTouchableRegionManager = shadeTouchableRegionManager;
+        mStatusBarLongPressGestureDetector = statusBarLongPressGestureDetector;
         mKeyguardStateController = keyguardStateController;
         mKeyguardBypassController = keyguardBypassController;
         mScrimController = scrimController;
@@ -691,7 +695,7 @@
                 /* right= */ (int) mQsFrame.getX() + mQsFrame.getWidth(),
                 /* bottom= */ headerBottom + frameTop);
         // Also allow QS to intercept if the touch is near the notch.
-        mStatusBarTouchableRegionManager.updateRegionForNotch(mInterceptRegion);
+        mShadeTouchableRegionManager.updateRegionForNotch(mInterceptRegion);
         final boolean onHeader = mInterceptRegion.contains((int) x, (int) y);
 
         if (getExpanded()) {
@@ -1648,6 +1652,10 @@
         if (isSplitShadeAndTouchXOutsideQs(event.getX())) {
             return false;
         }
+        boolean isInStatusBar = event.getY(event.getActionIndex()) < mStatusBarMinHeight;
+        if (ShadeExpandsOnStatusBarLongPress.isEnabled() && isInStatusBar) {
+            mStatusBarLongPressGestureDetector.get().handleTouch(event);
+        }
         final int action = event.getActionMasked();
         boolean collapsedQs = !getExpanded() && !mSplitShadeEnabled;
         boolean expandedShadeCollapsedQs = mShadeExpandedFraction == 1f
@@ -1684,9 +1692,7 @@
         if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed && isExpansionEnabled()) {
             mTwoFingerExpandPossible = true;
         }
-        if (mTwoFingerExpandPossible && isOpenQsEvent(event)
-                && event.getY(event.getActionIndex())
-                < mStatusBarMinHeight) {
+        if (mTwoFingerExpandPossible && isOpenQsEvent(event) && isInStatusBar) {
             mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1);
             setExpandImmediate(true);
             mNotificationStackScrollLayoutController.setShouldShowShelfOnly(!mSplitShadeEnabled);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAware.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAware.kt
index 111d335..e8cdf836 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAware.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAware.kt
@@ -29,5 +29,13 @@
  * `ConfigurationController`) will be dynamically updated to reflect the current display's
  * configuration. This ensures consistent rendering even when the shade window is moved to an
  * external display.
+ *
+ * Note that in SystemUI, Currently, the shade window includes the lockscreen, quick settings, the
+ * notification stack, AOD, Bouncer, Glancable hub, and potentially other components that have been
+ * introduced after this comment is written.
+ *
+ * TODO: b/378016985 - The usage of this annotation in the relevant packages will be enforced by a
+ *   presubmit linter that will highlight instances of the global instances used in shade window
+ *   classes.
  */
 @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class ShadeDisplayAware
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
index 4f73a345..91ca2ca 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
@@ -19,7 +19,8 @@
 import android.content.Context
 import android.content.res.Resources
 import android.view.LayoutInflater
-import android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
+import android.view.WindowManager
+import android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE
 import com.android.systemui.CoreStartable
 import com.android.systemui.common.ui.ConfigurationState
 import com.android.systemui.common.ui.ConfigurationStateImpl
@@ -30,16 +31,22 @@
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorImpl
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.res.R
+import com.android.systemui.scene.ui.view.WindowRootView
+import com.android.systemui.shade.data.repository.MutableShadeDisplaysRepository
 import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
 import com.android.systemui.shade.data.repository.ShadeDisplaysRepositoryImpl
+import com.android.systemui.shade.display.ShadeDisplayPolicyModule
+import com.android.systemui.shade.domain.interactor.ShadeDisplaysInteractor
 import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
 import com.android.systemui.statusbar.phone.ConfigurationForwarder
 import com.android.systemui.statusbar.policy.ConfigurationController
+import dagger.BindsOptionalOf
 import dagger.Module
 import dagger.Provides
 import dagger.multibindings.ClassKey
 import dagger.multibindings.IntoMap
+import javax.inject.Provider
 
 /**
  * Module responsible for managing display-specific components and resources for the notification
@@ -53,7 +60,7 @@
  * 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
+@Module(includes = [OptionalShadeDisplayAwareBindings::class, ShadeDisplayPolicyModule::class])
 object ShadeDisplayAwareModule {
 
     /** Creates a new context for the shade window. */
@@ -63,7 +70,7 @@
     fun provideShadeDisplayAwareContext(context: Context): Context {
         return if (ShadeWindowGoesAround.isEnabled) {
             context
-                .createWindowContext(context.display, TYPE_APPLICATION_OVERLAY, /* options= */ null)
+                .createWindowContext(context.display, TYPE_NOTIFICATION_SHADE, /* options= */ null)
                 .apply { setTheme(R.style.Theme_SystemUI) }
         } else {
             context
@@ -73,6 +80,20 @@
     @Provides
     @ShadeDisplayAware
     @SysUISingleton
+    fun provideShadeWindowManager(
+        defaultWindowManager: WindowManager,
+        @ShadeDisplayAware context: Context,
+    ): WindowManager {
+        return if (ShadeWindowGoesAround.isEnabled) {
+            context.getSystemService(WindowManager::class.java) as WindowManager
+        } else {
+            defaultWindowManager
+        }
+    }
+
+    @Provides
+    @ShadeDisplayAware
+    @SysUISingleton
     fun provideShadeDisplayAwareResources(@ShadeDisplayAware context: Context): Resources {
         return context.resources
     }
@@ -162,6 +183,15 @@
         return impl
     }
 
+    @SysUISingleton
+    @Provides
+    fun provideMutableShadePositionRepository(
+        impl: ShadeDisplaysRepositoryImpl
+    ): MutableShadeDisplaysRepository {
+        ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
+        return impl
+    }
+
     @Provides
     @IntoMap
     @ClassKey(ShadePrimaryDisplayCommand::class)
@@ -172,4 +202,20 @@
             CoreStartable.NOP
         }
     }
+
+    @Provides
+    @IntoMap
+    @ClassKey(ShadeDisplaysInteractor::class)
+    fun provideShadeDisplaysInteractor(impl: Provider<ShadeDisplaysInteractor>): CoreStartable {
+        return if (ShadeWindowGoesAround.isEnabled) {
+            impl.get()
+        } else {
+            CoreStartable.NOP
+        }
+    }
+}
+
+@Module
+internal interface OptionalShadeDisplayAwareBindings {
+    @BindsOptionalOf fun bindOptionalOfWindowRootView(): WindowRootView
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt
index a5d9e96..a54f6b9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt
@@ -20,11 +20,14 @@
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.display.data.repository.DisplayRepository
-import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
+import com.android.systemui.shade.data.repository.MutableShadeDisplaysRepository
+import com.android.systemui.shade.display.ShadeDisplayPolicy
+import com.android.systemui.shade.display.SpecificDisplayIdPolicy
 import com.android.systemui.statusbar.commandline.Command
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import java.io.PrintWriter
 import javax.inject.Inject
+import kotlin.text.toIntOrNull
 
 @SysUISingleton
 class ShadePrimaryDisplayCommand
@@ -32,7 +35,9 @@
 constructor(
     private val commandRegistry: CommandRegistry,
     private val displaysRepository: DisplayRepository,
-    private val positionRepository: ShadeDisplaysRepository,
+    private val positionRepository: MutableShadeDisplaysRepository,
+    private val policies: Set<@JvmSuppressWildcards ShadeDisplayPolicy>,
+    private val defaultPolicy: ShadeDisplayPolicy,
 ) : Command, CoreStartable {
 
     override fun start() {
@@ -40,8 +45,11 @@
     }
 
     override fun help(pw: PrintWriter) {
-        pw.println("shade_display_override <displayId> ")
-        pw.println("Set the display which is holding the shade.")
+        pw.println("shade_display_override (<displayId>|<policyName>) ")
+        pw.println("Set the display which is holding the shade, or the policy that defines it.")
+        pw.println()
+        pw.println("shade_display_override policies")
+        pw.println("Lists available policies")
         pw.println()
         pw.println("shade_display_override reset ")
         pw.println("Reset the display which is holding the shade.")
@@ -68,21 +76,27 @@
                 "reset" -> reset()
                 "list",
                 "status" -> printStatus()
+                "policies" -> printPolicies()
                 "any_external" -> anyExternal()
-                else -> {
-                    val cmdAsInteger = command?.toIntOrNull()
-                    if (cmdAsInteger != null) {
-                        changeDisplay(displayId = cmdAsInteger)
-                    } else {
-                        help(pw)
-                    }
+                null -> help(pw)
+                else -> parsePolicy(command)
+            }
+        }
+
+        private fun parsePolicy(policyIdentifier: String) {
+            val displayId = policyIdentifier.toIntOrNull()
+            when {
+                displayId != null -> changeDisplay(displayId = displayId)
+                policies.any { it.name == policyIdentifier } -> {
+                    positionRepository.policy.value = policies.first { it.name == policyIdentifier }
                 }
+                else -> help(pw)
             }
         }
 
         private fun reset() {
-            positionRepository.resetDisplayId()
-            pw.println("Reset shade primary display id to ${Display.DEFAULT_DISPLAY}")
+            positionRepository.policy.value = defaultPolicy
+            pw.println("Reset shade display policy to default policy: ${defaultPolicy.name}")
         }
 
         private fun printStatus() {
@@ -95,6 +109,15 @@
             }
         }
 
+        private fun printPolicies() {
+            val currentPolicyName = positionRepository.policy.value.name
+            pw.println("Available policies: ")
+            policies.forEach {
+                pw.print(" - ${it.name}")
+                pw.println(if (currentPolicyName == it.name) " (Current policy)" else "")
+            }
+        }
+
         private fun anyExternal() {
             val anyExternalDisplay =
                 displaysRepository.displays.value.firstOrNull {
@@ -116,7 +139,7 @@
         }
 
         private fun setDisplay(id: Int) {
-            positionRepository.setDisplayId(id)
+            positionRepository.policy.value = SpecificDisplayIdPolicy(id)
             pw.println("New shade primary display id is $id")
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt
index 7346a28..9ca23f0 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt
@@ -19,8 +19,8 @@
 import com.android.systemui.shade.domain.interactor.ShadeBackActionInteractor
 import com.android.systemui.shade.domain.interactor.ShadeLockscreenInteractor
 import com.android.systemui.statusbar.GestureRecorder
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.phone.CentralSurfaces
-import com.android.systemui.statusbar.policy.HeadsUpManager
 
 /**
  * Allows CentralSurfacesImpl to interact with the shade. Only CentralSurfacesImpl should reference
@@ -37,7 +37,7 @@
         centralSurfaces: CentralSurfaces,
         recorder: GestureRecorder,
         hideExpandedRunnable: Runnable,
-        headsUpManager: HeadsUpManager
+        headsUpManager: HeadsUpManager,
     )
 
     /** Cancels any pending collapses. */
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurfaceImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurfaceImpl.kt
index ec4018c..3bbda16 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurfaceImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurfaceImpl.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.shade
 
 import com.android.systemui.statusbar.GestureRecorder
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.phone.CentralSurfaces
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import javax.inject.Inject
 
 class ShadeSurfaceImpl @Inject constructor() : ShadeSurface, ShadeViewControllerEmptyImpl() {
@@ -26,7 +26,7 @@
         centralSurfaces: CentralSurfaces,
         recorder: GestureRecorder,
         hideExpandedRunnable: Runnable,
-        headsUpManager: HeadsUpManager
+        headsUpManager: HeadsUpManager,
     ) {}
 
     override fun cancelPendingCollapse() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadeDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadeDisplayRepository.kt
index 71c5658..732d4d1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadeDisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadeDisplayRepository.kt
@@ -23,14 +23,14 @@
 class FakeShadeDisplayRepository : ShadeDisplaysRepository {
     private val _displayId = MutableStateFlow(Display.DEFAULT_DISPLAY)
 
-    override fun setDisplayId(displayId: Int) {
+    fun setDisplayId(displayId: Int) {
         _displayId.value = displayId
     }
 
     override val displayId: StateFlow<Int>
         get() = _displayId
 
-    override fun resetDisplayId() {
+    fun resetDisplayId() {
         _displayId.value = Display.DEFAULT_DISPLAY
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
index 4a95e33..756241e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
@@ -18,37 +18,40 @@
 
 import android.view.Display
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.shade.display.ShadeDisplayPolicy
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.stateIn
 
+/** Source of truth for the display currently holding the shade. */
 interface ShadeDisplaysRepository {
     /** ID of the display which currently hosts the shade */
     val displayId: StateFlow<Int>
-
-    /**
-     * Updates the value of the shade display id stored, emitting to the new display id to every
-     * component dependent on the shade display id
-     */
-    fun setDisplayId(displayId: Int)
-
-    /** Resets value of shade primary display to the default display */
-    fun resetDisplayId()
 }
 
-/** Source of truth for the display currently holding the shade. */
+/** Allows to change the policy that determines in which display the Shade window is visible. */
+interface MutableShadeDisplaysRepository : ShadeDisplaysRepository {
+    /** Updates the policy to select where the shade is visible. */
+    val policy: MutableStateFlow<ShadeDisplayPolicy>
+}
+
+/** Keeps the policy and propagates the display id for the shade from it. */
 @SysUISingleton
-class ShadeDisplaysRepositoryImpl @Inject constructor() : ShadeDisplaysRepository {
-    private val _displayId = MutableStateFlow(Display.DEFAULT_DISPLAY)
+@OptIn(ExperimentalCoroutinesApi::class)
+class ShadeDisplaysRepositoryImpl
+@Inject
+constructor(defaultPolicy: ShadeDisplayPolicy, @Background bgScope: CoroutineScope) :
+    MutableShadeDisplaysRepository {
+    override val policy = MutableStateFlow<ShadeDisplayPolicy>(defaultPolicy)
 
-    override val displayId: StateFlow<Int>
-        get() = _displayId
-
-    override fun setDisplayId(displayId: Int) {
-        _displayId.value = displayId
-    }
-
-    override fun resetDisplayId() {
-        _displayId.value = Display.DEFAULT_DISPLAY
-    }
+    override val displayId: StateFlow<Int> =
+        policy
+            .flatMapLatest { it.displayId }
+            .stateIn(bgScope, SharingStarted.WhileSubscribed(), Display.DEFAULT_DISPLAY)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/display/AnyExternalShadeDisplayPolicy.kt b/packages/SystemUI/src/com/android/systemui/shade/display/AnyExternalShadeDisplayPolicy.kt
new file mode 100644
index 0000000..3f6c949
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/display/AnyExternalShadeDisplayPolicy.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.shade.display
+
+import android.view.Display
+import android.view.Display.DEFAULT_DISPLAY
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.display.data.repository.DisplayRepository
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * Returns an external display if one exists, otherwise the default display.
+ *
+ * If there are multiple external displays, the one with minimum display ID is returned.
+ */
+@SysUISingleton
+class AnyExternalShadeDisplayPolicy
+@Inject
+constructor(displayRepository: DisplayRepository, @Background bgScope: CoroutineScope) :
+    ShadeDisplayPolicy {
+    override val name: String
+        get() = "any_external_display"
+
+    override val displayId: StateFlow<Int> =
+        displayRepository.displays
+            .map { displays ->
+                displays
+                    .filter { it.displayId != DEFAULT_DISPLAY && it.type in ALLOWED_DISPLAY_TYPES }
+                    .minOfOrNull { it.displayId } ?: DEFAULT_DISPLAY
+            }
+            .stateIn(bgScope, SharingStarted.WhileSubscribed(), DEFAULT_DISPLAY)
+
+    private companion object {
+        val ALLOWED_DISPLAY_TYPES =
+            setOf(Display.TYPE_EXTERNAL, Display.TYPE_OVERLAY, Display.TYPE_WIFI)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/display/ShadeDisplayPolicy.kt b/packages/SystemUI/src/com/android/systemui/shade/display/ShadeDisplayPolicy.kt
new file mode 100644
index 0000000..1b22ee4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/display/ShadeDisplayPolicy.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade.display
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoSet
+import kotlinx.coroutines.flow.StateFlow
+
+/** Describes the display the shade should be shown in. */
+interface ShadeDisplayPolicy {
+    val name: String
+
+    /** The display id the shade should be at, according to this policy. */
+    val displayId: StateFlow<Int>
+}
+
+@Module
+interface ShadeDisplayPolicyModule {
+    @IntoSet
+    @Binds
+    fun provideDefaultPolicyToSet(impl: DefaultShadeDisplayPolicy): ShadeDisplayPolicy
+
+    @IntoSet
+    @Binds
+    fun provideAnyExternalShadeDisplayPolicyToSet(
+        impl: AnyExternalShadeDisplayPolicy
+    ): ShadeDisplayPolicy
+
+    @Binds fun provideDefaultPolicy(impl: DefaultShadeDisplayPolicy): ShadeDisplayPolicy
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/display/SpecificDisplayIdPolicy.kt b/packages/SystemUI/src/com/android/systemui/shade/display/SpecificDisplayIdPolicy.kt
new file mode 100644
index 0000000..13e7664
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/display/SpecificDisplayIdPolicy.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.shade.display
+
+import android.view.Display
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+/** Policy to specify a display id explicitly. */
+open class SpecificDisplayIdPolicy(displayId: Int) : ShadeDisplayPolicy {
+    override val name: String
+        get() = "display_${displayId}_policy"
+
+    override val displayId: StateFlow<Int> = MutableStateFlow(displayId)
+}
+
+class DefaultShadeDisplayPolicy @Inject constructor() :
+    SpecificDisplayIdPolicy(Display.DEFAULT_DISPLAY)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
index 1055dcb..fb2cbec 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
@@ -18,21 +18,21 @@
 
 import android.content.Context
 import android.util.Log
-import android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE
+import android.view.WindowManager
+import androidx.annotation.UiThread
 import com.android.app.tracing.coroutines.launchTraced
 import com.android.app.tracing.traceSection
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
-import com.android.systemui.display.shared.model.DisplayWindowProperties
 import com.android.systemui.scene.ui.view.WindowRootView
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.shade.ShadeWindowLayoutParams
 import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
 import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
-import com.android.systemui.statusbar.phone.ConfigurationForwarder
+import com.android.systemui.util.kotlin.getOrNull
+import java.util.Optional
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
@@ -43,15 +43,27 @@
 class ShadeDisplaysInteractor
 @Inject
 constructor(
-    private val shadeRootView: WindowRootView,
+    optionalShadeRootView: Optional<WindowRootView>,
     private val shadePositionRepository: ShadeDisplaysRepository,
     @ShadeDisplayAware private val shadeContext: Context,
-    private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
+    @ShadeDisplayAware private val wm: WindowManager,
     @Background private val bgScope: CoroutineScope,
-    @ShadeDisplayAware private val configurationForwarder: ConfigurationForwarder,
-    @Main private val mainContext: CoroutineContext,
+    @Main private val mainThreadContext: CoroutineContext,
 ) : CoreStartable {
 
+    private val shadeLayoutParams: WindowManager.LayoutParams =
+        ShadeWindowLayoutParams.create(shadeContext)
+
+    private val shadeRootView =
+        optionalShadeRootView.getOrNull()
+            ?: error(
+                """
+            ShadeRootView must be provided for this ShadeDisplayInteractor to work.
+            If it is not, it means this is being instantiated in a SystemUI variant that shouldn't.
+            """
+                    .trimIndent()
+            )
+
     override fun start() {
         ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
         bgScope.launchTraced(TAG) {
@@ -60,51 +72,52 @@
     }
 
     /** Tries to move the shade. If anything wrong happens, fails gracefully without crashing. */
-    private suspend fun moveShadeWindowTo(destinationDisplayId: Int) {
-        val currentId = shadeRootView.display.displayId
-        if (currentId == destinationDisplayId) {
+    private suspend fun moveShadeWindowTo(destinationId: Int) {
+        Log.d(TAG, "Trying to move shade window to display with id $destinationId")
+        val currentDisplay = shadeRootView.display
+        if (currentDisplay == null) {
+            Log.w(TAG, "Current shade display is null")
+            return
+        }
+        val currentId = currentDisplay.displayId
+        if (currentId == destinationId) {
             Log.w(TAG, "Trying to move the shade to a display it was already in")
             return
         }
         try {
-            moveShadeWindow(fromId = currentId, toId = destinationDisplayId)
+            withContext(mainThreadContext) { moveShadeWindow(toId = destinationId) }
         } catch (e: IllegalStateException) {
             Log.e(
                 TAG,
-                "Unable to move the shade window from display $currentId to $destinationDisplayId",
+                "Unable to move the shade window from display $currentId to $destinationId",
                 e,
             )
         }
     }
 
-    private suspend fun moveShadeWindow(fromId: Int, toId: Int) {
-        val sourceProperties = getDisplayWindowProperties(fromId)
-        val destinationProperties = getDisplayWindowProperties(toId)
-        traceSection({ "MovingShadeWindow from $fromId to $toId" }) {
-            withContext(mainContext) {
-                traceSection("removeView") {
-                    sourceProperties.windowManager.removeView(shadeRootView)
-                }
-                traceSection("addView") {
-                    destinationProperties.windowManager.addView(
-                        shadeRootView,
-                        ShadeWindowLayoutParams.create(shadeContext),
-                    )
-                }
-            }
-        }
-        traceSection("SecondaryShadeInteractor#onConfigurationChanged") {
-            configurationForwarder.onConfigurationChanged(
-                destinationProperties.context.resources.configuration
-            )
+    @UiThread
+    private fun moveShadeWindow(toId: Int) {
+        traceSection({ "moveShadeWindow  to $toId" }) {
+            removeShadeWindow()
+            updateContextDisplay(toId)
+            addShadeWindow()
         }
     }
 
-    private fun getDisplayWindowProperties(displayId: Int): DisplayWindowProperties {
-        return displayWindowPropertiesRepository.get(displayId, TYPE_NOTIFICATION_SHADE)
+    @UiThread
+    private fun removeShadeWindow(): Unit =
+        traceSection("removeShadeWindow") { wm.removeView(shadeRootView) }
+
+    @UiThread
+    private fun addShadeWindow(): Unit =
+        traceSection("addShadeWindow") { wm.addView(shadeRootView, shadeLayoutParams) }
+
+    @UiThread
+    private fun updateContextDisplay(newDisplayId: Int) {
+        traceSection("updateContextDisplay") { shadeContext.updateDisplay(newDisplayId) }
     }
 
     private companion object {
-        const val TAG = "SecondaryShadeInteractor"
+        const val TAG = "ShadeDisplaysInteractor"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
index 45516aa..0d847d8 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
@@ -23,6 +23,7 @@
 import android.icu.text.DisplayContext
 import android.os.UserHandle
 import android.provider.Settings
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.plugins.ActivityStarter
@@ -48,7 +49,6 @@
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /** Models UI state for the shade header. */
 class ShadeHeaderViewModel
@@ -87,10 +87,6 @@
     /** Whether or not the privacy chip is enabled in the device privacy config. */
     val isPrivacyChipEnabled: StateFlow<Boolean> = privacyChipInteractor.isChipEnabled
 
-    private val _isDisabled = MutableStateFlow(false)
-    /** Whether or not the Shade Header should be disabled based on disableFlags. */
-    val isDisabled: StateFlow<Boolean> = _isDisabled.asStateFlow()
-
     private val longerPattern = context.getString(R.string.abbrev_wday_month_day_no_year_alarm)
     private val shorterPattern = context.getString(R.string.abbrev_month_day_no_year)
     private val longerDateFormat = MutableStateFlow(getFormatFromPattern(longerPattern))
@@ -132,8 +128,6 @@
                     .collect { _mobileSubIds.value = it }
             }
 
-            launch { shadeInteractor.isQsEnabled.map { !it }.collect { _isDisabled.value = it } }
-
             awaitCancellation()
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt
index ce4c081..02531221 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt
@@ -30,15 +30,21 @@
 import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
+import com.android.systemui.statusbar.disableflags.domain.interactor.DisableFlagsInteractor
 import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import java.util.concurrent.atomic.AtomicBoolean
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
 
 /**
  * Models UI state used to render the content of the shade scene.
@@ -54,6 +60,7 @@
     val brightnessMirrorViewModelFactory: BrightnessMirrorViewModel.Factory,
     val mediaCarouselInteractor: MediaCarouselInteractor,
     shadeInteractor: ShadeInteractor,
+    private val disableFlagsInteractor: DisableFlagsInteractor,
     private val footerActionsViewModelFactory: FooterActionsViewModel.Factory,
     private val footerActionsController: FooterActionsController,
     private val unfoldTransitionInteractor: UnfoldTransitionInteractor,
@@ -70,12 +77,21 @@
 
     val isMediaVisible: StateFlow<Boolean> = mediaCarouselInteractor.hasActiveMediaOrRecommendation
 
+    private val _isQsEnabled =
+        MutableStateFlow(!disableFlagsInteractor.disableFlags.value.isQuickSettingsEnabled())
+    val isQsEnabled: StateFlow<Boolean> = _isQsEnabled.asStateFlow()
+
     private val footerActionsControllerInitialized = AtomicBoolean(false)
 
-    override suspend fun onActivated(): Nothing {
-        deviceEntryInteractor.isDeviceEntered.collect { isDeviceEntered ->
-            _isEmptySpaceClickable.value = !isDeviceEntered
-        }
+    override suspend fun onActivated(): Nothing = coroutineScope {
+        deviceEntryInteractor.isDeviceEntered
+            .onEach { isDeviceEntered -> _isEmptySpaceClickable.value = !isDeviceEntered }
+            .launchIn(this)
+        disableFlagsInteractor.disableFlags
+            .map { it.isQuickSettingsEnabled() }
+            .onEach { _isQsEnabled.value = it }
+            .launchIn(this)
+        awaitCancellation()
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt
index b0777c9..dd1b58c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt
@@ -27,24 +27,28 @@
 
 /** Returns collection of [UserAction] to [UserActionResult] pairs for opening the single shade. */
 fun singleShadeActions(
-    requireTwoPointersForTopEdgeForQs: Boolean = false
+    isDownFromTopEdgeEnabled: Boolean = true,
+    requireTwoPointersForTopEdgeForQs: Boolean = false,
 ): Array<Pair<UserAction, UserActionResult>> {
     val shadeUserActionResult = UserActionResult(Scenes.Shade, isIrreversible = true)
     val qsSceneUserActionResult = UserActionResult(Scenes.QuickSettings, isIrreversible = true)
-    return arrayOf(
-        // Swiping down, not from the edge, always goes to shade.
-        Swipe.Down to shadeUserActionResult,
-        Swipe.Down(pointerCount = 2) to shadeUserActionResult,
-
-        // Swiping down from the top edge.
-        swipeDownFromTop(pointerCount = 1) to
-            if (requireTwoPointersForTopEdgeForQs) {
-                shadeUserActionResult
-            } else {
-                qsSceneUserActionResult
-            },
-        swipeDownFromTop(pointerCount = 2) to qsSceneUserActionResult,
-    )
+    return buildList {
+            // Swiping down, not from the edge, always goes to shade.
+            add(Swipe.Down to shadeUserActionResult)
+            add(Swipe.Down(pointerCount = 2) to shadeUserActionResult)
+            if (isDownFromTopEdgeEnabled) {
+                add(
+                    swipeDownFromTop(pointerCount = 1) to
+                        if (requireTwoPointersForTopEdgeForQs) {
+                            shadeUserActionResult
+                        } else {
+                            qsSceneUserActionResult
+                        }
+                )
+                add(swipeDownFromTop(pointerCount = 2) to qsSceneUserActionResult)
+            }
+        }
+        .toTypedArray()
 }
 
 /** Returns collection of [UserAction] to [UserActionResult] pairs for opening the split shade. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
index c019f30..72b03bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
@@ -14,7 +14,7 @@
 per-file *Keyboard* = file:../keyguard/OWNERS
 per-file *Keyguard* = set noparent
 per-file *Keyguard* = file:../keyguard/OWNERS
-per-file *Notification* = set noparent
+# Not setting noparent here, since *Notification* also matches some status bar notification chips files (statusbar/chips/notification) which should be owned by the status bar team.
 per-file *Notification* = file:notification/OWNERS
 # Not setting noparent here, since *Mode* matches many other classes (e.g., *ViewModel*)
 per-file *Mode* = file:notification/OWNERS
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index e19fcd0..85b8bf9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -39,24 +39,24 @@
 import com.android.systemui.res.R
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import java.io.PrintWriter
 import javax.inject.Inject
 import kotlin.math.max
 
 /**
  * A utility class that handles notification panel expansion when a user swipes downward on a
- * notification from the pulsing state.
- * If face-bypass is enabled, the user can swipe down anywhere on the screen (not just from a
- * notification) to trigger the notification panel expansion.
+ * notification from the pulsing state. If face-bypass is enabled, the user can swipe down anywhere
+ * on the screen (not just from a notification) to trigger the notification panel expansion.
  */
 @SysUISingleton
-class PulseExpansionHandler @Inject
+class PulseExpansionHandler
+@Inject
 constructor(
     context: Context,
     private val wakeUpCoordinator: NotificationWakeUpCoordinator,
@@ -67,7 +67,7 @@
     private val falsingManager: FalsingManager,
     private val shadeInteractor: ShadeInteractor,
     private val lockscreenShadeTransitionController: LockscreenShadeTransitionController,
-    dumpManager: DumpManager
+    dumpManager: DumpManager,
 ) : Gefingerpoken, Dumpable {
     companion object {
         private val SPRING_BACK_ANIMATION_LENGTH_MS = 375
@@ -91,14 +91,13 @@
                         pulseExpandAbortListener?.run()
                     }
                 }
-                headsUpManager.unpinAll(
-                    /*userUnPinned= */
-                    true,
-                )
+                headsUpManager.unpinAll(/* userUnPinned= */ true)
             }
         }
+
     var leavingLockscreen: Boolean = false
         private set
+
     private var touchSlop = 0f
     private var minDragDistance = 0
     private lateinit var stackScrollerController: NotificationStackScrollLayoutController
@@ -111,24 +110,27 @@
 
     private val isFalseTouch: Boolean
         get() = falsingManager.isFalseTouch(NOTIFICATION_DRAG_DOWN)
+
     var pulseExpandAbortListener: Runnable? = null
     var bouncerShowing: Boolean = false
 
     init {
         initResources(context)
-        configurationController.addCallback(object : ConfigurationController.ConfigurationListener {
-            override fun onConfigChanged(newConfig: Configuration?) {
-                initResources(context)
+        configurationController.addCallback(
+            object : ConfigurationController.ConfigurationListener {
+                override fun onConfigChanged(newConfig: Configuration?) {
+                    initResources(context)
+                }
             }
-        })
+        )
 
         mPowerManager = context.getSystemService(PowerManager::class.java)
         dumpManager.registerDumpable(this)
     }
 
     private fun initResources(context: Context) {
-        minDragDistance = context.resources.getDimensionPixelSize(
-            R.dimen.keyguard_drag_down_min_distance)
+        minDragDistance =
+            context.resources.getDimensionPixelSize(R.dimen.keyguard_drag_down_min_distance)
         touchSlop = ViewConfiguration.get(context).scaledTouchSlop.toFloat()
     }
 
@@ -137,7 +139,8 @@
     }
 
     private fun canHandleMotionEvent(): Boolean {
-        return wakeUpCoordinator.canShowPulsingHuns && !shadeInteractor.isQsExpanded.value &&
+        return wakeUpCoordinator.canShowPulsingHuns &&
+            !shadeInteractor.isQsExpanded.value &&
             !bouncerShowing
     }
 
@@ -189,18 +192,20 @@
     }
 
     override fun onTouchEvent(event: MotionEvent): Boolean {
-        val finishExpanding = (event.action == MotionEvent.ACTION_CANCEL ||
-            event.action == MotionEvent.ACTION_UP) && isExpanding
+        val finishExpanding =
+            (event.action == MotionEvent.ACTION_CANCEL || event.action == MotionEvent.ACTION_UP) &&
+                isExpanding
 
-        val isDraggingNotificationOrCanBypass = mStartingChild?.showingPulsing() == true ||
-            bypassController.canBypass()
+        val isDraggingNotificationOrCanBypass =
+            mStartingChild?.showingPulsing() == true || bypassController.canBypass()
         if ((!canHandleMotionEvent() || !isDraggingNotificationOrCanBypass) && !finishExpanding) {
             // We allow cancellations/finishing to still go through here to clean up the state
             return false
         }
 
-        if (velocityTracker == null || !isExpanding ||
-            event.actionMasked == MotionEvent.ACTION_DOWN) {
+        if (
+            velocityTracker == null || !isExpanding || event.actionMasked == MotionEvent.ACTION_DOWN
+        ) {
             return startExpansion(event)
         }
         velocityTracker!!.addMovement(event)
@@ -210,12 +215,11 @@
         when (event.actionMasked) {
             MotionEvent.ACTION_MOVE -> updateExpansionHeight(moveDistance)
             MotionEvent.ACTION_UP -> {
-                velocityTracker!!.computeCurrentVelocity(
-                    /* units= */
-                    1000,
-                )
-                val canExpand = moveDistance > 0 && velocityTracker!!.getYVelocity() > -1000 &&
-                    statusBarStateController.state != StatusBarState.SHADE
+                velocityTracker!!.computeCurrentVelocity(/* units= */ 1000)
+                val canExpand =
+                    moveDistance > 0 &&
+                        velocityTracker!!.getYVelocity() > -1000 &&
+                        statusBarStateController.state != StatusBarState.SHADE
                 if (!falsingManager.isUnlockingDisabled && !isFalseTouch && canExpand) {
                     finishExpansion()
                 } else {
@@ -243,22 +247,16 @@
             mPowerManager!!.wakeUp(
                 SystemClock.uptimeMillis(),
                 PowerManager.WAKE_REASON_GESTURE,
-                "com.android.systemui:PULSEDRAG"
+                "com.android.systemui:PULSEDRAG",
             )
         }
-        lockscreenShadeTransitionController.goToLockedShade(
-            startingChild,
-            needsQSAnimation = false
-        )
+        lockscreenShadeTransitionController.goToLockedShade(startingChild, needsQSAnimation = false)
         lockscreenShadeTransitionController.finishPulseAnimation(cancelled = false)
         leavingLockscreen = true
         isExpanding = false
         if (mStartingChild is ExpandableNotificationRow) {
             val row = mStartingChild as ExpandableNotificationRow?
-            row!!.onExpandedByGesture(
-                /*userExpanded= */
-                true,
-            )
+            row!!.onExpandedByGesture(/* userExpanded= */ true)
         }
     }
 
@@ -266,19 +264,15 @@
         var expansionHeight = max(height, 0.0f)
         if (mStartingChild != null) {
             val child = mStartingChild!!
-            val newHeight = Math.min(
-                (child.collapsedHeight + expansionHeight).toInt(),
-                child.maxContentHeight
-            )
+            val newHeight =
+                Math.min((child.collapsedHeight + expansionHeight).toInt(), child.maxContentHeight)
             child.actualHeight = newHeight
         } else {
             wakeUpCoordinator.setNotificationsVisibleForExpansion(
-                height
-                    > lockscreenShadeTransitionController.distanceUntilShowingPulsingNotifications,
-                /*animate= */
-                true,
-                /*increaseSpeed= */
-                true
+                height >
+                    lockscreenShadeTransitionController.distanceUntilShowingPulsingNotifications,
+                /*animate= */ true,
+                /*increaseSpeed= */ true,
             )
         }
         lockscreenShadeTransitionController.setPulseHeight(expansionHeight, animate = false)
@@ -296,7 +290,7 @@
     @VisibleForTesting
     fun reset(
         child: ExpandableView,
-        animationDuration: Long = SPRING_BACK_ANIMATION_LENGTH_MS.toLong()
+        animationDuration: Long = SPRING_BACK_ANIMATION_LENGTH_MS.toLong(),
     ) {
         if (child.actualHeight == child.collapsedHeight) {
             setUserLocked(child, false)
@@ -309,11 +303,13 @@
             // don't use reflection, because the `actualHeight` field may be obfuscated
             child.actualHeight = animation.animatedValue as Int
         }
-        anim.addListener(object : AnimatorListenerAdapter() {
-            override fun onAnimationEnd(animation: Animator) {
-                setUserLocked(child, false)
+        anim.addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    setUserLocked(child, false)
+                }
             }
-        })
+        )
         anim.start()
     }
 
@@ -331,12 +327,9 @@
         }
         lockscreenShadeTransitionController.finishPulseAnimation(cancelled = true)
         wakeUpCoordinator.setNotificationsVisibleForExpansion(
-            /*visible= */
-            false,
-            /*animate= */
-            true,
-            /*increaseSpeed= */
-            false
+            /*visible= */ false,
+            /*animate= */ true,
+            /*increaseSpeed= */ false,
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt
index 8ce0dbf..6db610b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt
@@ -21,7 +21,10 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogBufferFactory
 import com.android.systemui.statusbar.chips.notification.demo.ui.viewmodel.DemoNotifChipViewModel
+import com.android.systemui.statusbar.chips.notification.domain.interactor.StatusBarNotificationChipsInteractor
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import dagger.Binds
+import dagger.Lazy
 import dagger.Module
 import dagger.Provides
 import dagger.multibindings.ClassKey
@@ -41,5 +44,19 @@
         fun provideChipsLogBuffer(factory: LogBufferFactory): LogBuffer {
             return factory.create("StatusBarChips", 200)
         }
+
+        @Provides
+        @SysUISingleton
+        @IntoMap
+        @ClassKey(StatusBarNotificationChipsInteractor::class)
+        fun statusBarNotificationChipsInteractorAsCoreStartable(
+            interactorLazy: Lazy<StatusBarNotificationChipsInteractor>
+        ): CoreStartable {
+            return if (StatusBarNotifChips.isEnabled) {
+                interactorLazy.get()
+            } else {
+                CoreStartable.NOP
+            }
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
index af238f6..49c4479 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.chips.mediaprojection.domain.interactor
 
 import android.content.pm.PackageManager
+import android.media.projection.StopReason
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.Flags
 import com.android.systemui.dagger.SysUISingleton
@@ -105,7 +106,7 @@
 
     /** Stops the currently active projection. */
     fun stopProjecting() {
-        scope.launch { mediaProjectionRepository.stopProjecting() }
+        scope.launch { mediaProjectionRepository.stopProjecting(StopReason.STOP_PRIVACY_CHIP) }
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
new file mode 100644
index 0000000..087b510
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.chips.notification.domain.interactor
+
+import com.android.systemui.activity.data.repository.ActivityManagerRepository
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.Logger
+import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
+import com.android.systemui.statusbar.chips.notification.domain.model.NotificationChipModel
+import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
+
+/**
+ * Interactor representing a single notification's status bar chip.
+ *
+ * [startingModel.key] dictates which notification this interactor corresponds to - all updates sent
+ * to this interactor via [setNotification] should only be for the notification with the same key.
+ *
+ * [StatusBarNotificationChipsInteractor] will collect all the individual instances of this
+ * interactor and send all the necessary information to the UI layer.
+ */
+@OptIn(ExperimentalCoroutinesApi::class)
+class SingleNotificationChipInteractor
+@AssistedInject
+constructor(
+    @Assisted startingModel: ActiveNotificationModel,
+    private val activityManagerRepository: ActivityManagerRepository,
+    @StatusBarChipsLog private val logBuffer: LogBuffer,
+) {
+    private val key = startingModel.key
+    private val logger = Logger(logBuffer, "Notif".pad())
+    // [StatusBarChipLogTag] recommends a max tag length of 20, so [extraLogTag] should NOT be the
+    // top-level tag. It should instead be provided as the first string in each log message.
+    private val extraLogTag = "SingleChipInteractor[key=$key]"
+
+    private val _notificationModel = MutableStateFlow(startingModel)
+
+    /**
+     * Sets the new notification info corresponding to this interactor. The key on [model] *must*
+     * match the key on the original [startingModel], otherwise the update won't be processed.
+     */
+    fun setNotification(model: ActiveNotificationModel) {
+        if (model.key != this.key) {
+            logger.w({ "$str1: received model for different key $str2" }) {
+                str1 = extraLogTag
+                str2 = model.key
+            }
+            return
+        }
+        _notificationModel.value = model
+    }
+
+    private val uid: Flow<Int> = _notificationModel.map { it.uid }
+
+    /** True if the application managing the notification is visible to the user. */
+    private val isAppVisible: Flow<Boolean> =
+        uid.flatMapLatest { currentUid ->
+            activityManagerRepository.createIsAppVisibleFlow(currentUid, logger, extraLogTag)
+        }
+
+    /**
+     * Emits this notification's status bar chip, or null if this notification shouldn't show a
+     * status bar chip.
+     */
+    val notificationChip: Flow<NotificationChipModel?> =
+        combine(_notificationModel, isAppVisible) { notif, isAppVisible ->
+            if (isAppVisible) {
+                // If the app that posted this notification is visible, we want to hide the chip
+                // because information between the status bar chip and the app itself could be
+                // out-of-sync (like a timer that's slightly off)
+                null
+            } else {
+                notif.toNotificationChipModel()
+            }
+        }
+
+    private fun ActiveNotificationModel.toNotificationChipModel(): NotificationChipModel? {
+        val statusBarChipIconView = this.statusBarChipIconView
+        if (statusBarChipIconView == null) {
+            logger.w({ "$str1: Can't show chip because status bar chip icon view is null" }) {
+                str1 = extraLogTag
+            }
+            return null
+        }
+        return NotificationChipModel(key, statusBarChipIconView)
+    }
+
+    @AssistedFactory
+    fun interface Factory {
+        fun create(startingModel: ActiveNotificationModel): SingleNotificationChipInteractor
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
index 9e09671..e8cb35b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt
@@ -17,16 +17,42 @@
 package com.android.systemui.statusbar.chips.notification.domain.interactor
 
 import android.annotation.SuppressLint
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.Logger
+import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
+import com.android.systemui.statusbar.chips.notification.domain.model.NotificationChipModel
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
+import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
+import com.android.systemui.util.kotlin.pairwise
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
 
 /** An interactor for the notification chips shown in the status bar. */
 @SysUISingleton
-class StatusBarNotificationChipsInteractor @Inject constructor() {
+@OptIn(ExperimentalCoroutinesApi::class)
+class StatusBarNotificationChipsInteractor
+@Inject
+constructor(
+    @Background private val backgroundScope: CoroutineScope,
+    private val activeNotificationsInteractor: ActiveNotificationsInteractor,
+    private val singleNotificationChipInteractorFactory: SingleNotificationChipInteractor.Factory,
+    @StatusBarChipsLog private val logBuffer: LogBuffer,
+) : CoreStartable {
+    private val logger = Logger(logBuffer, "AllNotifs".pad())
 
     // Each chip tap is an individual event, *not* a state, which is why we're using SharedFlow not
     // StateFlow. There shouldn't be multiple updates per frame, which should avoid performance
@@ -45,4 +71,79 @@
         StatusBarNotifChips.assertInNewMode()
         _promotedNotificationChipTapEvent.emit(key)
     }
+
+    /**
+     * A cache of interactors. Each currently-promoted notification should have a corresponding
+     * interactor in this map.
+     */
+    private val promotedNotificationInteractorMap =
+        mutableMapOf<String, SingleNotificationChipInteractor>()
+
+    /**
+     * A list of interactors. Each currently-promoted notification should have a corresponding
+     * interactor in this list.
+     */
+    private val promotedNotificationInteractors =
+        MutableStateFlow<List<SingleNotificationChipInteractor>>(emptyList())
+
+    override fun start() {
+        if (!StatusBarNotifChips.isEnabled) {
+            return
+        }
+
+        backgroundScope.launch("StatusBarNotificationChipsInteractor") {
+            activeNotificationsInteractor.promotedOngoingNotifications
+                .pairwise(initialValue = emptyList())
+                .collect { (oldNotifs, currentNotifs) ->
+                    val removedNotifs = oldNotifs.minus(currentNotifs.toSet())
+                    removedNotifs.forEach { removedNotif ->
+                        val wasRemoved = promotedNotificationInteractorMap.remove(removedNotif.key)
+                        if (wasRemoved == null) {
+                            logger.w({
+                                "Attempted to remove $str1 from interactor map but it wasn't present"
+                            }) {
+                                str1 = removedNotif.key
+                            }
+                        }
+                    }
+                    currentNotifs.forEach { notif ->
+                        val interactor =
+                            promotedNotificationInteractorMap.computeIfAbsent(notif.key) {
+                                singleNotificationChipInteractorFactory.create(notif)
+                            }
+                        interactor.setNotification(notif)
+                    }
+                    logger.d({ "Interactors: $str1" }) {
+                        str1 =
+                            promotedNotificationInteractorMap.keys.joinToString(separator = " /// ")
+                    }
+                    promotedNotificationInteractors.value =
+                        promotedNotificationInteractorMap.values.toList()
+                }
+        }
+    }
+
+    /**
+     * A flow modeling the notifications that should be shown as chips in the status bar. Emits an
+     * empty list if there are no notifications that should show a status bar chip.
+     */
+    val notificationChips: Flow<List<NotificationChipModel>> =
+        if (StatusBarNotifChips.isEnabled) {
+            // For all our current interactors...
+            promotedNotificationInteractors.flatMapLatest { interactors ->
+                if (interactors.isNotEmpty()) {
+                    // Combine each interactor's [notificationChip] flow...
+                    val allNotificationChips: List<Flow<NotificationChipModel?>> =
+                        interactors.map { interactor -> interactor.notificationChip }
+                    combine(allNotificationChips) {
+                        // ... and emit just the non-null chips
+                        it.filterNotNull()
+                    }
+                } else {
+                    flowOf(emptyList())
+                }
+            }
+        } else {
+            flowOf(emptyList())
+        }
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
similarity index 66%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
index 5a04169..5698ee6 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.systemui.statusbar.chips.notification.domain.model
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+import com.android.systemui.statusbar.StatusBarIconView
+
+/** Modeling all the data needed to render a status bar notification chip. */
+data class NotificationChipModel(val key: String, val statusBarChipIconView: StatusBarIconView)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
index 7526748..9eff627 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
@@ -20,11 +20,10 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.statusbar.chips.notification.domain.interactor.StatusBarNotificationChipsInteractor
+import com.android.systemui.statusbar.chips.notification.domain.model.NotificationChipModel
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
-import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
-import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
@@ -37,7 +36,6 @@
 @Inject
 constructor(
     @Application private val applicationScope: CoroutineScope,
-    activeNotificationsInteractor: ActiveNotificationsInteractor,
     private val notifChipsInteractor: StatusBarNotificationChipsInteractor,
 ) {
     /**
@@ -45,19 +43,14 @@
      * no notifications that should show a status bar chip.
      */
     val chips: Flow<List<OngoingActivityChipModel.Shown>> =
-        activeNotificationsInteractor.promotedOngoingNotifications.map { notifications ->
-            notifications.mapNotNull { it.toChipModel() }
+        notifChipsInteractor.notificationChips.map { notifications ->
+            notifications.map { it.toActivityChipModel() }
         }
 
-    /**
-     * Converts the notification to the [OngoingActivityChipModel] object. Returns null if the
-     * notification has invalid data such that it can't be displayed as a chip.
-     */
-    private fun ActiveNotificationModel.toChipModel(): OngoingActivityChipModel.Shown? {
+    /** Converts the notification to the [OngoingActivityChipModel] object. */
+    private fun NotificationChipModel.toActivityChipModel(): OngoingActivityChipModel.Shown {
         StatusBarNotifChips.assertInNewMode()
-        // TODO(b/364653005): Log error if there's no icon view.
-        val rawIcon = this.statusBarChipIconView ?: return null
-        val icon = OngoingActivityChipModel.ChipIcon.StatusBarView(rawIcon)
+        val icon = OngoingActivityChipModel.ChipIcon.StatusBarView(this.statusBarChipIconView)
         // TODO(b/364653005): Use the notification color if applicable.
         val colors = ColorsModel.Themed
         val onClickListener =
@@ -65,7 +58,9 @@
                 // The notification pipeline needs everything to run on the main thread, so keep
                 // this event on the main thread.
                 applicationScope.launch {
-                    notifChipsInteractor.onPromotedNotificationChipTapped(this@toChipModel.key)
+                    notifChipsInteractor.onPromotedNotificationChipTapped(
+                        this@toActivityChipModel.key
+                    )
                 }
             }
         return OngoingActivityChipModel.Shown.IconOnly(icon, colors, onClickListener)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
index 84c7ab2..9e9a38e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.statusbar.data.repository.LightBarControllerStore
 import com.android.systemui.statusbar.data.repository.PrivacyDotWindowControllerStore
 import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
+import com.android.systemui.statusbar.phone.AutoHideControllerStore
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
 import com.android.systemui.statusbar.window.data.repository.StatusBarWindowStateRepositoryStore
 import com.android.systemui.util.kotlin.pairwiseBy
@@ -50,6 +51,7 @@
     private val initializerStore: StatusBarInitializerStore,
     private val statusBarWindowControllerStore: StatusBarWindowControllerStore,
     private val statusBarInitializerStore: StatusBarInitializerStore,
+    private val autoHideControllerStore: AutoHideControllerStore,
     private val privacyDotWindowControllerStore: PrivacyDotWindowControllerStore,
     private val lightBarControllerStore: LightBarControllerStore,
 ) : CoreStartable {
@@ -95,6 +97,7 @@
                 statusBarModeRepositoryStore.forDisplay(displayId),
                 initializerStore.forDisplay(displayId),
                 statusBarWindowControllerStore.forDisplay(displayId),
+                autoHideControllerStore.forDisplay(displayId),
             )
             .start()
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
index ff4760f..9f5a311 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
@@ -71,9 +71,9 @@
     @Assisted private val statusBarInitializer: StatusBarInitializer,
     @Assisted private val statusBarWindowController: StatusBarWindowController,
     @Main private val mainContext: CoroutineContext,
+    @Assisted private val autoHideController: AutoHideController,
     private val demoModeController: DemoModeController,
     private val pluginDependencyProvider: PluginDependencyProvider,
-    private val autoHideController: AutoHideController,
     private val remoteInputManager: NotificationRemoteInputManager,
     private val notificationShadeWindowViewControllerLazy:
         Lazy<NotificationShadeWindowViewController>,
@@ -210,10 +210,6 @@
     }
 
     private fun setUpAutoHide() {
-        if (displayId != Display.DEFAULT_DISPLAY) {
-            return
-        }
-        // TODO(b/373309973): per display implementation of auto hide controller
         autoHideController.setStatusBar(
             object : AutoHideUiElement {
                 override fun synchronizeState() {}
@@ -241,10 +237,7 @@
         if (!demoModeController.isInDemoMode) {
             barTransitions.transitionTo(barMode.toTransitionModeInt(), animate)
         }
-        if (displayId == Display.DEFAULT_DISPLAY) {
-            // TODO(b/373309973): per display implementation of auto hide controller
-            autoHideController.touchAutoHide()
-        }
+        autoHideController.touchAutoHide()
     }
 
     private fun updateBubblesVisibility(statusBarVisible: Boolean) {
@@ -288,6 +281,7 @@
             statusBarModeRepository: StatusBarModePerDisplayRepository,
             statusBarInitializer: StatusBarInitializer,
             statusBarWindowController: StatusBarWindowController,
+            autoHideController: AutoHideController,
         ): StatusBarOrchestrator
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt
index 4341200..47b695e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt
@@ -27,7 +27,10 @@
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
 import com.android.systemui.statusbar.data.StatusBarDataLayerModule
 import com.android.systemui.statusbar.data.repository.LightBarControllerStore
+import com.android.systemui.statusbar.phone.AutoHideController
+import com.android.systemui.statusbar.phone.AutoHideControllerImpl
 import com.android.systemui.statusbar.phone.LightBarController
+import com.android.systemui.statusbar.phone.LightBarControllerImpl
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProviderImpl
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy
@@ -79,6 +82,13 @@
         implFactory: StatusBarWindowControllerImpl.Factory
     ): StatusBarWindowController.Factory
 
+    @Binds @SysUISingleton fun autoHideController(impl: AutoHideControllerImpl): AutoHideController
+
+    @Binds
+    fun lightBarControllerFactory(
+        legacyFactory: LightBarControllerImpl.LegacyFactory
+    ): LightBarController.Factory
+
     companion object {
 
         @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index a24f267..85cd505 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -83,39 +83,36 @@
 import javax.inject.Inject
 import javax.inject.Named
 
-
 /** Controller for managing the smartspace view on the lockscreen */
 @SysUISingleton
 class LockscreenSmartspaceController
 @Inject
 constructor(
-        private val context: Context,
-        private val featureFlags: FeatureFlags,
-        private val activityStarter: ActivityStarter,
-        private val falsingManager: FalsingManager,
-        private val systemClock: SystemClock,
-        private val secureSettings: SecureSettings,
-        private val userTracker: UserTracker,
-        private val contentResolver: ContentResolver,
-        private val configurationController: ConfigurationController,
-        private val statusBarStateController: StatusBarStateController,
-        private val deviceProvisionedController: DeviceProvisionedController,
-        private val bypassController: KeyguardBypassController,
-        private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
-        private val wakefulnessLifecycle: WakefulnessLifecycle,
-        private val smartspaceViewModelFactory: SmartspaceViewModel.Factory,
-        private val dumpManager: DumpManager,
-        private val execution: Execution,
-        @Main private val uiExecutor: Executor,
-        @Background private val bgExecutor: Executor,
-        @Main private val handler: Handler,
-        @Background private val bgHandler: Handler,
-        @Named(DATE_SMARTSPACE_DATA_PLUGIN)
-        optionalDatePlugin: Optional<BcSmartspaceDataPlugin>,
-        @Named(WEATHER_SMARTSPACE_DATA_PLUGIN)
-        optionalWeatherPlugin: Optional<BcSmartspaceDataPlugin>,
-        optionalPlugin: Optional<BcSmartspaceDataPlugin>,
-        optionalConfigPlugin: Optional<BcSmartspaceConfigPlugin>,
+    private val context: Context,
+    private val featureFlags: FeatureFlags,
+    private val activityStarter: ActivityStarter,
+    private val falsingManager: FalsingManager,
+    private val systemClock: SystemClock,
+    private val secureSettings: SecureSettings,
+    private val userTracker: UserTracker,
+    private val contentResolver: ContentResolver,
+    private val configurationController: ConfigurationController,
+    private val statusBarStateController: StatusBarStateController,
+    private val deviceProvisionedController: DeviceProvisionedController,
+    private val bypassController: KeyguardBypassController,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    private val wakefulnessLifecycle: WakefulnessLifecycle,
+    private val smartspaceViewModelFactory: SmartspaceViewModel.Factory,
+    private val dumpManager: DumpManager,
+    private val execution: Execution,
+    @Main private val uiExecutor: Executor,
+    @Background private val bgExecutor: Executor,
+    @Main private val handler: Handler,
+    @Background private val bgHandler: Handler,
+    @Named(DATE_SMARTSPACE_DATA_PLUGIN) optionalDatePlugin: Optional<BcSmartspaceDataPlugin>,
+    @Named(WEATHER_SMARTSPACE_DATA_PLUGIN) optionalWeatherPlugin: Optional<BcSmartspaceDataPlugin>,
+    optionalPlugin: Optional<BcSmartspaceDataPlugin>,
+    optionalConfigPlugin: Optional<BcSmartspaceConfigPlugin>,
 ) : Dumpable {
     companion object {
         private const val TAG = "LockscreenSmartspaceController"
@@ -135,11 +132,9 @@
 
     // Smartspace can be used on multiple displays, such as when the user casts their screen
     @VisibleForTesting var smartspaceViews = mutableSetOf<SmartspaceView>()
-    private var regionSamplers =
-            mutableMapOf<SmartspaceView, RegionSampler>()
+    private var regionSamplers = mutableMapOf<SmartspaceView, RegionSampler>()
 
-    private val regionSamplingEnabled =
-            featureFlags.isEnabled(Flags.REGION_SAMPLING)
+    private val regionSamplingEnabled = featureFlags.isEnabled(Flags.REGION_SAMPLING)
     private var isRegionSamplersCreated = false
     private var showNotifications = false
     private var showSensitiveContentForCurrentUser = false
@@ -157,119 +152,130 @@
     //  how we test color updates when theme changes (See testThemeChangeUpdatesTextColor).
 
     // TODO: Move logic into SmartspaceView
-    var stateChangeListener = object : View.OnAttachStateChangeListener {
-        override fun onViewAttachedToWindow(v: View) {
-            (v as SmartspaceView).setSplitShadeEnabled(mSplitShadeEnabled)
-            smartspaceViews.add(v as SmartspaceView)
+    var stateChangeListener =
+        object : View.OnAttachStateChangeListener {
+            override fun onViewAttachedToWindow(v: View) {
+                (v as SmartspaceView).setSplitShadeEnabled(mSplitShadeEnabled)
+                smartspaceViews.add(v as SmartspaceView)
 
-            connectSession()
+                connectSession()
 
-            updateTextColorFromWallpaper()
-            statusBarStateListener.onDozeAmountChanged(0f, statusBarStateController.dozeAmount)
+                updateTextColorFromWallpaper()
+                statusBarStateListener.onDozeAmountChanged(0f, statusBarStateController.dozeAmount)
 
-            if (regionSamplingEnabled && (!regionSamplers.containsKey(v))) {
-                var regionSampler = RegionSampler(
-                        v as View,
-                        uiExecutor,
-                        bgExecutor,
-                        regionSamplingEnabled,
-                        isLockscreen = true,
-                ) { updateTextColorFromRegionSampler() }
-                initializeTextColors(regionSampler)
-                regionSamplers[v] = regionSampler
-                regionSampler.startRegionSampler()
-            }
-        }
-
-        override fun onViewDetachedFromWindow(v: View) {
-            smartspaceViews.remove(v as SmartspaceView)
-
-            regionSamplers[v]?.stopRegionSampler()
-            regionSamplers.remove(v as SmartspaceView)
-
-            if (smartspaceViews.isEmpty()) {
-                disconnect()
-            }
-        }
-    }
-
-    private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets ->
-        execution.assertIsMainThread()
-
-        // The weather data plugin takes unfiltered targets and performs the filtering internally.
-        weatherPlugin?.onTargetsAvailable(targets)
-
-        val now = Instant.ofEpochMilli(systemClock.currentTimeMillis())
-        val weatherTarget = targets.find { t ->
-            t.featureType == SmartspaceTarget.FEATURE_WEATHER &&
-                    now.isAfter(Instant.ofEpochMilli(t.creationTimeMillis)) &&
-                    now.isBefore(Instant.ofEpochMilli(t.expiryTimeMillis))
-        }
-        if (weatherTarget != null) {
-            val clickIntent = weatherTarget.headerAction?.intent
-            val weatherData = weatherTarget.baseAction?.extras?.let { extras ->
-                WeatherData.fromBundle(
-                    extras,
-                ) { _ ->
-                    if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
-                        activityStarter.startActivity(
-                            clickIntent,
-                            true, /* dismissShade */
-                            null,
-                            false)
-                    }
+                if (regionSamplingEnabled && (!regionSamplers.containsKey(v))) {
+                    var regionSampler =
+                        RegionSampler(
+                            v as View,
+                            uiExecutor,
+                            bgExecutor,
+                            regionSamplingEnabled,
+                            isLockscreen = true,
+                        ) {
+                            updateTextColorFromRegionSampler()
+                        }
+                    initializeTextColors(regionSampler)
+                    regionSamplers[v] = regionSampler
+                    regionSampler.startRegionSampler()
                 }
             }
 
-            if (weatherData != null) {
-                keyguardUpdateMonitor.sendWeatherData(weatherData)
+            override fun onViewDetachedFromWindow(v: View) {
+                smartspaceViews.remove(v as SmartspaceView)
+
+                regionSamplers[v]?.stopRegionSampler()
+                regionSamplers.remove(v as SmartspaceView)
+
+                if (smartspaceViews.isEmpty()) {
+                    disconnect()
+                }
             }
         }
 
-        val filteredTargets = targets.filter(::filterSmartspaceTarget)
+    private val sessionListener =
+        SmartspaceSession.OnTargetsAvailableListener { targets ->
+            execution.assertIsMainThread()
 
-        synchronized(recentSmartspaceData) {
-            recentSmartspaceData.offerLast(filteredTargets)
-            if (recentSmartspaceData.size > MAX_RECENT_SMARTSPACE_DATA_FOR_DUMP) {
-                recentSmartspaceData.pollFirst()
+            // The weather data plugin takes unfiltered targets and performs the filtering
+            // internally.
+            weatherPlugin?.onTargetsAvailable(targets)
+
+            val now = Instant.ofEpochMilli(systemClock.currentTimeMillis())
+            val weatherTarget =
+                targets.find { t ->
+                    t.featureType == SmartspaceTarget.FEATURE_WEATHER &&
+                        now.isAfter(Instant.ofEpochMilli(t.creationTimeMillis)) &&
+                        now.isBefore(Instant.ofEpochMilli(t.expiryTimeMillis))
+                }
+            if (weatherTarget != null) {
+                val clickIntent = weatherTarget.headerAction?.intent
+                val weatherData =
+                    weatherTarget.baseAction?.extras?.let { extras ->
+                        WeatherData.fromBundle(extras) { _ ->
+                            if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+                                activityStarter.startActivity(
+                                    clickIntent,
+                                    true, /* dismissShade */
+                                    null,
+                                    false,
+                                )
+                            }
+                        }
+                    }
+
+                if (weatherData != null) {
+                    keyguardUpdateMonitor.sendWeatherData(weatherData)
+                }
+            }
+
+            val filteredTargets = targets.filter(::filterSmartspaceTarget)
+
+            synchronized(recentSmartspaceData) {
+                recentSmartspaceData.offerLast(filteredTargets)
+                if (recentSmartspaceData.size > MAX_RECENT_SMARTSPACE_DATA_FOR_DUMP) {
+                    recentSmartspaceData.pollFirst()
+                }
+            }
+
+            plugin?.onTargetsAvailable(filteredTargets)
+        }
+
+    private val userTrackerCallback =
+        object : UserTracker.Callback {
+            override fun onUserChanged(newUser: Int, userContext: Context) {
+                execution.assertIsMainThread()
+                reloadSmartspace()
             }
         }
 
-        plugin?.onTargetsAvailable(filteredTargets)
-    }
-
-    private val userTrackerCallback = object : UserTracker.Callback {
-        override fun onUserChanged(newUser: Int, userContext: Context) {
-            execution.assertIsMainThread()
-            reloadSmartspace()
-        }
-    }
-
-    private val settingsObserver = object : ContentObserver(handler) {
-        override fun onChange(selfChange: Boolean, uri: Uri?) {
-            execution.assertIsMainThread()
-            reloadSmartspace()
-        }
-    }
-
-    private val configChangeListener = object : ConfigurationController.ConfigurationListener {
-        override fun onThemeChanged() {
-            execution.assertIsMainThread()
-            updateTextColorFromWallpaper()
-        }
-    }
-
-    private val statusBarStateListener = object : StatusBarStateController.StateListener {
-        override fun onDozeAmountChanged(linear: Float, eased: Float) {
-            execution.assertIsMainThread()
-            smartspaceViews.forEach { it.setDozeAmount(eased) }
+    private val settingsObserver =
+        object : ContentObserver(handler) {
+            override fun onChange(selfChange: Boolean, uri: Uri?) {
+                execution.assertIsMainThread()
+                reloadSmartspace()
+            }
         }
 
-        override fun onDozingChanged(isDozing: Boolean) {
-            execution.assertIsMainThread()
-            smartspaceViews.forEach { it.setDozing(isDozing) }
+    private val configChangeListener =
+        object : ConfigurationController.ConfigurationListener {
+            override fun onThemeChanged() {
+                execution.assertIsMainThread()
+                updateTextColorFromWallpaper()
+            }
         }
-    }
+
+    private val statusBarStateListener =
+        object : StatusBarStateController.StateListener {
+            override fun onDozeAmountChanged(linear: Float, eased: Float) {
+                execution.assertIsMainThread()
+                smartspaceViews.forEach { it.setDozeAmount(eased) }
+            }
+
+            override fun onDozingChanged(isDozing: Boolean) {
+                execution.assertIsMainThread()
+                smartspaceViews.forEach { it.setDozing(isDozing) }
+            }
+        }
 
     private val deviceProvisionedListener =
         object : DeviceProvisionedController.DeviceProvisionedListener {
@@ -313,11 +319,8 @@
     val isWeatherEnabled: Boolean
         get() {
             val showWeather =
-                secureSettings.getIntForUser(
-                    LOCK_SCREEN_WEATHER_ENABLED,
-                    1,
-                    userTracker.userId,
-                ) == 1
+                secureSettings.getIntForUser(LOCK_SCREEN_WEATHER_ENABLED, 1, userTracker.userId) ==
+                    1
             return showWeather
         }
 
@@ -326,9 +329,7 @@
         smartspaceViews.forEach { it.setKeyguardBypassEnabled(bypassEnabled) }
     }
 
-    /**
-     * Constructs the date view and connects it to the smartspace service.
-     */
+    /** Constructs the date view and connects it to the smartspace service. */
     fun buildAndConnectDateView(parent: ViewGroup): View? {
         execution.assertIsMainThread()
 
@@ -343,16 +344,14 @@
             buildView(
                 surfaceName = SmartspaceViewModel.SURFACE_DATE_VIEW,
                 parent = parent,
-                plugin = datePlugin
+                plugin = datePlugin,
             )
         connectSession()
 
         return view
     }
 
-    /**
-     * Constructs the weather view and connects it to the smartspace service.
-     */
+    /** Constructs the weather view and connects it to the smartspace service. */
     fun buildAndConnectWeatherView(parent: ViewGroup): View? {
         execution.assertIsMainThread()
 
@@ -367,16 +366,14 @@
             buildView(
                 surfaceName = SmartspaceViewModel.SURFACE_WEATHER_VIEW,
                 parent = parent,
-                plugin = weatherPlugin
+                plugin = weatherPlugin,
             )
         connectSession()
 
         return view
     }
 
-    /**
-     * Constructs the smartspace view and connects it to the smartspace service.
-     */
+    /** Constructs the smartspace view and connects it to the smartspace service. */
     fun buildAndConnectView(parent: ViewGroup): View? {
         execution.assertIsMainThread()
 
@@ -384,12 +381,14 @@
             throw RuntimeException("Cannot build view when not enabled")
         }
 
+        configPlugin?.let { plugin?.registerConfigProvider(it) }
+
         val view =
             buildView(
                 surfaceName = SmartspaceViewModel.SURFACE_GENERAL_VIEW,
                 parent = parent,
                 plugin = plugin,
-                configPlugin = configPlugin
+                configPlugin = configPlugin,
             )
         connectSession()
 
@@ -400,7 +399,7 @@
         surfaceName: String,
         parent: ViewGroup,
         plugin: BcSmartspaceDataPlugin?,
-        configPlugin: BcSmartspaceConfigPlugin? = null
+        configPlugin: BcSmartspaceConfigPlugin? = null,
     ): View? {
         if (plugin == null) {
             return null
@@ -413,37 +412,41 @@
         ssView.setTimeChangedDelegate(SmartspaceTimeChangedDelegate(keyguardUpdateMonitor))
         ssView.registerDataProvider(plugin)
 
-        ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter {
-            override fun startIntent(view: View, intent: Intent, showOnLockscreen: Boolean) {
-                if (showOnLockscreen) {
-                    activityStarter.startActivity(
+        ssView.setIntentStarter(
+            object : BcSmartspaceDataPlugin.IntentStarter {
+                override fun startIntent(view: View, intent: Intent, showOnLockscreen: Boolean) {
+                    if (showOnLockscreen) {
+                        activityStarter.startActivity(
                             intent,
                             true, /* dismissShade */
                             // launch animator - looks bad with the transparent smartspace bg
                             null,
-                            true
-                    )
-                } else {
-                    activityStarter.postStartActivityDismissingKeyguard(intent, 0)
+                            true,
+                        )
+                    } else {
+                        activityStarter.postStartActivityDismissingKeyguard(intent, 0)
+                    }
                 }
-            }
 
-            override fun startPendingIntent(
+                override fun startPendingIntent(
                     view: View,
                     pi: PendingIntent,
-                    showOnLockscreen: Boolean
-            ) {
-                if (showOnLockscreen) {
-                    val options = ActivityOptions.makeBasic()
-                            .setPendingIntentBackgroundActivityStartMode(
-                                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
-                            .toBundle()
-                    pi.send(options)
-                } else {
-                    activityStarter.postStartActivityDismissingKeyguard(pi)
+                    showOnLockscreen: Boolean,
+                ) {
+                    if (showOnLockscreen) {
+                        val options =
+                            ActivityOptions.makeBasic()
+                                .setPendingIntentBackgroundActivityStartMode(
+                                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+                                )
+                                .toBundle()
+                        pi.send(options)
+                    } else {
+                        activityStarter.postStartActivityDismissingKeyguard(pi)
+                    }
                 }
             }
-        })
+        )
         ssView.setFalsingManager(falsingManager)
         ssView.setKeyguardBypassEnabled(bypassController.bypassEnabled)
         return (ssView as View).apply {
@@ -452,10 +455,7 @@
 
             if (smartspaceLockscreenViewmodel()) {
                 val viewModel = smartspaceViewModelFactory.create(surfaceName)
-                SmartspaceViewBinder.bind(
-                    smartspaceView = ssView,
-                    viewModel = viewModel,
-                )
+                SmartspaceViewBinder.bind(smartspaceView = ssView, viewModel = viewModel)
             }
         }
     }
@@ -473,34 +473,41 @@
 
         // Only connect after the device is fully provisioned to avoid connection caching
         // issues
-        if (!deviceProvisionedController.isDeviceProvisioned() ||
-                !deviceProvisionedController.isCurrentUserSetup()) {
+        if (
+            !deviceProvisionedController.isDeviceProvisioned() ||
+                !deviceProvisionedController.isCurrentUserSetup()
+        ) {
             return
         }
 
-        val newSession = userSmartspaceManager?.createSmartspaceSession(
-            SmartspaceConfig.Builder(
-                userTracker.userContext, BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD
-            ).build()
+        val newSession =
+            userSmartspaceManager?.createSmartspaceSession(
+                SmartspaceConfig.Builder(
+                        userTracker.userContext,
+                        BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD,
+                    )
+                    .build()
+            )
+        Log.d(
+            TAG,
+            "Starting smartspace session for " + BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD,
         )
-        Log.d(TAG, "Starting smartspace session for " +
-                BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
         newSession?.addOnTargetsAvailableListener(uiExecutor, sessionListener)
         this.session = newSession
 
         deviceProvisionedController.removeCallback(deviceProvisionedListener)
         userTracker.addCallback(userTrackerCallback, uiExecutor)
         contentResolver.registerContentObserver(
-                secureSettings.getUriFor(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
-                true,
-                settingsObserver,
-                UserHandle.USER_ALL
+            secureSettings.getUriFor(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+            true,
+            settingsObserver,
+            UserHandle.USER_ALL,
         )
         contentResolver.registerContentObserver(
-                secureSettings.getUriFor(LOCK_SCREEN_SHOW_NOTIFICATIONS),
-                true,
-                settingsObserver,
-                UserHandle.USER_ALL
+            secureSettings.getUriFor(LOCK_SCREEN_SHOW_NOTIFICATIONS),
+            true,
+            settingsObserver,
+            UserHandle.USER_ALL,
         )
         configurationController.addCallback(configChangeListener)
         statusBarStateController.addCallback(statusBarStateListener)
@@ -522,16 +529,12 @@
         smartspaceViews.forEach { it.setSplitShadeEnabled(enabled) }
     }
 
-    /**
-     * Requests the smartspace session for an update.
-     */
+    /** Requests the smartspace session for an update. */
     fun requestSmartspaceUpdate() {
         session?.requestSmartspaceUpdate()
     }
 
-    /**
-     * Disconnects the smartspace view from the smartspace service and cleans up any resources.
-     */
+    /** Disconnects the smartspace view from the smartspace service and cleans up any resources. */
     fun disconnect() {
         if (!smartspaceViews.isEmpty()) return
         if (suppressDisconnects) return
@@ -638,7 +641,7 @@
     private fun updateTextColorFromWallpaper() {
         if (!regionSamplingEnabled || regionSamplers.isEmpty()) {
             val wallpaperTextColor =
-                    Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor)
+                Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor)
             smartspaceViews.forEach { it.setPrimaryTextColor(wallpaperTextColor) }
         } else {
             updateTextColorFromRegionSampler()
@@ -646,26 +649,25 @@
     }
 
     private fun reloadSmartspace() {
-        showNotifications = secureSettings.getIntForUser(
-            LOCK_SCREEN_SHOW_NOTIFICATIONS,
-            0,
-            userTracker.userId
-        ) == 1
+        showNotifications =
+            secureSettings.getIntForUser(LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userTracker.userId) == 1
 
-        showSensitiveContentForCurrentUser = secureSettings.getIntForUser(
-            LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
-            0,
-            userTracker.userId
-        ) == 1
+        showSensitiveContentForCurrentUser =
+            secureSettings.getIntForUser(
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                0,
+                userTracker.userId,
+            ) == 1
 
         managedUserHandle = getWorkProfileUser()
         val managedId = managedUserHandle?.identifier
         if (managedId != null) {
-            showSensitiveContentForManagedUser = secureSettings.getIntForUser(
-                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
-                0,
-                managedId
-            ) == 1
+            showSensitiveContentForManagedUser =
+                secureSettings.getIntForUser(
+                    LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                    0,
+                    managedId,
+                ) == 1
         }
 
         session?.requestSmartspaceUpdate()
@@ -682,9 +684,7 @@
 
     override fun dump(pw: PrintWriter, args: Array<out String>) {
         pw.asIndenting().run {
-            printCollection("Region Samplers", regionSamplers.values) {
-                it.dump(this)
-            }
+            printCollection("Region Samplers", regionSamplers.values) { it.dump(this) }
         }
 
         pw.println("Recent BC Smartspace Targets (most recent first)")
@@ -707,15 +707,17 @@
         private val keyguardUpdateMonitor: KeyguardUpdateMonitor
     ) : TimeChangedDelegate {
         private var keyguardUpdateMonitorCallback: KeyguardUpdateMonitorCallback? = null
+
         override fun register(callback: Runnable) {
             if (keyguardUpdateMonitorCallback != null) {
                 unregister()
             }
-            keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
-                override fun onTimeChanged() {
-                    callback.run()
+            keyguardUpdateMonitorCallback =
+                object : KeyguardUpdateMonitorCallback() {
+                    override fun onTimeChanged() {
+                        callback.run()
+                    }
                 }
-            }
             keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
             callback.run()
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
index 9a779300..3825c09 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
@@ -34,12 +34,12 @@
 import com.android.systemui.statusbar.notification.collection.inflation.BindEventManager
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.NotificationContentView
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinderLogger
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator
-import com.android.systemui.statusbar.policy.HeadsUpManager
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
 import com.android.systemui.util.children
 import java.util.concurrent.ConcurrentHashMap
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt
index 67c53d46..383227d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt
@@ -22,10 +22,10 @@
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.animation.TransitionAnimator
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
+import com.android.systemui.statusbar.notification.headsup.HeadsUpUtil
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.policy.HeadsUpManager
-import com.android.systemui.statusbar.policy.HeadsUpUtil
 import kotlin.math.ceil
 import kotlin.math.max
 
@@ -36,12 +36,12 @@
     private val notificationLaunchAnimationInteractor: NotificationLaunchAnimationInteractor,
     private val notificationListContainer: NotificationListContainer,
     private val headsUpManager: HeadsUpManager,
-    private val jankMonitor: InteractionJankMonitor
+    private val jankMonitor: InteractionJankMonitor,
 ) {
     @JvmOverloads
     fun getAnimatorController(
         notification: ExpandableNotificationRow,
-        onFinishAnimationCallback: Runnable? = null
+        onFinishAnimationCallback: Runnable? = null,
     ): NotificationTransitionAnimatorController {
         return NotificationTransitionAnimatorController(
             notificationLaunchAnimationInteractor,
@@ -49,7 +49,7 @@
             headsUpManager,
             notification,
             jankMonitor,
-            onFinishAnimationCallback
+            onFinishAnimationCallback,
         )
     }
 }
@@ -65,7 +65,7 @@
     private val headsUpManager: HeadsUpManager,
     private val notification: ExpandableNotificationRow,
     private val jankMonitor: InteractionJankMonitor,
-    private val onFinishAnimationCallback: Runnable?
+    private val onFinishAnimationCallback: Runnable?,
 ) : ActivityTransitionAnimator.Controller {
 
     companion object {
@@ -109,7 +109,7 @@
                 left = location[0],
                 right = location[0] + notification.width,
                 topCornerRadius = topCornerRadius,
-                bottomCornerRadius = notification.bottomCornerRadius
+                bottomCornerRadius = notification.bottomCornerRadius,
             )
 
         params.startTranslationZ = notification.translationZ
@@ -177,7 +177,7 @@
             row.entry.key,
             true /* releaseImmediately */,
             animate,
-            reason
+            reason,
         )
     }
 
@@ -224,7 +224,7 @@
     override fun onTransitionAnimationProgress(
         state: TransitionAnimator.State,
         progress: Float,
-        linearProgress: Float
+        linearProgress: Float,
     ) {
         val params = state as LaunchAnimationParameters
         params.progress = progress
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 08ffbf2..7a59f79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -36,14 +36,14 @@
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.KeyguardBypassController.OnBypassStateChangedListener
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController
-import com.android.systemui.statusbar.policy.HeadsUpManager
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
 import com.android.systemui.util.doOnEnd
 import com.android.systemui.util.doOnStart
 import java.io.PrintWriter
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index c487ff5..6b84b6d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -65,6 +65,7 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
 import com.android.systemui.statusbar.notification.icon.IconPack;
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -675,8 +676,8 @@
         return row != null && row.isPinnedAndExpanded();
     }
 
-    public void setRowPinned(boolean pinned) {
-        if (row != null) row.setPinned(pinned);
+    public void setRowPinnedStatus(PinnedStatus pinnedStatus) {
+        if (row != null) row.setPinnedStatus(pinnedStatus);
     }
 
     public boolean isRowHeadsUp() {
@@ -1075,7 +1076,7 @@
         if (PromotedNotificationContentModel.featureFlagEnabled()) {
             return mPromotedNotificationContentModel;
         } else {
-            Log.wtf(TAG, "getting promoted content without feature flag enabled");
+            Log.wtf(TAG, "getting promoted content without feature flag enabled", new Throwable());
             return null;
         }
     }
@@ -1089,7 +1090,7 @@
         if (PromotedNotificationContentModel.featureFlagEnabled()) {
             this.mPromotedNotificationContentModel = promotedNotificationContentModel;
         } else {
-            Log.wtf(TAG, "setting promoted content without feature flag enabled");
+            Log.wtf(TAG, "setting promoted content without feature flag enabled", new Throwable());
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
index 47a0429..733b986 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
@@ -20,13 +20,21 @@
 
 import android.app.Notification;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
 import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt;
 
+import com.google.common.primitives.Booleans;
+
 import javax.inject.Inject;
 
 /**
@@ -44,12 +52,21 @@
 
     @Override
     public void attach(NotifPipeline pipeline) {
+        if (PromotedNotificationUi.isEnabled()) {
+            pipeline.addPromoter(mPromotedOngoingPromoter);
+        }
     }
 
     public NotifSectioner getSectioner() {
         return mNotifSectioner;
     }
 
+    private final NotifPromoter mPromotedOngoingPromoter = new NotifPromoter("PromotedOngoing") {
+        @Override
+        public boolean shouldPromoteToTopLevel(NotificationEntry child) {
+            return isPromotedOngoing(child);
+        }
+    };
 
     /**
      * Puts colorized foreground service and call notifications into its own section.
@@ -64,11 +81,30 @@
             }
             return false;
         }
+
+        private NotifComparator mPreferPromoted = new NotifComparator("PreferPromoted") {
+            @Override
+            public int compare(@NonNull ListEntry o1, @NonNull ListEntry o2) {
+                return -1 * Booleans.compare(
+                        isPromotedOngoing(o1.getRepresentativeEntry()),
+                        isPromotedOngoing(o2.getRepresentativeEntry()));
+            }
+        };
+
+        @Nullable
+        @Override
+        public NotifComparator getComparator() {
+            if (PromotedNotificationUi.isEnabled()) {
+                return mPreferPromoted;
+            } else {
+                return null;
+            }
+        }
     };
 
     /** Determines if the given notification is a colorized or call notification */
     public static boolean isRichOngoing(NotificationEntry entry) {
-        return isColorizedForegroundService(entry) || isCall(entry);
+        return isPromotedOngoing(entry) || isColorizedForegroundService(entry) || isCall(entry);
     }
 
     private static boolean isColorizedForegroundService(NotificationEntry entry) {
@@ -78,6 +114,11 @@
                 && entry.getImportance() > IMPORTANCE_MIN;
     }
 
+    private static boolean isPromotedOngoing(NotificationEntry entry) {
+        // NOTE: isPromotedOngoing already checks the android.app.ui_rich_ongoing flag.
+        return entry != null && entry.getSbn().getNotification().isPromotedOngoing();
+    }
+
     private static boolean isCall(NotificationEntry entry) {
         Notification notification = entry.getSbn().getNotification();
         return entry.getImportance() > IMPORTANCE_MIN
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index c7b47ee..0269b16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -41,13 +41,13 @@
 import com.android.systemui.statusbar.notification.collection.provider.LaunchFullScreenIntentProvider
 import com.android.systemui.statusbar.notification.collection.render.NodeController
 import com.android.systemui.statusbar.notification.dagger.IncomingHeader
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener
 import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider
 import com.android.systemui.statusbar.notification.logKey
 import com.android.systemui.statusbar.notification.shared.GroupHunAnimationFix
 import com.android.systemui.statusbar.notification.stack.BUCKET_HEADS_UP
-import com.android.systemui.statusbar.policy.HeadsUpManager
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.time.SystemClock
 import java.util.function.Consumer
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinator.kt
index 366704e..de6f257 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinator.kt
@@ -18,6 +18,7 @@
 
 import android.annotation.SuppressLint
 import androidx.annotation.VisibleForTesting
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.Dumpable
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dump.DumpManager
@@ -35,8 +36,8 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
 import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor
-import com.android.systemui.statusbar.policy.HeadsUpManager
-import com.android.systemui.statusbar.policy.headsUpEvents
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
+import com.android.systemui.statusbar.notification.headsup.headsUpEvents
 import com.android.systemui.util.asIndenting
 import com.android.systemui.util.indentIfPossible
 import java.io.PrintWriter
@@ -52,7 +53,6 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
 import kotlinx.coroutines.yield
 
 /**
@@ -123,7 +123,7 @@
                     unseenNotifications.removeAll(notificationsSeenWhileLocked)
                     logger.logAllMarkedSeenOnUnlock(
                         seenCount = notificationsSeenWhileLocked.size,
-                        remainingUnseenCount = unseenNotifications.size
+                        remainingUnseenCount = unseenNotifications.size,
                     )
                     notificationsSeenWhileLocked.clear()
                 }
@@ -140,7 +140,7 @@
      * been "seen" while the device is on the keyguard.
      */
     private suspend fun trackSeenNotificationsWhileLocked(
-        notificationsSeenWhileLocked: MutableSet<NotificationEntry>,
+        notificationsSeenWhileLocked: MutableSet<NotificationEntry>
     ) = coroutineScope {
         // Remove removed notifications from the set
         launch {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
index 8660cd1..e75c11d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -45,7 +45,7 @@
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
 import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor;
 import com.android.systemui.statusbar.notification.shared.NotificationMinimalism;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.kotlin.BooleanFlowOperators;
 import com.android.systemui.util.kotlin.JavaAdapter;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
index 5743ab0..07fa6ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
@@ -34,7 +34,7 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 
 import javax.inject.Inject;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 42aadd1..8a1371f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -77,6 +77,10 @@
 import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger;
 import com.android.systemui.statusbar.notification.logging.NotificationPanelLoggerImpl;
 import com.android.systemui.statusbar.notification.logging.dagger.NotificationsLogModule;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationLogger;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationsProvider;
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel;
 import com.android.systemui.statusbar.notification.row.NotificationEntryProcessorFactory;
 import com.android.systemui.statusbar.notification.row.NotificationEntryProcessorFactoryLooperImpl;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -88,7 +92,7 @@
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.ZenModesCleanupStartable;
 
 import dagger.Binds;
@@ -101,6 +105,8 @@
 
 import kotlinx.coroutines.CoroutineScope;
 
+import java.util.Optional;
+
 import javax.inject.Provider;
 
 /**
@@ -308,4 +314,22 @@
     @IntoMap
     @ClassKey(ZenModesCleanupStartable.class)
     CoreStartable bindsZenModesCleanup(ZenModesCleanupStartable zenModesCleanup);
+
+    /**
+     * Provides {@link
+     * com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor} if
+     * one of the relevant feature flags is enabled.
+     */
+    @Provides
+    @SysUISingleton
+    static Optional<PromotedNotificationContentExtractor>
+            providePromotedNotificationContentExtractor(
+                    PromotedNotificationsProvider provider, Context context,
+                    PromotedNotificationLogger logger) {
+        if (PromotedNotificationContentModel.featureFlagEnabled()) {
+            return Optional.of(new PromotedNotificationContentExtractor(provider, context, logger));
+        } else {
+            return Optional.empty();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt
index cf4fb25..3759835 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt
@@ -16,11 +16,11 @@
 package com.android.systemui.statusbar.notification.data
 
 import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository
-import com.android.systemui.statusbar.policy.BaseHeadsUpManager
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManagerImpl
 import dagger.Binds
 import dagger.Module
 
 @Module(includes = [NotificationSettingsRepositoryModule::class])
 interface NotificationDataLayerModule {
-    @Binds fun bindHeadsUpNotificationRepository(impl: BaseHeadsUpManager): HeadsUpRepository
+    @Binds fun bindHeadsUpNotificationRepository(impl: HeadsUpManagerImpl): HeadsUpRepository
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRowRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRowRepository.kt
index 7b40812..2663104 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRowRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRowRepository.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.data.repository
 
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import com.android.systemui.statusbar.notification.shared.HeadsUpRowKey
 import kotlinx.coroutines.flow.StateFlow
 
@@ -31,6 +32,6 @@
     /** A key to identify this row in the view hierarchy. */
     val elementKey: Any
 
-    /** Whether this notification is "pinned", meaning that it should stay on top of the screen. */
-    val isPinned: StateFlow<Boolean>
+    /** This notification's pinning status. */
+    val pinnedStatus: StateFlow<PinnedStatus>
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
index e25127e..8133565 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
@@ -52,7 +52,9 @@
     val topHeadsUpRowIfPinned: Flow<HeadsUpRowKey?> =
         headsUpRepository.topHeadsUpRow
             .flatMapLatest { repository ->
-                repository?.isPinned?.map { pinned -> repository.takeIf { pinned } } ?: flowOf(null)
+                repository?.pinnedStatus?.map { pinnedStatus ->
+                    repository.takeIf { pinnedStatus.isPinned }
+                } ?: flowOf(null)
             }
             .distinctUntilChanged()
 
@@ -64,7 +66,7 @@
                 if (repositories.isNotEmpty()) {
                     val toCombine: List<Flow<Pair<HeadsUpRowRepository, Boolean>>> =
                         repositories.map { repo ->
-                            repo.isPinned.map { isPinned -> repo to isPinned }
+                            repo.pinnedStatus.map { pinnedStatus -> repo to pinnedStatus.isPinned }
                         }
                     combine(toCombine) { pairs -> pairs.toSet() }
                 } else {
@@ -102,7 +104,9 @@
         } else {
             headsUpRepository.activeHeadsUpRows.flatMapLatest { rows ->
                 if (rows.isNotEmpty()) {
-                    combine(rows.map { it.isPinned }) { pins -> pins.any { it } }
+                    combine(rows.map { it.pinnedStatus }) { pinnedStatus ->
+                        pinnedStatus.any { it.isPinned }
+                    }
                 } else {
                     // if the set is empty, there are no flows to combine
                     flowOf(false)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
index 8edbc5e..8bd7a1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
@@ -152,6 +152,13 @@
             } else {
                 null
             }
+        val promotedContent =
+            if (PromotedNotificationContentModel.featureFlagEnabled()) {
+                promotedNotificationContentModel
+            } else {
+                null
+            }
+
         return existingModels.createOrReuse(
             key = key,
             groupKey = sbn.groupKey,
@@ -174,7 +181,7 @@
             isGroupSummary = sbn.notification.isGroupSummary,
             bucket = bucket,
             callType = sbn.toCallType(),
-            promotedContent = promotedNotificationContentModel,
+            promotedContent = promotedContent,
         )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/AvalancheController.kt
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/AvalancheController.kt
index d406ed4..5c7c020 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/AvalancheController.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.statusbar.policy
+package com.android.systemui.statusbar.notification.headsup
 
 import android.os.Handler
 import android.util.Log
@@ -24,29 +24,30 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManagerImpl.HeadsUpEntry
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
-import com.android.systemui.statusbar.policy.BaseHeadsUpManager.HeadsUpEntry
 import com.android.systemui.util.Compile
 import java.io.PrintWriter
 import javax.inject.Inject
 
 /*
  * Control when heads up notifications show during an avalanche where notifications arrive in fast
- * succession, by delaying visual listener side effects and removal handling from BaseHeadsUpManager
+ * succession, by delaying visual listener side effects and removal handling from
+ * [HeadsUpManagerImpl].
  */
 @SysUISingleton
 class AvalancheController
 @Inject
 constructor(
-        dumpManager: DumpManager,
-        private val uiEventLogger: UiEventLogger,
-        private val headsUpManagerLogger: HeadsUpManagerLogger,
-        @Background private val bgHandler: Handler
+    dumpManager: DumpManager,
+    private val uiEventLogger: UiEventLogger,
+    private val headsUpManagerLogger: HeadsUpManagerLogger,
+    @Background private val bgHandler: Handler,
 ) : Dumpable {
 
     private val tag = "AvalancheController"
     private val debug = Compile.IS_DEBUG && Log.isLoggable(tag, Log.DEBUG)
-    var baseEntryMapStr : () -> String = { "baseEntryMapStr not initialized" }
+    var baseEntryMapStr: () -> String = { "baseEntryMapStr not initialized" }
 
     var enableAtRuntime = true
         set(value) {
@@ -119,23 +120,29 @@
 
         if (runnable == null) {
             headsUpManagerLogger.logAvalancheUpdate(
-                caller, isEnabled, key,
-                "Runnable NULL, stop. ${getStateStr()}"
+                caller,
+                isEnabled,
+                key,
+                "Runnable NULL, stop. ${getStateStr()}",
             )
             return
         }
         if (!isEnabled) {
             headsUpManagerLogger.logAvalancheUpdate(
-                caller, isEnabled, key,
-                "NOT ENABLED, run runnable. ${getStateStr()}"
+                caller,
+                isEnabled,
+                key,
+                "NOT ENABLED, run runnable. ${getStateStr()}",
             )
             runnable.run()
             return
         }
         if (entry == null) {
             headsUpManagerLogger.logAvalancheUpdate(
-                caller, isEnabled, key,
-                "Entry NULL, stop. ${getStateStr()}"
+                caller,
+                isEnabled,
+                key,
+                "Entry NULL, stop. ${getStateStr()}",
             )
             return
         }
@@ -168,7 +175,7 @@
                 headsUpEntryShowing!!.updateEntry(
                     /* updatePostTime= */ false,
                     /* updateEarliestRemovalTime= */ false,
-                    /* reason= */ "avalanche duration update"
+                    /* reason= */ "avalanche duration update",
                 )
             }
         }
@@ -192,24 +199,30 @@
 
         if (runnable == null) {
             headsUpManagerLogger.logAvalancheDelete(
-                caller, isEnabled, key,
-                "Runnable NULL, stop. ${getStateStr()}"
+                caller,
+                isEnabled,
+                key,
+                "Runnable NULL, stop. ${getStateStr()}",
             )
             return
         }
         if (!isEnabled) {
             runnable.run()
             headsUpManagerLogger.logAvalancheDelete(
-                caller, isEnabled = false, key,
-                "NOT ENABLED, run runnable. ${getStateStr()}"
+                caller,
+                isEnabled = false,
+                key,
+                "NOT ENABLED, run runnable. ${getStateStr()}",
             )
             return
         }
         if (entry == null) {
             runnable.run()
             headsUpManagerLogger.logAvalancheDelete(
-                caller, isEnabled = true, key,
-                "Entry NULL, run runnable. ${getStateStr()}"
+                caller,
+                isEnabled = true,
+                key,
+                "Entry NULL, run runnable. ${getStateStr()}",
             )
             return
         }
@@ -219,11 +232,9 @@
             if (entry in nextList) nextList.remove(entry)
             uiEventLogger.log(ThrottleEvent.AVALANCHE_THROTTLING_HUN_REMOVED)
             outcome = "remove from next. ${getStateStr()}"
-
         } else if (entry in debugDropSet) {
             debugDropSet.remove(entry)
             outcome = "remove from dropset. ${getStateStr()}"
-
         } else if (isShowing(entry)) {
             previousHunKey = getKey(headsUpEntryShowing)
             // Show the next HUN before removing this one, so that we don't tell listeners
@@ -233,7 +244,6 @@
             showNext()
             runnable.run()
             outcome = "remove showing. ${getStateStr()}"
-
         } else {
             runnable.run()
             outcome = "run runnable for untracked shown HUN. ${getStateStr()}"
@@ -421,13 +431,13 @@
 
     private fun getStateStr(): String {
         return "\navalanche state:" +
-                "\n\tshowing: [${getKey(headsUpEntryShowing)}]" +
-                "\n\tprevious: [$previousHunKey]" +
-                "\n\tnext list: $nextListStr" +
-                "\n\tnext map: $nextMapStr" +
-                "\n\tdropped: $dropSetStr" +
-                "\nBHUM.mHeadsUpEntryMap: " +
-                baseEntryMapStr()
+            "\n\tshowing: [${getKey(headsUpEntryShowing)}]" +
+            "\n\tprevious: [$previousHunKey]" +
+            "\n\tnext list: $nextListStr" +
+            "\n\tnext map: $nextMapStr" +
+            "\n\tdropped: $dropSetStr" +
+            "\nBHUM.mHeadsUpEntryMap: " +
+            baseEntryMapStr()
     }
 
     private val dropSetStr: String
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManager.kt
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManager.kt
index b37194b..424a3c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManager.kt
@@ -1,4 +1,20 @@
-package com.android.systemui.statusbar.policy
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.headsup
 
 import android.graphics.Region
 import com.android.systemui.Dumpable
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerExt.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerExt.kt
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerExt.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerExt.kt
index 5e36750..6525b6f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerExt.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy
+package com.android.systemui.statusbar.notification.headsup
 
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
index f6f567f..99df9f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.notification.headsup;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -55,6 +55,8 @@
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun;
 import com.android.systemui.statusbar.phone.ExpandHeadsUpOnInlineReply;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.ListenerSet;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.kotlin.JavaAdapter;
@@ -84,11 +86,11 @@
  * they simply peek from the top of the screen.
  */
 @SysUISingleton
-public class BaseHeadsUpManager
+public class HeadsUpManagerImpl
         implements HeadsUpManager, HeadsUpRepository, OnHeadsUpChangedListener {
     private static final String TAG = "BaseHeadsUpManager";
     private static final String SETTING_HEADS_UP_SNOOZE_LENGTH_MS = "heads_up_snooze_length_ms";
-
+    private static final String REASON_REORDER_ALLOWED = "mOnReorderingAllowedListener";
     protected final ListenerSet<OnHeadsUpChangedListener> mListeners = new ListenerSet<>();
 
     protected final Context mContext;
@@ -180,7 +182,7 @@
     }
 
     @Inject
-    public BaseHeadsUpManager(
+    public HeadsUpManagerImpl(
             @NonNull final Context context,
             HeadsUpManagerLogger logger,
             StatusBarStateController statusBarStateController,
@@ -403,9 +405,11 @@
         }
         if (shouldHeadsUpAgain) {
             headsUpEntry.updateEntry(true /* updatePostTime */, "updateNotification");
+            PinnedStatus pinnedStatus = shouldHeadsUpBecomePinned(headsUpEntry.mEntry)
+                    ? PinnedStatus.PinnedBySystem
+                    : PinnedStatus.NotPinned;
             if (headsUpEntry != null) {
-                setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(headsUpEntry.mEntry),
-                        "updateNotificationInternal");
+                setEntryPinned(headsUpEntry, pinnedStatus, "updateNotificationInternal");
             }
         }
     }
@@ -417,7 +421,7 @@
 
     @Override
     public boolean shouldSwallowClick(@NonNull String key) {
-        BaseHeadsUpManager.HeadsUpEntry entry = getHeadsUpEntry(key);
+        HeadsUpManagerImpl.HeadsUpEntry entry = getHeadsUpEntry(key);
         return entry != null && mSystemClock.elapsedRealtime() < entry.mPostTime;
     }
 
@@ -560,15 +564,16 @@
     }
 
     protected void setEntryPinned(
-            @NonNull BaseHeadsUpManager.HeadsUpEntry headsUpEntry, boolean isPinned,
+            @NonNull HeadsUpManagerImpl.HeadsUpEntry headsUpEntry, PinnedStatus pinnedStatus,
             String reason) {
-        mLogger.logSetEntryPinned(headsUpEntry.mEntry, isPinned, reason);
+        mLogger.logSetEntryPinned(headsUpEntry.mEntry, pinnedStatus, reason);
         NotificationEntry entry = headsUpEntry.mEntry;
+        boolean isPinned = pinnedStatus.isPinned();
         if (!isPinned) {
             headsUpEntry.mWasUnpinned = true;
         }
-        if (headsUpEntry.isRowPinned() != isPinned) {
-            headsUpEntry.setRowPinned(isPinned);
+        if (headsUpEntry.getPinnedStatus().getValue() != pinnedStatus) {
+            headsUpEntry.setRowPinnedStatus(pinnedStatus);
             updatePinnedMode();
             if (isPinned && entry.getSbn() != null) {
                mUiEventLogger.logWithInstanceId(
@@ -594,8 +599,10 @@
         NotificationEntry entry = headsUpEntry.mEntry;
         entry.setHeadsUp(true);
 
-        final boolean shouldPin = shouldHeadsUpBecomePinned(entry);
-        setEntryPinned(headsUpEntry, shouldPin, "onEntryAdded");
+        final PinnedStatus pinnedStatus = shouldHeadsUpBecomePinned(entry)
+                ? PinnedStatus.PinnedBySystem
+                : PinnedStatus.NotPinned;
+        setEntryPinned(headsUpEntry, pinnedStatus, "onEntryAdded");
         EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 1 /* visible */);
         for (OnHeadsUpChangedListener listener : mListeners) {
             listener.onHeadsUpStateChanged(entry, true);
@@ -633,7 +640,7 @@
             }
             entry.demoteStickyHun();
             mHeadsUpEntryMap.remove(key);
-            onEntryRemoved(finalHeadsUpEntry);
+            onEntryRemoved(finalHeadsUpEntry, reason);
             // TODO(b/328390331) move accessibility events to the view layer
             entry.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
             if (NotificationThrottleHun.isEnabled()) {
@@ -648,11 +655,12 @@
     /**
      * Manager-specific logic that should occur when an entry is removed.
      * @param headsUpEntry entry removed
+     * @param reason why onEntryRemoved was called
      */
-    protected void onEntryRemoved(HeadsUpEntry headsUpEntry) {
+    protected void onEntryRemoved(HeadsUpEntry headsUpEntry, String reason) {
         NotificationEntry entry = headsUpEntry.mEntry;
         entry.setHeadsUp(false);
-        setEntryPinned(headsUpEntry, false /* isPinned */, "onEntryRemoved");
+        setEntryPinned(headsUpEntry, PinnedStatus.NotPinned, "onEntryRemoved");
         EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 0 /* visible */);
         mLogger.logNotificationActuallyRemoved(entry);
         for (OnHeadsUpChangedListener listener : mListeners) {
@@ -664,10 +672,17 @@
         updateTopHeadsUpFlow();
         updateHeadsUpFlow();
         if (NotificationThrottleHun.isEnabled()) {
-            if (headsUpEntry.mEntry != null) {
-                if (mEntriesToRemoveWhenReorderingAllowed.contains(headsUpEntry.mEntry)) {
-                    mEntriesToRemoveWhenReorderingAllowed.remove(headsUpEntry.mEntry);
-                }
+            NotificationEntry notifEntry = headsUpEntry.mEntry;
+            if (notifEntry == null) {
+                return;
+            }
+            // If reorder was just allowed and we called onEntryRemoved while iterating over
+            // mEntriesToRemoveWhenReorderingAllowed, we should not remove from this list (and cause
+            // ArrayIndexOutOfBoundsException). We don't need to in this case anyway, because we
+            // clear mEntriesToRemoveWhenReorderingAllowed after removing these entries.
+            if (!reason.equals(REASON_REORDER_ALLOWED)
+                    && mEntriesToRemoveWhenReorderingAllowed.contains(notifEntry)) {
+                mEntriesToRemoveWhenReorderingAllowed.remove(notifEntry);
             }
         }
     }
@@ -954,7 +969,7 @@
             Runnable runnable = () -> {
                 mLogger.logUnpinEntry(key);
 
-                setEntryPinned(headsUpEntry, false /* isPinned */, "unpinAll");
+                setEntryPinned(headsUpEntry, PinnedStatus.NotPinned, "unpinAll");
                 // maybe it got un sticky
                 headsUpEntry.updateEntry(false /* updatePostTime */, "unpinAll");
 
@@ -1135,7 +1150,8 @@
                 && Notification.CATEGORY_CALL.equals(n.category));
     }
 
-    private final OnReorderingAllowedListener mOnReorderingAllowedListener = () -> {
+    @VisibleForTesting
+    public final OnReorderingAllowedListener mOnReorderingAllowedListener = () -> {
         if (NotificationThrottleHun.isEnabled()) {
             mAvalancheController.setEnableAtRuntime(true);
             if (mEntriesToRemoveWhenReorderingAllowed.isEmpty()) {
@@ -1146,7 +1162,7 @@
         for (NotificationEntry entry : mEntriesToRemoveWhenReorderingAllowed) {
             if (entry != null && isHeadsUpEntry(entry.getKey())) {
                 // Maybe the heads-up was removed already
-                removeEntry(entry.getKey(), "mOnReorderingAllowedListener");
+                removeEntry(entry.getKey(), REASON_REORDER_ALLOWED);
             }
         }
         mEntriesToRemoveWhenReorderingAllowed.clear();
@@ -1224,7 +1240,8 @@
         @Nullable private Runnable mCancelRemoveRunnable;
 
         private boolean mGutsShownPinned;
-        private final MutableStateFlow<Boolean> mIsPinned = StateFlowKt.MutableStateFlow(false);
+        private final MutableStateFlow<PinnedStatus> mPinnedStatus =
+                StateFlowKt.MutableStateFlow(PinnedStatus.NotPinned);
 
         /**
          * If the time this entry has been on was extended
@@ -1260,8 +1277,8 @@
 
         @Override
         @NonNull
-        public StateFlow<Boolean> isPinned() {
-            return mIsPinned;
+        public StateFlow<PinnedStatus> getPinnedStatus() {
+            return mPinnedStatus;
         }
 
         /** Attach a NotificationEntry. */
@@ -1291,9 +1308,9 @@
             return mEntry != null && mEntry.isRowPinned();
         }
 
-        protected void setRowPinned(boolean pinned) {
-            if (mEntry != null) mEntry.setRowPinned(pinned);
-            mIsPinned.setValue(pinned);
+        protected void setRowPinnedStatus(PinnedStatus pinnedStatus) {
+            if (mEntry != null) mEntry.setRowPinnedStatus(pinnedStatus);
+            mPinnedStatus.setValue(pinnedStatus);
         }
 
         /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLogger.kt
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLogger.kt
index 600270c..80225c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLogger.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy
+package com.android.systemui.statusbar.notification.headsup
 
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel.INFO
@@ -52,7 +52,7 @@
         caller: String,
         isEnabled: Boolean,
         notifEntryKey: String,
-        outcome: String
+        outcome: String,
     ) {
         buffer.log(
             TAG,
@@ -63,7 +63,7 @@
                 str3 = outcome
                 bool1 = isEnabled
             },
-            { "$str1\n\t=> AC[isEnabled:$bool1] update: $str2\n\t=> $str3" }
+            { "$str1\n\t=> AC[isEnabled:$bool1] update: $str2\n\t=> $str3" },
         )
     }
 
@@ -71,7 +71,7 @@
         caller: String,
         isEnabled: Boolean,
         notifEntryKey: String,
-        outcome: String
+        outcome: String,
     ) {
         buffer.log(
             TAG,
@@ -82,7 +82,7 @@
                 str3 = outcome
                 bool1 = isEnabled
             },
-            { "$str1\n\t=> AC[isEnabled:$bool1] delete: $str2\n\t=> $str3" }
+            { "$str1\n\t=> AC[isEnabled:$bool1] delete: $str2\n\t=> $str3" },
         )
     }
 
@@ -99,7 +99,7 @@
                 long1 = delayMillis
                 str2 = reason
             },
-            { "schedule auto remove of $str1 in $long1 ms reason: $str2" }
+            { "schedule auto remove of $str1 in $long1 ms reason: $str2" },
         )
     }
 
@@ -111,7 +111,7 @@
                 str1 = entry.logKey
                 str2 = reason
             },
-            { "request: reschedule auto remove of $str1 reason: $str2" }
+            { "request: reschedule auto remove of $str1 reason: $str2" },
         )
     }
 
@@ -124,7 +124,7 @@
                 long1 = delayMillis
                 str2 = reason
             },
-            { "reschedule auto remove of $str1 in $long1 ms reason: $str2" }
+            { "reschedule auto remove of $str1 in $long1 ms reason: $str2" },
         )
     }
 
@@ -136,7 +136,7 @@
                 str1 = entry.logKey
                 str2 = reason ?: "unknown"
             },
-            { "request: cancel auto remove of $str1 reason: $str2" }
+            { "request: cancel auto remove of $str1 reason: $str2" },
         )
     }
 
@@ -148,7 +148,7 @@
                 str1 = entry.logKey
                 str2 = reason ?: "unknown"
             },
-            { "cancel auto remove of $str1 reason: $str2" }
+            { "cancel auto remove of $str1 reason: $str2" },
         )
     }
 
@@ -161,7 +161,7 @@
                 str2 = reason
                 bool1 = isWaiting
             },
-            { "request: $str2 => remove entry $str1 isWaiting: $isWaiting" }
+            { "request: $str2 => remove entry $str1 isWaiting: $isWaiting" },
         )
     }
 
@@ -174,7 +174,7 @@
                 str2 = reason
                 bool1 = isWaiting
             },
-            { "$str2 => remove entry $str1 isWaiting: $isWaiting" }
+            { "$str2 => remove entry $str1 isWaiting: $isWaiting" },
         )
     }
 
@@ -190,7 +190,7 @@
         key: String,
         releaseImmediately: Boolean,
         isWaiting: Boolean,
-        reason: String
+        reason: String,
     ) {
         buffer.log(
             TAG,
@@ -204,7 +204,7 @@
             {
                 "remove notification $str1 releaseImmediately: $bool1 isWaiting: $bool2 " +
                     "reason: $str2"
-            }
+            },
         )
     }
 
@@ -216,7 +216,7 @@
                 str1 = logKey(key)
                 str2 = reason
             },
-            { "remove notification $str1 when headsUpEntry is null, reason: $str2" }
+            { "remove notification $str1 when headsUpEntry is null, reason: $str2" },
         )
     }
 
@@ -233,7 +233,7 @@
                 bool1 = alert
                 bool2 = hasEntry
             },
-            { "request: update notification $str1 alert: $bool1 hasEntry: $bool2" }
+            { "request: update notification $str1 alert: $bool1 hasEntry: $bool2" },
         )
     }
 
@@ -246,7 +246,7 @@
                 bool1 = alert
                 bool2 = hasEntry
             },
-            { "update notification $str1 alert: $bool1 hasEntry: $bool2" }
+            { "update notification $str1 alert: $bool1 hasEntry: $bool2" },
         )
     }
 
@@ -259,7 +259,7 @@
                 bool1 = updatePostTime
                 str2 = reason ?: "unknown"
             },
-            { "update entry $str1 updatePostTime: $bool1 reason: $str2" }
+            { "update entry $str1 updatePostTime: $bool1 reason: $str2" },
         )
     }
 
@@ -268,20 +268,20 @@
             TAG,
             INFO,
             { int1 = packageSnoozeLengthMs },
-            { "snooze length changed: ${int1}ms" }
+            { "snooze length changed: ${int1}ms" },
         )
     }
 
-    fun logSetEntryPinned(entry: NotificationEntry, isPinned: Boolean, reason: String) {
+    fun logSetEntryPinned(entry: NotificationEntry, pinnedStatus: PinnedStatus, reason: String) {
         buffer.log(
             TAG,
             VERBOSE,
             {
                 str1 = entry.logKey
-                bool1 = isPinned
                 str2 = reason
+                str3 = pinnedStatus.name
             },
-            { "$str2 => set entry pinned $str1 pinned: $bool1" }
+            { "$str2 => set entry pinned $str1 pinned: $str3" },
         )
     }
 
@@ -290,16 +290,12 @@
             TAG,
             INFO,
             { bool1 = hasPinnedNotification },
-            { "has pinned notification changed to $bool1" }
+            { "has pinned notification changed to $bool1" },
         )
     }
 
     fun logRemoveEntryAfterExpand(entry: NotificationEntry) {
-        buffer.log(TAG, VERBOSE, {
-            str1 = entry.logKey
-        }, {
-            "remove entry after expand: $str1"
-        })
+        buffer.log(TAG, VERBOSE, { str1 = entry.logKey }, { "remove entry after expand: $str1" })
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpModule.kt
similarity index 74%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpModule.kt
index 83551e9..f9502ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpModule.kt
@@ -14,15 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone
+package com.android.systemui.statusbar.notification.headsup
 
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.policy.BaseHeadsUpManager
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import dagger.Binds
 import dagger.Module
 
 @Module
 interface HeadsUpModule {
-    @Binds @SysUISingleton fun bindsHeadsUpManager(hum: BaseHeadsUpManager): HeadsUpManager
+    @Binds @SysUISingleton fun bindsHeadsUpManager(hum: HeadsUpManagerImpl): HeadsUpManager
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeadsUpNotificationViewControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpNotificationViewControllerEmptyImpl.kt
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/HeadsUpNotificationViewControllerEmptyImpl.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpNotificationViewControllerEmptyImpl.kt
index 021d301..84754e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeadsUpNotificationViewControllerEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpNotificationViewControllerEmptyImpl.kt
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification
+package com.android.systemui.statusbar.notification.headsup
 
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
-import com.android.systemui.statusbar.notification.HeadsUpTouchHelper.HeadsUpNotificationViewController
+import com.android.systemui.statusbar.notification.headsup.HeadsUpTouchHelper.HeadsUpNotificationViewController
 
 /** Empty impl of [HeadsUpNotificationViewController] for use with Scene Container */
 class HeadsUpNotificationViewControllerEmptyImpl : HeadsUpNotificationViewController {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpTouchHelper.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/HeadsUpTouchHelper.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpTouchHelper.java
index a614638..3b6b9ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpTouchHelper.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification;
+package com.android.systemui.statusbar.notification.headsup;
 
 import android.content.Context;
 import android.os.RemoteException;
@@ -27,7 +27,6 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 /**
  * A helper class to handle touches on the heads-up views.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpUtil.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpUtil.java
index f4a1975..40da232 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpUtil.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.notification.headsup;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/OnHeadsUpChangedListener.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/OnHeadsUpChangedListener.java
index de3bf04..b1fd784 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/OnHeadsUpChangedListener.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.notification.headsup;
 
 import android.annotation.NonNull;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/PinnedStatus.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/PinnedStatus.kt
new file mode 100644
index 0000000..af18054
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/PinnedStatus.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.headsup
+
+/**
+ * A status representing whether and how a notification is pinned.
+ *
+ * @property isPinned true if a notification should be "pinned", meaning that a notification should
+ *   stay on top of the screen.
+ */
+enum class PinnedStatus(val isPinned: Boolean) {
+    /** This notification is not pinned. */
+    NotPinned(isPinned = false),
+    /**
+     * This notification is pinned by the system - likely because when the notification was added or
+     * updated, it required pinning.
+     */
+    PinnedBySystem(isPinned = true),
+    /**
+     * This notification is pinned because the user did an explicit action to pin it (like tapping
+     * the notification chip in the status bar).
+     */
+    // TODO(b/364653005): Use this status when a user taps the notification chip.
+    PinnedByUser(isPinned = true),
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/StatusBarHeadsUpChangeListener.java
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/StatusBarHeadsUpChangeListener.java
index 7145ffe..23eb507 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/StatusBarHeadsUpChangeListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.statusbar.notification.headsup;
 
 import com.android.systemui.CoreStartable;
 import com.android.systemui.dagger.SysUISingleton;
@@ -26,14 +26,13 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
 
 import javax.inject.Inject;
 
 /**
- * Ties the status bar to {@link com.android.systemui.statusbar.policy.HeadsUpManager}.
+ * Ties the status bar to {@link HeadsUpManager}.
  */
 @SysUISingleton
 public class StatusBarHeadsUpChangeListener implements OnHeadsUpChangedListener, CoreStartable {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
index ec0827b..caa6ccf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
@@ -52,13 +52,13 @@
 import com.android.systemui.shared.notifications.domain.interactor.NotificationSettingsInteractor
 import com.android.systemui.statusbar.StatusBarState.SHADE
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.MAX_HUN_WHEN_AGE_MS
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.HUN_SUPPRESSED_OLD_WHEN
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PEEK
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE
 import com.android.systemui.statusbar.policy.BatteryController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.util.NotificationChannels
 import com.android.systemui.util.settings.GlobalSettings
 import com.android.systemui.util.settings.SystemSettings
@@ -102,7 +102,7 @@
         globalSettings.registerContentObserverSync(
             globalSettings.getUriFor(HEADS_UP_NOTIFICATIONS_ENABLED),
             /* notifyForDescendants = */ true,
-            observer
+            observer,
         )
 
         // QQQ: Do we need to register for SETTING_HEADS_UP_TICKER? It seems unused.
@@ -139,7 +139,7 @@
 
 class PeekAlreadyBubbledSuppressor(
     private val statusBarStateController: StatusBarStateController,
-    private val bubbles: Optional<Bubbles>
+    private val bubbles: Optional<Bubbles>,
 ) : VisualInterruptionFilter(types = setOf(PEEK), reason = "already bubbled") {
     override fun shouldSuppress(entry: NotificationEntry) =
         when {
@@ -164,7 +164,7 @@
 
 class PeekDeviceNotInUseSuppressor(
     private val powerManager: PowerManager,
-    private val statusBarStateController: StatusBarStateController
+    private val statusBarStateController: StatusBarStateController,
 ) : VisualInterruptionCondition(types = setOf(PEEK), reason = "device not in use") {
     override fun shouldSuppress() =
         when {
@@ -177,7 +177,7 @@
     VisualInterruptionFilter(
         types = setOf(PEEK),
         reason = "has old `when`",
-        uiEventId = HUN_SUPPRESSED_OLD_WHEN
+        uiEventId = HUN_SUPPRESSED_OLD_WHEN,
     ) {
     private fun whenAge(entry: NotificationEntry) =
         systemClock.currentTimeMillis() - entry.sbn.notification.getWhen()
@@ -206,7 +206,7 @@
 class PulseLockscreenVisibilityPrivateSuppressor :
     VisualInterruptionFilter(
         types = setOf(PULSE),
-        reason = "hidden by lockscreen visibility override"
+        reason = "hidden by lockscreen visibility override",
     ) {
     override fun shouldSuppress(entry: NotificationEntry) =
         entry.ranking.lockscreenVisibilityOverride == VISIBILITY_PRIVATE
@@ -220,7 +220,7 @@
 class HunGroupAlertBehaviorSuppressor :
     VisualInterruptionFilter(
         types = setOf(PEEK, PULSE),
-        reason = "suppressive group alert behavior"
+        reason = "suppressive group alert behavior",
     ) {
     override fun shouldSuppress(entry: NotificationEntry) =
         entry.sbn.let { it.isGroup && it.notification.suppressAlertingDueToGrouping() }
@@ -282,11 +282,7 @@
     private val notificationManager: NotificationManager,
     private val logger: VisualInterruptionDecisionLogger,
     private val systemSettings: SystemSettings,
-) :
-    VisualInterruptionFilter(
-        types = setOf(PEEK, PULSE),
-        reason = "avalanche",
-    ) {
+) : VisualInterruptionFilter(types = setOf(PEEK, PULSE), reason = "avalanche") {
     val TAG = "AvalancheSuppressor"
 
     private val prefs = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE)
@@ -324,7 +320,7 @@
         ALLOW_FSI_WITH_PERMISSION_ON,
         ALLOW_COLORIZED,
         ALLOW_EMERGENCY,
-        SUPPRESS
+        SUPPRESS,
     }
 
     enum class AvalancheEvent(private val id: Int) : UiEventLogger.UiEventEnum {
@@ -354,6 +350,7 @@
         AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_CAR_EMERGENCY(1868),
         @UiEvent(doc = "HUN allowed during avalanche because it is a car warning")
         AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_CAR_WARNING(1869);
+
         override fun getId(): Int {
             return id
         }
@@ -399,7 +396,7 @@
         val bundle = Bundle()
         bundle.putString(
             Notification.EXTRA_SUBSTITUTE_APP_NAME,
-            context.getString(com.android.internal.R.string.android_system_label)
+            context.getString(com.android.internal.R.string.android_system_label),
         )
 
         val builder =
@@ -452,7 +449,8 @@
 
         if (entry.sbn.notification.category == CATEGORY_CAR_EMERGENCY) {
             uiEventLogger.log(
-                    AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_CAR_EMERGENCY)
+                AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_CAR_EMERGENCY
+            )
             return State.ALLOW_CATEGORY_CAR_EMERGENCY
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index 450067a..f586051 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -47,7 +47,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.EventLog;
 import com.android.systemui.util.settings.GlobalSettings;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
index 52336be..b831b94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
@@ -32,6 +32,7 @@
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.shared.notifications.domain.interactor.NotificationSettingsInteractor
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.Decision
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.FullScreenIntentDecision
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionSuppressor.EventLogData
@@ -41,7 +42,6 @@
 import com.android.systemui.statusbar.notification.shared.NotificationAvalancheSuppression
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.EventLog
 import com.android.systemui.util.settings.GlobalSettings
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
new file mode 100644
index 0000000..f400d60
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.promoted
+
+import android.app.Notification
+import android.app.Notification.BigPictureStyle
+import android.app.Notification.BigTextStyle
+import android.app.Notification.CallStyle
+import android.app.Notification.EXTRA_CHRONOMETER_COUNT_DOWN
+import android.app.Notification.EXTRA_SUB_TEXT
+import android.app.Notification.EXTRA_TEXT
+import android.app.Notification.EXTRA_TITLE
+import android.app.Notification.ProgressStyle
+import android.content.Context
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When
+import javax.inject.Inject
+
+@SysUISingleton
+class PromotedNotificationContentExtractor
+@Inject
+constructor(
+    private val promotedNotificationsProvider: PromotedNotificationsProvider,
+    private val context: Context,
+    private val logger: PromotedNotificationLogger,
+) {
+    fun extractContent(
+        entry: NotificationEntry,
+        recoveredBuilder: Notification.Builder,
+    ): PromotedNotificationContentModel? {
+        if (!PromotedNotificationContentModel.featureFlagEnabled()) {
+            logger.logExtractionSkipped(entry, "feature flags disabled")
+            return null
+        }
+
+        if (!promotedNotificationsProvider.shouldPromote(entry)) {
+            logger.logExtractionSkipped(entry, "shouldPromote returned false")
+            return null
+        }
+
+        val notification = entry.sbn.notification
+        if (notification == null) {
+            logger.logExtractionFailed(entry, "entry.sbn.notification is null")
+            return null
+        }
+
+        val contentBuilder = PromotedNotificationContentModel.Builder(entry.key)
+
+        // TODO: Pitch a fit if style is unsupported or mandatory fields are missing once
+        // FLAG_PROMOTED_ONGOING is set reliably and we're not testing status bar chips.
+
+        contentBuilder.skeletonSmallIcon = entry.icons.aodIcon?.sourceIcon
+        contentBuilder.appName = notification.loadHeaderAppName(context)
+        contentBuilder.subText = notification.subText()
+        contentBuilder.time = notification.extractWhen()
+        contentBuilder.lastAudiblyAlertedMs = entry.lastAudiblyAlertedMs
+        contentBuilder.profileBadgeResId = null // TODO
+        contentBuilder.title = notification.title()
+        contentBuilder.text = notification.text()
+        contentBuilder.skeletonLargeIcon = null // TODO
+
+        recoveredBuilder.style?.extractContent(contentBuilder)
+            ?: run { contentBuilder.style = Style.Ineligible }
+
+        return contentBuilder.build().also { logger.logExtractionSucceeded(entry, it) }
+    }
+}
+
+private fun Notification.title(): CharSequence? = extras?.getCharSequence(EXTRA_TITLE)
+
+private fun Notification.text(): CharSequence? = extras?.getCharSequence(EXTRA_TEXT)
+
+private fun Notification.subText(): String? = extras?.getString(EXTRA_SUB_TEXT)
+
+private fun Notification.chronometerCountDown(): Boolean =
+    extras?.getBoolean(EXTRA_CHRONOMETER_COUNT_DOWN, /* defaultValue= */ false) ?: false
+
+private fun Notification.extractWhen(): When? {
+    val time = `when`
+    val showsTime = showsTime()
+    val showsChronometer = showsChronometer()
+    val countDown = chronometerCountDown()
+
+    return when {
+        showsTime -> When(time, When.Mode.Absolute)
+        showsChronometer -> When(time, if (countDown) When.Mode.CountDown else When.Mode.CountUp)
+        else -> null
+    }
+}
+
+private fun Notification.Style.extractContent(
+    contentBuilder: PromotedNotificationContentModel.Builder
+) {
+    contentBuilder.style =
+        when (this) {
+            is BigPictureStyle -> {
+                extractContent(contentBuilder)
+                Style.BigPicture
+            }
+
+            is BigTextStyle -> {
+                extractContent(contentBuilder)
+                Style.BigText
+            }
+
+            is CallStyle -> {
+                extractContent(contentBuilder)
+                Style.Call
+            }
+
+            is ProgressStyle -> {
+                extractContent(contentBuilder)
+                Style.Progress
+            }
+
+            else -> Style.Ineligible
+        }
+}
+
+private fun BigPictureStyle.extractContent(
+    contentBuilder: PromotedNotificationContentModel.Builder
+) {
+    // TODO?
+}
+
+private fun BigTextStyle.extractContent(contentBuilder: PromotedNotificationContentModel.Builder) {
+    // TODO?
+}
+
+private fun CallStyle.extractContent(contentBuilder: PromotedNotificationContentModel.Builder) {
+    contentBuilder.personIcon = null // TODO
+    contentBuilder.personName = null // TODO
+    contentBuilder.verificationIcon = null // TODO
+    contentBuilder.verificationText = null // TODO
+}
+
+private fun ProgressStyle.extractContent(contentBuilder: PromotedNotificationContentModel.Builder) {
+    // TODO: Create NotificationProgressModel.toSkeleton, or something similar.
+    contentBuilder.progress = createProgressModel(0xffffffff.toInt(), 0x00000000)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt
new file mode 100644
index 0000000..13ad141
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.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.statusbar.notification.promoted
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel.ERROR
+import com.android.systemui.log.core.LogLevel.INFO
+import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
+import javax.inject.Inject
+
+class PromotedNotificationLogger
+@Inject
+constructor(@NotificationLog private val buffer: LogBuffer) {
+    fun logExtractionSkipped(entry: NotificationEntry, reason: String) {
+        buffer.log(
+            EXTRACTION_TAG,
+            INFO,
+            {
+                str1 = entry.logKey
+                str2 = reason
+            },
+            { "extraction skipped: $str2 for $str1" },
+        )
+    }
+
+    fun logExtractionFailed(entry: NotificationEntry, reason: String) {
+        buffer.log(
+            EXTRACTION_TAG,
+            ERROR,
+            {
+                str1 = entry.logKey
+                str2 = reason
+            },
+            { "extraction failed: $str2 for $str1" },
+        )
+    }
+
+    fun logExtractionSucceeded(
+        entry: NotificationEntry,
+        content: PromotedNotificationContentModel,
+    ) {
+        buffer.log(
+            EXTRACTION_TAG,
+            INFO,
+            {
+                str1 = entry.logKey
+                str2 = content.toString()
+            },
+            { "extraction succeeded: $str2 for $str1" },
+        )
+    }
+}
+
+private const val EXTRACTION_TAG = "PromotedNotificationContentExtractor"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProvider.kt
index 691dc6f..947d9e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProvider.kt
@@ -19,6 +19,7 @@
 import android.app.Notification.FLAG_PROMOTED_ONGOING
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 import javax.inject.Inject
 
 /** A provider for making decisions on which notifications should be promoted. */
@@ -30,7 +31,7 @@
 @SysUISingleton
 open class PromotedNotificationsProviderImpl @Inject constructor() : PromotedNotificationsProvider {
     override fun shouldPromote(entry: NotificationEntry): Boolean {
-        if (!PromotedNotificationUi.isEnabled) {
+        if (!PromotedNotificationContentModel.featureFlagEnabled()) {
             return false
         }
         return (entry.sbn.notification.flags and FLAG_PROMOTED_ONGOING) != 0
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java
new file mode 100644
index 0000000..aad618d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row;
+
+import android.app.INotificationManager;
+import android.app.NotificationChannel;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.RemoteException;
+import android.service.notification.NotificationAssistantService;
+import android.service.notification.StatusBarNotification;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.AssistantFeedbackController;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import java.util.List;
+
+/**
+ * The guts of a notification revealed when performing a long press.
+ */
+public class BundleNotificationInfo extends NotificationInfo {
+    private static final String TAG = "BundleNotifInfoGuts";
+
+    public BundleNotificationInfo(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void bindNotification(
+            PackageManager pm,
+            INotificationManager iNotificationManager,
+            OnUserInteractionCallback onUserInteractionCallback,
+            ChannelEditorDialogController channelEditorDialogController,
+            String pkg,
+            NotificationChannel notificationChannel,
+            NotificationEntry entry,
+            OnSettingsClickListener onSettingsClick,
+            OnAppSettingsClickListener onAppSettingsClick,
+            UiEventLogger uiEventLogger,
+            boolean isDeviceProvisioned,
+            boolean isNonblockable,
+            boolean wasShownHighPriority,
+            AssistantFeedbackController assistantFeedbackController,
+            MetricsLogger metricsLogger) throws RemoteException {
+        super.bindNotification(pm, iNotificationManager, onUserInteractionCallback,
+                channelEditorDialogController, pkg, notificationChannel, entry, onSettingsClick,
+                onAppSettingsClick, uiEventLogger, isDeviceProvisioned, isNonblockable,
+                wasShownHighPriority, assistantFeedbackController, metricsLogger);
+
+        // Additionally, bind the feedback button.
+        ComponentName assistant = iNotificationManager.getAllowedNotificationAssistant();
+        bindFeedback(entry.getSbn(), pm, assistant, onAppSettingsClick);
+    }
+
+    protected void bindFeedback(StatusBarNotification sbn, PackageManager pm,
+            ComponentName assistant,
+            NotificationInfo.OnAppSettingsClickListener appSettingsClickListener) {
+        View feedbackButton = findViewById(R.id.notification_guts_bundle_feedback);
+        // If the assistant component is null, don't show the feedback button and finish.
+        if (assistant == null) {
+            feedbackButton.setVisibility(GONE);
+            return;
+        }
+        // Otherwise we extract the assistant package name.
+        String assistantPkg = assistant.getPackageName();
+
+        feedbackButton.setOnClickListener(getBundleFeedbackClickListener(sbn, pm, assistantPkg,
+                appSettingsClickListener));
+        feedbackButton.setVisibility(feedbackButton.hasOnClickListeners() ? VISIBLE : GONE);
+    }
+
+    private OnClickListener getBundleFeedbackClickListener(StatusBarNotification sbn,
+            PackageManager pm, String assistantPkg,
+            NotificationInfo.OnAppSettingsClickListener appSettingsClickListener) {
+        Intent feedbackIntent = getBundleFeedbackIntent(pm, assistantPkg, sbn.getKey());
+        if (feedbackIntent != null) {
+            return ((View view) -> {
+                appSettingsClickListener.onClick(view, feedbackIntent);
+            });
+        }
+        return null;
+    }
+
+    private Intent getBundleFeedbackIntent(PackageManager pm, String packageName, String key) {
+        Intent intent = new Intent(
+                NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS)
+                .setPackage(packageName);
+        final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
+                intent,
+                PackageManager.MATCH_DEFAULT_ONLY
+        );
+        if (resolveInfos == null || resolveInfos.size() == 0 || resolveInfos.get(0) == null) {
+            return null;
+        }
+        final ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
+        intent.setClassName(activityInfo.packageName, activityInfo.name);
+        intent.putExtra(NotificationAssistantService.EXTRA_NOTIFICATION_KEY, key);
+        return intent;
+    }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d1de6be..b7ab996 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -19,6 +19,7 @@
 import static android.app.Notification.Action.SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL;
 
+import static com.android.systemui.flags.Flags.ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE;
 import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.PARENT_DISMISSED;
 import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
 import static com.android.systemui.statusbar.policy.RemoteInputView.FOCUS_ANIMATION_MIN_SCALE;
@@ -35,6 +36,7 @@
 import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.AnimationDrawable;
 import android.graphics.drawable.Drawable;
@@ -75,8 +77,8 @@
 import com.android.internal.util.ContrastColorUtil;
 import com.android.internal.widget.CachingIconView;
 import com.android.internal.widget.CallLayout;
+import com.android.systemui.Flags;
 import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.flags.RefactorFlag;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.PluginListener;
@@ -100,6 +102,7 @@
 import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
 import com.android.systemui.statusbar.notification.logging.NotificationCounters;
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
@@ -107,6 +110,7 @@
 import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationCompactMessagingTemplateViewWrapper;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
+import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
 import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
 import com.android.systemui.statusbar.notification.shared.TransparentHeaderFix;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
@@ -117,13 +121,14 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.SwipeableView;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
 import com.android.systemui.statusbar.policy.RemoteInputView;
 import com.android.systemui.statusbar.policy.SmartReplyConstants;
 import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
 import com.android.systemui.util.Compile;
 import com.android.systemui.util.DumpUtilsKt;
+import com.android.systemui.util.ListenerSet;
 import com.android.systemui.wmshell.BubblesManager;
 
 import java.io.PrintWriter;
@@ -276,7 +281,7 @@
     private NotificationMenuRowPlugin mMenuRow;
     private ViewStub mGutsStub;
     private boolean mIsSystemChildExpanded;
-    private boolean mIsPinned;
+    private PinnedStatus mPinnedStatus = PinnedStatus.NotPinned;
     private boolean mExpandAnimationRunning;
     private AboveShelfChangedListener mAboveShelfChangedListener;
     private HeadsUpManager mHeadsUpManager;
@@ -293,7 +298,7 @@
 
     private static boolean shouldSimulateSlowMeasure() {
         return Compile.IS_DEBUG && RefactorFlag.forView(
-                Flags.ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE).isEnabled();
+                ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE).isEnabled();
     }
 
     private static final String SLOW_MEASURE_SIMULATE_DELAY_PROPERTY =
@@ -429,6 +434,10 @@
     private float mBottomRoundnessDuringLaunchAnimation;
     private float mSmallRoundness;
 
+    private ListenerSet<DismissButtonTargetVisibilityListener>
+            mDismissButtonTargetVisibilityListeners
+            = new ListenerSet();
+
     public NotificationContentView[] getLayouts() {
         return Arrays.copyOf(mLayouts, mLayouts.length);
     }
@@ -738,6 +747,73 @@
         }
     }
 
+    public interface DismissButtonTargetVisibilityListener {
+        // Called when the notification dismiss button's target visibility changes.
+        // NOTE: This can be called when the dismiss button already has the target visibility.
+        void onTargetVisibilityChanged(boolean targetVisible);
+    }
+
+    public void addDismissButtonTargetStateListener(
+            DismissButtonTargetVisibilityListener listener) {
+        if (NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode()) {
+            return;
+        }
+
+        mDismissButtonTargetVisibilityListeners.addIfAbsent(listener);
+    }
+
+    public void removeDismissButtonTargetStateListener(
+            DismissButtonTargetVisibilityListener listener) {
+        if (NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode()) {
+            return;
+        }
+
+        mDismissButtonTargetVisibilityListeners.remove(listener);
+    }
+
+    @Override
+    public boolean onInterceptHoverEvent(MotionEvent event) {
+        if (!NotificationAddXOnHoverToDismiss.isEnabled()) {
+            return super.onInterceptHoverEvent(event);
+        }
+
+        // Do not bother checking the dismiss button's target visibility if the notification cannot
+        // be dismissed.
+        if (!canEntryBeDismissed()) {
+            return false;
+        }
+
+        final Boolean targetVisible = getDismissButtonTargetVisibilityIfAny(event);
+        if (targetVisible != null) {
+            for (DismissButtonTargetVisibilityListener listener :
+                    mDismissButtonTargetVisibilityListeners) {
+                listener.onTargetVisibilityChanged(targetVisible.booleanValue());
+            }
+        }
+
+        // Do not consume the hover event so that children still have a chance to process it.
+        return false;
+    }
+
+    private @Nullable Boolean getDismissButtonTargetVisibilityIfAny(MotionEvent event) {
+        // Returns the dismiss button's target visibility resulted by `event`. Returns null if the
+        // target visibility should not change.
+
+        if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
+            // The notification dismiss button should be hidden when the hover exit event is located
+            // outside of the notification. NOTE: The hover exit event can be inside the
+            // notification if hover moves from one hoverable child to another.
+            final Rect localBounds = new Rect(0, 0, this.getWidth(), this.getActualHeight());
+            if (!localBounds.contains((int) event.getX(), (int) event.getY())) {
+                return Boolean.FALSE;
+            }
+        } else if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
+            return Boolean.TRUE;
+        }
+
+        return null;
+    }
+
     private void updateLimitsForView(NotificationContentView layout) {
         View contractedView = layout.getContractedChild();
         boolean customView = contractedView != null
@@ -1153,17 +1229,15 @@
     /**
      * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
      * the notification will be rendered on top of the screen.
-     *
-     * @param pinned whether it is pinned
      */
-    public void setPinned(boolean pinned) {
+    public void setPinnedStatus(PinnedStatus pinnedStatus) {
         int intrinsicHeight = getIntrinsicHeight();
         boolean wasAboveShelf = isAboveShelf();
-        mIsPinned = pinned;
+        mPinnedStatus = pinnedStatus;
         if (intrinsicHeight != getIntrinsicHeight()) {
             notifyHeightChanged(/* needsAnimation= */ false);
         }
-        if (pinned) {
+        if (pinnedStatus.isPinned()) {
             setAnimationRunning(true);
             mExpandedWhenPinned = false;
         } else if (mExpandedWhenPinned) {
@@ -1177,7 +1251,7 @@
 
     @Override
     public boolean isPinned() {
-        return mIsPinned;
+        return mPinnedStatus.isPinned();
     }
 
     @Override
@@ -1370,6 +1444,9 @@
             items.add(NotificationMenuRow.createPartialConversationItem(mContext));
             items.add(NotificationMenuRow.createInfoItem(mContext));
             items.add(NotificationMenuRow.createSnoozeItem(mContext));
+            if (android.app.Flags.notificationClassificationUi()) {
+                items.add(NotificationMenuRow.createBundleItem(mContext));
+            }
             mMenuRow.setMenuItems(items);
         }
         if (existed) {
@@ -1532,6 +1609,10 @@
         return mPrivateLayout.getSingleLineView();
     }
 
+    /**
+     * Whether this row is displayed over the unoccluded lockscreen. Returns false on the
+     * locked shade.
+     */
     public boolean isOnKeyguard() {
         return mOnKeyguard;
     }
@@ -1679,7 +1760,13 @@
         dismiss(fromAccessibility);
         if (canEntryBeDismissed()) {
             if (mOnUserInteractionCallback != null) {
-                mOnUserInteractionCallback.registerFutureDismissal(mEntry, REASON_CANCEL).run();
+                if (Flags.notificationReentrantDismiss()) {
+                    Runnable futureDismissal = mOnUserInteractionCallback.registerFutureDismissal(
+                            mEntry, REASON_CANCEL);
+                    post(futureDismissal);
+                } else {
+                    mOnUserInteractionCallback.registerFutureDismissal(mEntry, REASON_CANCEL).run();
+                }
             }
         }
     }
@@ -1986,7 +2073,7 @@
         mColorUpdateLogger = colorUpdateLogger;
         mDismissibilityProvider = dismissibilityProvider;
         mFeatureFlags = featureFlags;
-        setHapticFeedbackEnabled(!com.android.systemui.Flags.msdlFeedback());
+        setHapticFeedbackEnabled(!Flags.msdlFeedback());
     }
 
     private void initDimens() {
@@ -2204,6 +2291,10 @@
         mTranslateableViews.remove(mGutsStub);
         // We don't handle focus highlight in this view, it's done in background drawable instead
         setDefaultFocusHighlightEnabled(false);
+
+        if (NotificationAddXOnHoverToDismiss.isEnabled()) {
+            addDismissButtonTargetStateListener(findViewById(R.id.backgroundNormal));
+        }
     }
 
     /**
@@ -2810,7 +2901,8 @@
         }
     }
 
-    void setOnKeyguard(boolean onKeyguard) {
+    /** @see #isOnKeyguard() */
+    public void setOnKeyguard(boolean onKeyguard) {
         if (onKeyguard != mOnKeyguard) {
             boolean wasAboveShelf = isAboveShelf();
             final boolean wasExpanded = isExpanded();
@@ -3739,7 +3831,8 @@
     @Override
     public boolean isAboveShelf() {
         return (canShowHeadsUp()
-                && (mIsPinned || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf)
+                && (mPinnedStatus.isPinned()
+                || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf)
                 || mExpandAnimationRunning || mChildIsExpanding));
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index baad616..a150f7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -41,6 +41,7 @@
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.notification.ColorUpdateLogger;
 import com.android.systemui.statusbar.notification.FeedbackIcon;
@@ -58,7 +59,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationRowStatsLogger;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.SmartReplyConstants;
 import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
 import com.android.systemui.util.time.SystemClock;
@@ -378,15 +379,19 @@
                 mView.getEntry().setInitializationTime(mClock.elapsedRealtime());
                 mPluginManager.addPluginListener(mView,
                         NotificationMenuRowPlugin.class, false /* Allow multiple */);
-                mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
-                mStatusBarStateController.addCallback(mStatusBarStateListener);
+                if (!SceneContainerFlag.isEnabled()) {
+                    mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
+                    mStatusBarStateController.addCallback(mStatusBarStateListener);
+                }
                 mSettingsController.addCallback(BUBBLES_SETTING_URI, mSettingsListener);
             }
 
             @Override
             public void onViewDetachedFromWindow(View v) {
                 mPluginManager.removePluginListener(mView);
-                mStatusBarStateController.removeCallback(mStatusBarStateListener);
+                if (!SceneContainerFlag.isEnabled()) {
+                    mStatusBarStateController.removeCallback(mStatusBarStateListener);
+                }
                 mSettingsController.removeCallback(BUBBLES_SETTING_URI, mSettingsListener);
             }
         });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java
index 77f5717..11db2fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java
@@ -52,7 +52,7 @@
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 
 import javax.inject.Inject;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index d0db514..34ef639 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -21,7 +21,9 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.Canvas;
+import android.graphics.Path;
 import android.graphics.PorterDuff;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.LayerDrawable;
@@ -36,6 +38,7 @@
 import com.android.settingslib.Utils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
 import com.android.systemui.util.DrawableDumpKt;
 
 import java.io.PrintWriter;
@@ -44,7 +47,8 @@
 /**
  * A view that can be used for both the dimmed and normal background of an notification.
  */
-public class NotificationBackgroundView extends View implements Dumpable {
+public class NotificationBackgroundView extends View implements Dumpable,
+        ExpandableNotificationRow.DismissButtonTargetVisibilityListener {
 
     private final boolean mDontModifyCorners;
     private Drawable mBackground;
@@ -66,6 +70,11 @@
     private final ColorStateList mLightColoredStatefulColors;
     private final ColorStateList mDarkColoredStatefulColors;
     private final int mNormalColor;
+    private final int convexR = 9;
+    private final int concaveR = 22;
+
+    // True only if the dismiss button is visible.
+    private boolean mDrawDismissButtonCutout = false;
 
     public NotificationBackgroundView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -80,6 +89,18 @@
     }
 
     @Override
+    public void onTargetVisibilityChanged(boolean targetVisible) {
+        if (NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode()) {
+            return;
+        }
+
+        if (mDrawDismissButtonCutout != targetVisible) {
+            mDrawDismissButtonCutout = targetVisible;
+            invalidate();
+        }
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         if (mClipTopAmount + mClipBottomAmount < getActualHeight() || mExpandAnimationRunning) {
             canvas.save();
@@ -87,12 +108,87 @@
                 canvas.clipRect(0, mClipTopAmount, getWidth(),
                         getActualHeight() - mClipBottomAmount);
             }
-            draw(canvas, mBackground);
+
+            if (!NotificationAddXOnHoverToDismiss.isEnabled()) {
+                draw(canvas, mBackground);
+                canvas.restore();
+                return;
+            }
+
+            Rect backgroundBounds = null;
+            if (mBackground != null || mDrawDismissButtonCutout) {
+                backgroundBounds = calculateBackgroundBounds();
+            }
+
+            if (mDrawDismissButtonCutout) {
+                canvas.clipPath(calculateDismissButtonCutoutPath(backgroundBounds));
+            }
+
+            if (mBackground != null) {
+                mBackground.setBounds(backgroundBounds);
+                mBackground.draw(canvas);
+            }
+
             canvas.restore();
         }
     }
 
+    private Path calculateDismissButtonCutoutPath(Rect backgroundBounds) {
+        // TODO(b/365585705): Adapt to RTL after the UX design is finalized.
+
+        NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode();
+
+        Path path = new Path();
+
+        final int left = backgroundBounds.left;
+        final int right = backgroundBounds.right;
+        final int top = backgroundBounds.top;
+        final int bottom = backgroundBounds.bottom;
+
+        // Generate the path clockwise from the left-top corner.
+        path.moveTo(left, top);
+        path.lineTo(right - 2 * convexR - concaveR, top);
+        path.quadTo(right - convexR - concaveR, top, right - convexR - concaveR,
+                top + convexR);
+        path.quadTo(right - convexR - concaveR, top + convexR + concaveR, right - convexR,
+                top + convexR + concaveR);
+        path.quadTo(right, top + convexR + concaveR, right, top + 2 * convexR + concaveR);
+        path.lineTo(right, bottom);
+        path.lineTo(left, bottom);
+        path.lineTo(left, top);
+
+        return path;
+    }
+
+    private Rect calculateBackgroundBounds() {
+        NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode();
+
+        int top = 0;
+        int bottom = getActualHeight();
+        if (mBottomIsRounded
+                && mBottomAmountClips
+                && !mExpandAnimationRunning) {
+            bottom -= mClipBottomAmount;
+        }
+        final boolean isRtl = isLayoutRtl();
+        final int width = getWidth();
+        final int actualWidth = getActualWidth();
+
+        int left = isRtl ? width - actualWidth : 0;
+        int right = isRtl ? width : actualWidth;
+
+        if (mExpandAnimationRunning) {
+            // Horizontally center this background view inside of the container
+            left = (int) ((width - actualWidth) / 2.0f);
+            right = (int) (left + actualWidth);
+        }
+
+        return new Rect(left, top, right, bottom);
+    }
+
     private void draw(Canvas canvas, Drawable drawable) {
+        NotificationAddXOnHoverToDismiss.assertInLegacyMode();
+
         if (drawable != null) {
             int top = 0;
             int bottom = getActualHeight();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 41abac1..6e05e8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -54,6 +54,8 @@
 import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
 import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor;
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel;
 import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
 import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation;
 import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
@@ -92,6 +94,7 @@
     private final SmartReplyStateInflater mSmartReplyStateInflater;
     private final NotifLayoutInflaterFactory.Provider mNotifLayoutInflaterFactoryProvider;
     private final HeadsUpStyleProvider mHeadsUpStyleProvider;
+    private final PromotedNotificationContentExtractor mPromotedNotificationContentExtractor;
 
     private final NotificationRowContentBinderLogger mLogger;
 
@@ -105,6 +108,7 @@
             SmartReplyStateInflater smartRepliesInflater,
             NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider,
             HeadsUpStyleProvider headsUpStyleProvider,
+            PromotedNotificationContentExtractor promotedNotificationContentExtractor,
             NotificationRowContentBinderLogger logger) {
         NotificationRowContentBinderRefactor.assertInLegacyMode();
         mRemoteViewCache = remoteViewCache;
@@ -115,6 +119,7 @@
         mSmartReplyStateInflater = smartRepliesInflater;
         mNotifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider;
         mHeadsUpStyleProvider = headsUpStyleProvider;
+        mPromotedNotificationContentExtractor = promotedNotificationContentExtractor;
         mLogger = logger;
     }
 
@@ -165,6 +170,7 @@
                 mSmartReplyStateInflater,
                 mNotifLayoutInflaterFactoryProvider,
                 mHeadsUpStyleProvider,
+                mPromotedNotificationContentExtractor,
                 mLogger);
         if (mInflateSynchronously) {
             task.onPostExecute(task.doInBackground());
@@ -913,6 +919,11 @@
         NotificationContentView privateLayout = row.getPrivateLayout();
         NotificationContentView publicLayout = row.getPublicLayout();
         logger.logAsyncTaskProgress(entry, "finishing");
+
+        if (PromotedNotificationContentModel.featureFlagEnabled()) {
+            entry.setPromotedNotificationContentModel(result.mExtractedPromotedNotificationContent);
+        }
+
         boolean setRepliesAndActions = true;
         if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) {
             if (result.inflatedContentView != null) {
@@ -1123,6 +1134,7 @@
         private final SmartReplyStateInflater mSmartRepliesInflater;
         private final NotifLayoutInflaterFactory.Provider mNotifLayoutInflaterFactoryProvider;
         private final HeadsUpStyleProvider mHeadsUpStyleProvider;
+        private final PromotedNotificationContentExtractor mPromotedNotificationContentExtractor;
         private final NotificationRowContentBinderLogger mLogger;
 
         private AsyncInflationTask(
@@ -1142,6 +1154,7 @@
                 SmartReplyStateInflater smartRepliesInflater,
                 NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider,
                 HeadsUpStyleProvider headsUpStyleProvider,
+                PromotedNotificationContentExtractor promotedNotificationContentExtractor,
                 NotificationRowContentBinderLogger logger) {
             mEntry = entry;
             mRow = row;
@@ -1160,6 +1173,7 @@
             mIsMediaInQS = isMediaFlagEnabled;
             mNotifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider;
             mHeadsUpStyleProvider = headsUpStyleProvider;
+            mPromotedNotificationContentExtractor = promotedNotificationContentExtractor;
             mLogger = logger;
             entry.setInflationTask(this);
         }
@@ -1276,6 +1290,14 @@
                         );
             }
 
+            if (PromotedNotificationContentModel.featureFlagEnabled()) {
+                mLogger.logAsyncTaskProgress(mEntry, "extracting promoted notification content");
+                result.mExtractedPromotedNotificationContent = mPromotedNotificationContentExtractor
+                        .extractContent(mEntry, recoveredBuilder);
+                mLogger.logAsyncTaskProgress(mEntry, "extracted promoted notification content: "
+                        + result.mExtractedPromotedNotificationContent);
+            }
+
             mLogger.logAsyncTaskProgress(mEntry,
                     "getting row image resolver (on wrong thread!)");
             final NotificationInlineImageResolver imageResolver = mRow.getImageResolver();
@@ -1377,6 +1399,8 @@
 
     @VisibleForTesting
     static class InflationProgress {
+        PromotedNotificationContentModel mExtractedPromotedNotificationContent;
+
         private RemoteViews newContentView;
         private RemoteViews newHeadsUpView;
         private RemoteViews newExpandedView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 9e9116b..ea50874 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -19,6 +19,7 @@
 import static android.app.AppOpsManager.OP_RECORD_AUDIO;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 
+import android.annotation.FlaggedApi;
 import android.app.INotificationManager;
 import android.app.NotificationChannel;
 import android.content.Context;
@@ -71,7 +72,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.wmshell.BubblesManager;
 
@@ -317,6 +318,9 @@
                         (PartialConversationInfo) gutsView);
             } else if (gutsView instanceof FeedbackInfo) {
                 initializeFeedbackInfo(row, (FeedbackInfo) gutsView);
+            } else if (android.app.Flags.notificationClassificationUi()
+                    && gutsView instanceof BundleNotificationInfo) {
+                initializeBundleNotificationInfo(row, (BundleNotificationInfo) gutsView);
             }
             return true;
         } catch (Exception e) {
@@ -420,6 +424,60 @@
     }
 
     /**
+     * Sets up the {@link BundleNotificationInfo} inside the notification row's guts.
+     * @param row view to set up the guts for
+     * @param notificationInfoView view to set up/bind within {@code row}
+     */
+    @VisibleForTesting
+    @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    void initializeBundleNotificationInfo(
+            final ExpandableNotificationRow row,
+            BundleNotificationInfo notificationInfoView) throws Exception {
+        NotificationGuts guts = row.getGuts();
+        StatusBarNotification sbn = row.getEntry().getSbn();
+        String packageName = sbn.getPackageName();
+        // Settings link is only valid for notifications that specify a non-system user
+        NotificationInfo.OnSettingsClickListener onSettingsClick = null;
+        UserHandle userHandle = sbn.getUser();
+        PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(
+                mContext, userHandle.getIdentifier());
+        final NotificationInfo.OnAppSettingsClickListener onAppSettingsClick =
+                (View v, Intent intent) -> {
+                    mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_APP_NOTE_SETTINGS);
+                    guts.resetFalsingCheck();
+                    mNotificationActivityStarter.startNotificationGutsIntent(intent, sbn.getUid(),
+                            row);
+                };
+
+        if (!userHandle.equals(UserHandle.ALL)
+                || mLockscreenUserManager.getCurrentUserId() == UserHandle.USER_SYSTEM) {
+            onSettingsClick = (View v, NotificationChannel channel, int appUid) -> {
+                mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_NOTE_INFO);
+                guts.resetFalsingCheck();
+                mOnSettingsClickListener.onSettingsClick(sbn.getKey());
+                startAppNotificationSettingsActivity(packageName, appUid, channel, row);
+            };
+        }
+
+        notificationInfoView.bindNotification(
+                pmUser,
+                mNotificationManager,
+                mOnUserInteractionCallback,
+                mChannelEditorDialogController,
+                packageName,
+                row.getEntry().getChannel(),
+                row.getEntry(),
+                onSettingsClick,
+                onAppSettingsClick,
+                mUiEventLogger,
+                mDeviceProvisionedController.isDeviceProvisioned(),
+                row.getIsNonblockable(),
+                mHighPriorityProvider.isHighPriority(row.getEntry()),
+                mAssistantFeedbackController,
+                mMetricsLogger);
+    }
+
+    /**
      * Sets up the {@link PartialConversationInfo} inside the notification row's guts.
      * @param row view to set up the guts for
      * @param notificationInfoView view to set up/bind within {@code row}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index bdfbc4b..6e8ec95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static android.app.NotificationChannel.SYSTEM_RESERVED_IDS;
 import static android.view.HapticFeedbackConstants.CLOCK_TICK;
 
 import static com.android.systemui.SwipeHelper.SWIPED_FAR_ENOUGH_SIZE_FRACTION;
@@ -261,7 +262,11 @@
         mFeedbackItem = createFeedbackItem(mContext);
         NotificationEntry entry = mParent.getEntry();
         int personNotifType = mPeopleNotificationIdentifier.getPeopleNotificationType(entry);
-        if (personNotifType == PeopleNotificationIdentifier.TYPE_PERSON) {
+        if (android.app.Flags.notificationClassificationUi()
+                && SYSTEM_RESERVED_IDS.contains(entry.getChannel().getId())) {
+            // Bundled notification; create bundle-specific guts.
+            mInfoItem = createBundleItem(mContext);
+        } else if (personNotifType == PeopleNotificationIdentifier.TYPE_PERSON) {
             mInfoItem = createPartialConversationItem(mContext);
         } else if (personNotifType >= PeopleNotificationIdentifier.TYPE_FULL_PERSON) {
             mInfoItem = createConversationItem(mContext);
@@ -677,6 +682,16 @@
                 R.drawable.ic_settings);
     }
 
+    static NotificationMenuItem createBundleItem(Context context) {
+        Resources res = context.getResources();
+        String infoDescription = res.getString(R.string.notification_menu_gear_description);
+        BundleNotificationInfo infoContent =
+                (BundleNotificationInfo) LayoutInflater.from(context).inflate(
+                        R.layout.bundle_notification_info, null, false);
+        return new NotificationMenuItem(context, infoDescription, infoContent,
+                R.drawable.ic_settings);
+    }
+
     static NotificationMenuItem createPartialConversationItem(Context context) {
         Resources res = context.getResources();
         String infoDescription = res.getString(R.string.notification_menu_gear_description);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index d0c033b..c7d80e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.statusbar.notification.row
 
 import android.annotation.SuppressLint
+import android.app.Flags
 import android.app.Notification
 import android.content.Context
 import android.content.ContextWrapper
@@ -46,6 +47,8 @@
 import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
 import com.android.systemui.statusbar.notification.InflationException
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 import com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED
 import com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_EXPANDED
 import com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP
@@ -95,6 +98,7 @@
     private val smartReplyStateInflater: SmartReplyStateInflater,
     private val notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
     private val headsUpStyleProvider: HeadsUpStyleProvider,
+    private val promotedNotificationContentExtractor: PromotedNotificationContentExtractor,
     private val logger: NotificationRowContentBinderLogger,
 ) : NotificationRowContentBinder {
 
@@ -147,6 +151,7 @@
                 /* isMediaFlagEnabled = */ smartReplyStateInflater,
                 notifLayoutInflaterFactoryProvider,
                 headsUpStyleProvider,
+                promotedNotificationContentExtractor,
                 logger,
             )
         if (inflateSynchronously) {
@@ -166,6 +171,7 @@
         builder: Notification.Builder,
         packageContext: Context,
         smartRepliesInflater: SmartReplyStateInflater,
+        promotedNotificationContentExtractor: PromotedNotificationContentExtractor,
     ): InflationProgress {
         val systemUIContext = row.context
         val result =
@@ -182,6 +188,7 @@
                 notifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider,
                 headsUpStyleProvider = headsUpStyleProvider,
                 conversationProcessor = conversationProcessor,
+                promotedNotificationContentExtractor = promotedNotificationContentExtractor,
                 logger = logger,
             )
         inflateSmartReplyViews(
@@ -372,6 +379,7 @@
         private val smartRepliesInflater: SmartReplyStateInflater,
         private val notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
         private val headsUpStyleProvider: HeadsUpStyleProvider,
+        private val promotedNotificationContentExtractor: PromotedNotificationContentExtractor,
         private val logger: NotificationRowContentBinderLogger,
     ) : AsyncTask<Void, Void, Result<InflationProgress>>(), InflationCallback, InflationTask {
         private val context: Context
@@ -442,6 +450,7 @@
                     notifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider,
                     headsUpStyleProvider = headsUpStyleProvider,
                     conversationProcessor = conversationProcessor,
+                    promotedNotificationContentExtractor = promotedNotificationContentExtractor,
                     logger = logger,
                 )
             logger.logAsyncTaskProgress(
@@ -582,6 +591,7 @@
         @VisibleForTesting val packageContext: Context,
         val remoteViews: NewRemoteViews,
         val contentModel: NotificationContentModel,
+        val extractedPromotedNotificationContentModel: PromotedNotificationContentModel?,
     ) {
 
         var inflatedContentView: View? = null
@@ -670,8 +680,23 @@
             notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
             headsUpStyleProvider: HeadsUpStyleProvider,
             conversationProcessor: ConversationNotificationProcessor,
+            promotedNotificationContentExtractor: PromotedNotificationContentExtractor,
             logger: NotificationRowContentBinderLogger,
         ): InflationProgress {
+            val promoted =
+                if (PromotedNotificationContentModel.featureFlagEnabled()) {
+                    logger.logAsyncTaskProgress(entry, "extracting promoted notification content")
+                    val extracted =
+                        promotedNotificationContentExtractor.extractContent(entry, builder)
+                    logger.logAsyncTaskProgress(
+                        entry,
+                        "extracted promoted notification content: {extracted}",
+                    )
+                    extracted
+                } else {
+                    null
+                }
+
             // process conversations and extract the messaging style
             val messagingStyle =
                 if (entry.ranking.isConversation) {
@@ -734,6 +759,7 @@
                 packageContext = packageContext,
                 remoteViews = remoteViews,
                 contentModel = contentModel,
+                extractedPromotedNotificationContentModel = promoted,
             )
         }
 
@@ -1393,6 +1419,11 @@
             logger.logAsyncTaskProgress(entry, "finishing")
 
             entry.setContentModel(result.contentModel)
+            if (PromotedNotificationContentModel.featureFlagEnabled()) {
+                entry.promotedNotificationContentModel =
+                    result.extractedPromotedNotificationContentModel
+            }
+
             result.inflatedSmartReplyState?.let { row.privateLayout.setInflatedSmartReplyState(it) }
 
             setContentViewsFromRemoteViews(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index b622def..e9eecdd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.statusbar.notification.row.wrapper;
 
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
 import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
 
 import android.app.Notification;
@@ -48,6 +51,7 @@
 import com.android.systemui.statusbar.notification.RoundableState;
 import com.android.systemui.statusbar.notification.TransformState;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
 
 import java.util.Stack;
 
@@ -115,6 +119,10 @@
         resolveHeaderViews();
         addFeedbackOnClickListener(row);
         addCloseButtonOnClickListener(row);
+
+        if (NotificationAddXOnHoverToDismiss.isEnabled()) {
+            mRow.addDismissButtonTargetStateListener(mHoverListener);
+        }
     }
 
     @Override
@@ -166,13 +174,34 @@
         }
     }
 
+    private ExpandableNotificationRow.DismissButtonTargetVisibilityListener mHoverListener = new
+            ExpandableNotificationRow.DismissButtonTargetVisibilityListener() {
+                @Override
+                public void onTargetVisibilityChanged(boolean targetVisible) {
+                    NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode();
+
+                    if (mCloseButton != null) {
+                        mCloseButton.setVisibility(targetVisible ? VISIBLE : GONE);
+                    }
+                }
+            };
+
+    @Override
+    public void setRemoved() {
+        super.setRemoved();
+
+        if (NotificationAddXOnHoverToDismiss.isEnabled()) {
+            mRow.removeDismissButtonTargetStateListener(mHoverListener);
+        }
+    }
+
     /**
      * Shows the given feedback icon, or hides the icon if null.
      */
     @Override
     public void setFeedbackIcon(@Nullable FeedbackIcon icon) {
         if (mFeedbackIcon != null) {
-            mFeedbackIcon.setVisibility(icon != null ? View.VISIBLE : View.GONE);
+            mFeedbackIcon.setVisibility(icon != null ? VISIBLE : GONE);
             if (icon != null) {
                 if (mFeedbackIcon instanceof ImageButton) {
                     ((ImageButton) mFeedbackIcon).setImageResource(icon.getIconRes());
@@ -266,7 +295,7 @@
             boolean expandable,
             View.OnClickListener onClickListener,
             boolean requestLayout) {
-        mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE);
+        mExpandButton.setVisibility(expandable ? VISIBLE : GONE);
         mExpandButton.setOnClickListener(expandable ? onClickListener : null);
         if (mAltExpandTarget != null) {
             mAltExpandTarget.setOnClickListener(expandable ? onClickListener : null);
@@ -294,7 +323,7 @@
     @Override
     public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
         if (mAudiblyAlertedIcon != null) {
-            mAudiblyAlertedIcon.setVisibility(audiblyAlerted ? View.VISIBLE : View.GONE);
+            mAudiblyAlertedIcon.setVisibility(audiblyAlerted ? VISIBLE : GONE);
         }
     }
 
@@ -371,6 +400,7 @@
             ((DateTimeView) timeView).setTime(whenMillis);
         }
     }
+
     protected void addTransformedViews(View... views) {
         for (View view : views) {
             if (view != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationAddXOnHoverToDismiss.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationAddXOnHoverToDismiss.kt
new file mode 100644
index 0000000..0961874
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationAddXOnHoverToDismiss.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.shared
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the notification dismiss button on hover flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object NotificationAddXOnHoverToDismiss {
+    const val FLAG_NAME = Flags.FLAG_NOTIFICATION_ADD_X_ON_HOVER_TO_DISMISS
+
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.notificationAddXOnHoverToDismiss()
+
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 7771421..ad36117 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -39,7 +39,7 @@
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController;
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.policy.AvalancheController;
+import com.android.systemui.statusbar.notification.headsup.AvalancheController;
 
 import java.io.PrintWriter;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index 5c9a0b9..f85545e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -100,6 +100,9 @@
      */
     void addContainerViewAt(View v, int index);
 
+    /** Sets whether the notificatios are displayed on the unoccluded lockscreen. */
+    void setOnLockscreen(boolean isOnKeyguard);
+
     /**
      * Sets the maximum number of notifications to display.
      *
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 57af8ea..223475e 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
@@ -99,7 +99,7 @@
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.ColorUpdateLogger;
 import com.android.systemui.statusbar.notification.FakeShadowView;
-import com.android.systemui.statusbar.notification.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
 import com.android.systemui.statusbar.notification.NotificationTransitionAnimatorController;
 import com.android.systemui.statusbar.notification.NotificationUtils;
@@ -127,7 +127,7 @@
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.policy.HeadsUpUtil;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.ScrollAdapter;
 import com.android.systemui.statusbar.policy.SplitShadeStateController;
 import com.android.systemui.util.Assert;
@@ -575,6 +575,7 @@
     @Nullable private SplitShadeStateController mSplitShadeStateController = null;
     private boolean mIsSmallLandscapeLockscreenEnabled = false;
     private boolean mSuppressHeightUpdates;
+    private boolean mIsOnLockscreen;
 
     /** Pass splitShadeStateController to view and update split shade */
     public void passSplitShadeStateController(SplitShadeStateController splitShadeStateController) {
@@ -3228,9 +3229,12 @@
     private void onViewAddedInternal(ExpandableView child) {
         updateHideSensitiveForChild(child);
         child.setOnHeightChangedListener(mOnChildHeightChangedListener);
-        if (child instanceof ExpandableNotificationRow) {
+        if (child instanceof ExpandableNotificationRow row) {
             NotificationEntry entry = ((ExpandableNotificationRow) child).getEntry();
             entry.addOnSensitivityChangedListener(mOnChildSensitivityChangedListener);
+            if (SceneContainerFlag.isEnabled()) {
+                row.setOnKeyguard(mIsOnLockscreen);
+            }
         }
         generateAddAnimation(child, false /* fromMoreCard */);
         updateAnimationState(child);
@@ -4752,8 +4756,11 @@
         }
     }
 
-    void goToFullShade(long delay) {
-        SceneContainerFlag.assertInLegacyMode();
+    /**
+     * Requests an animation for the next stack height update, to animate from the constrained stack
+     * displayed on the lock screen, to the scrollable stack displayed in the expanded shade.
+     */
+    public void animateGoToFullShade(long delay) {
         mGoToFullShadeNeedsAnimation = true;
         mGoToFullShadeDelay = delay;
         mNeedsAnimation = true;
@@ -5356,12 +5363,38 @@
         shelf.bind(mAmbientState, this, mController.getNotificationRoundnessManager());
     }
 
+    /**
+     * Whether the notifications are displayed over the unoccluded lockscreen. Returns false on the
+     * locked shade.
+     */
+    public boolean isOnLockscreen() {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return false;
+        return mIsOnLockscreen;
+    }
+
+    /** @see #isOnLockscreen() */
+    public void setOnLockscreen(boolean isOnLockscreen) {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+        if (mIsOnLockscreen != isOnLockscreen) {
+            mIsOnLockscreen = isOnLockscreen;
+            for (int i = 0; i < getChildCount(); i++) {
+                View child = getChildAt(i);
+                if (child instanceof ExpandableNotificationRow childRow) {
+                    childRow.setOnKeyguard(isOnLockscreen);
+                }
+            }
+        }
+    }
+
     public void setMaxDisplayedNotifications(int maxDisplayedNotifications) {
         if (mMaxDisplayedNotifications != maxDisplayedNotifications) {
             mMaxDisplayedNotifications = maxDisplayedNotifications;
             if (SceneContainerFlag.isEnabled()) {
                 updateIntrinsicStackHeight();
                 updateStackEndHeightAndStackHeight(mAmbientState.getExpansionFraction());
+                if (maxDisplayedNotifications == -1) {
+                    animateGoToFullShade(0);
+                }
             } else {
                 updateContentHeight();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index dc1a191..e89645d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -98,9 +98,9 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.ColorUpdateLogger;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.HeadsUpNotificationViewControllerEmptyImpl;
-import com.android.systemui.statusbar.notification.HeadsUpTouchHelper;
-import com.android.systemui.statusbar.notification.HeadsUpTouchHelper.HeadsUpNotificationViewController;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpNotificationViewControllerEmptyImpl;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpTouchHelper.HeadsUpNotificationViewController;
 import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
@@ -138,8 +138,8 @@
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController;
 import com.android.systemui.statusbar.policy.SplitShadeStateController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -1222,7 +1222,7 @@
 
     public void goToFullShade(long delay) {
         SceneContainerFlag.assertInLegacyMode();
-        mView.goToFullShade(delay);
+        mView.animateGoToFullShade(delay);
     }
 
     public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
@@ -1603,6 +1603,12 @@
         }
     }
 
+    /** Sets whether the NSSL is displayed over the unoccluded Lockscreen. */
+    public void setOnLockscreen(boolean isOnLockscreen) {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+        mNotificationListContainer.setOnLockscreen(isOnLockscreen);
+    }
+
     /**
      * Set the maximum number of notifications that can currently be displayed
      */
@@ -2029,6 +2035,11 @@
         }
 
         @Override
+        public void setOnLockscreen(boolean isOnLockscreen) {
+            mView.setOnLockscreen(isOnLockscreen);
+        }
+
+        @Override
         public void setMaxDisplayedNotifications(int maxNotifications) {
             mView.setMaxDisplayedNotifications(maxNotifications);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
index ef14557..b2ffa4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
@@ -33,7 +33,7 @@
 import com.android.systemui.statusbar.notification.NotificationFadeAware.FadeOptimizedNotification;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
-import com.android.systemui.statusbar.policy.HeadsUpUtil;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpUtil;
 
 import java.io.PrintWriter;
 import java.lang.reflect.Field;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 4a55dfa..ea71460 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -118,8 +118,12 @@
                     }
 
                     launch {
-                        viewModel.getMaxNotifications(calculateMaxNotifications).collect {
-                            controller.setMaxDisplayedNotifications(it)
+                        viewModel.getLockscreenDisplayConfig(calculateMaxNotifications).collect {
+                            (isOnLockscreen, maxNotifications) ->
+                            if (SceneContainerFlag.isEnabled) {
+                                controller.setOnLockscreen(isOnLockscreen)
+                            }
+                            controller.setMaxDisplayedNotifications(maxNotifications)
                         }
                     }
 
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 fb60f26..a55a165 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
@@ -718,9 +718,11 @@
      * When expanding or when the user is interacting with the shade, keep the count stable; do not
      * emit a value.
      */
-    fun getMaxNotifications(calculateSpace: (Float, Boolean) -> Int): Flow<Int> {
+    fun getLockscreenDisplayConfig(
+        calculateSpace: (Float, Boolean) -> Int
+    ): Flow<LockscreenDisplayConfig> {
         val showLimitedNotifications = isOnLockscreenWithoutShade
-        val showUnlimitedNotifications =
+        val showUnlimitedNotificationsAndIsOnLockScreen =
             combine(
                 isOnLockscreen,
                 keyguardInteractor.statusBarState,
@@ -730,28 +732,42 @@
                     )
                     .onStart { emit(false) },
             ) { isOnLockscreen, statusBarState, showAllNotifications ->
-                statusBarState == SHADE_LOCKED || !isOnLockscreen || showAllNotifications
+                (statusBarState == SHADE_LOCKED || !isOnLockscreen || showAllNotifications) to
+                    isOnLockscreen
             }
 
+        @Suppress("UNCHECKED_CAST")
         return combineTransform(
                 showLimitedNotifications,
-                showUnlimitedNotifications,
+                showUnlimitedNotificationsAndIsOnLockScreen,
                 shadeInteractor.isUserInteracting,
                 availableHeight,
                 interactor.notificationStackChanged,
                 interactor.useExtraShelfSpace,
             ) { flows ->
                 val showLimitedNotifications = flows[0] as Boolean
-                val showUnlimitedNotifications = flows[1] as Boolean
+                val (showUnlimitedNotifications, isOnLockscreen) =
+                    flows[1] as Pair<Boolean, Boolean>
                 val isUserInteracting = flows[2] as Boolean
                 val availableHeight = flows[3] as Float
                 val useExtraShelfSpace = flows[5] as Boolean
 
                 if (!isUserInteracting) {
                     if (showLimitedNotifications) {
-                        emit(calculateSpace(availableHeight, useExtraShelfSpace))
+                        emit(
+                            LockscreenDisplayConfig(
+                                isOnLockscreen = isOnLockscreen,
+                                maxNotifications =
+                                    calculateSpace(availableHeight, useExtraShelfSpace),
+                            )
+                        )
                     } else if (showUnlimitedNotifications) {
-                        emit(-1)
+                        emit(
+                            LockscreenDisplayConfig(
+                                isOnLockscreen = isOnLockscreen,
+                                maxNotifications = -1,
+                            )
+                        )
                     }
                 }
             }
@@ -775,9 +791,9 @@
         SceneContainerFlag.assertInLegacyMode()
 
         return combine(
-            getMaxNotifications(calculateMaxNotifications).map {
-                val height = calculateHeight(it)
-                if (it == 0) {
+            getLockscreenDisplayConfig(calculateMaxNotifications).map { (_, maxNotifications) ->
+                val height = calculateHeight(maxNotifications)
+                if (maxNotifications == 0) {
                     height - shelfHeight
                 } else {
                     height
@@ -815,4 +831,13 @@
          */
         data class FloatAtEnd(val width: Int) : HorizontalPosition
     }
+
+    /**
+     * Data class representing a configuration for displaying Notifications on the Lockscreen.
+     *
+     * @param isOnLockscreen is the user on the lockscreen
+     * @param maxNotifications Limit for the max number of top-level Notifications to be displayed.
+     *   A value of -1 indicates no limit.
+     */
+    data class LockscreenDisplayConfig(val isOnLockscreen: Boolean, val maxNotifications: Int)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.kt
new file mode 100644
index 0000000..636e1c4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import android.content.Context
+import android.view.MotionEvent
+import com.android.systemui.statusbar.AutoHideUiElement
+import java.io.PrintWriter
+
+/**
+ * Controls the auto-hide behavior of system bars (status bar, navigation bar).
+ *
+ * This interface provides methods to manage the auto-hide schedule of system bars, allowing them to
+ * be shown or hidden.
+ */
+interface AutoHideController {
+    /**
+     * Sets a [AutoHideUiElement] status bar that should be controlled by the [AutoHideController].
+     */
+    fun setStatusBar(element: AutoHideUiElement)
+
+    /**
+     * Sets a [AutoHideUiElement] navigation bar that should be controlled by the
+     * [AutoHideController].
+     */
+    fun setNavigationBar(element: AutoHideUiElement)
+
+    /** Resumes the auto-hide behavior that was previously suspended. */
+    fun resumeSuspendedAutoHide()
+
+    /** Suspends the auto-hide behavior. */
+    fun suspendAutoHide()
+
+    /** Schedules or cancels auto hide behavior based on current system bar state. */
+    fun touchAutoHide()
+
+    /** Hides system bars on user touch if the interaction requires them to be hidden. */
+    fun checkUserAutoHide(event: MotionEvent)
+
+    /** Called when work should stop and resources should be released. */
+    fun stop()
+
+    /** Dumps the current state of the [AutoHideController] */
+    fun dump(pw: PrintWriter)
+
+    /** Injectable factory for creating a [AutoHideController]. */
+    interface Factory {
+        /** Create an [AutoHideController] */
+        fun create(context: Context): AutoHideController
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerImpl.java
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerImpl.java
index 1358cfd..4fbfbb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.AutoHideUiElement;
 
@@ -36,9 +35,7 @@
 
 import javax.inject.Inject;
 
-/** A controller to control all auto-hide things. Also see {@link AutoHideUiElement}. */
-@SysUISingleton
-public class AutoHideController {
+public class AutoHideControllerImpl implements AutoHideController {
     private static final String TAG = "AutoHideController";
     private static final int AUTO_HIDE_TIMEOUT_MS = 2250;
     private static final int USER_AUTO_HIDE_TIMEOUT_MS = 350;
@@ -61,7 +58,7 @@
     };
 
     @Inject
-    public AutoHideController(Context context,
+    public AutoHideControllerImpl(Context context,
             @Main Handler handler,
             IWindowManager iWindowManager) {
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
@@ -70,18 +67,12 @@
         mDisplayId = context.getDisplayId();
     }
 
-    /**
-     * Sets a {@link AutoHideUiElement} status bar that should be controlled by the
-     * {@link AutoHideController}.
-     */
+    @Override
     public void setStatusBar(AutoHideUiElement element) {
         mStatusBar = element;
     }
 
-    /**
-     * Sets a {@link AutoHideUiElement} navigation bar that should be controlled by the
-     * {@link AutoHideController}.
-     */
+    @Override
     public void setNavigationBar(AutoHideUiElement element) {
         mNavigationBar = element;
     }
@@ -102,6 +93,7 @@
         }
     }
 
+    @Override
     public void resumeSuspendedAutoHide() {
         if (mAutoHideSuspended) {
             scheduleAutoHide();
@@ -112,6 +104,7 @@
         }
     }
 
+    @Override
     public void suspendAutoHide() {
         mHandler.removeCallbacks(mAutoHide);
         Runnable checkBarModesRunnable = getCheckBarModesRunnable();
@@ -121,7 +114,7 @@
         mAutoHideSuspended = isAnyTransientBarShown();
     }
 
-    /** Schedules or cancels auto hide behavior based on current system bar state. */
+    @Override
     public void touchAutoHide() {
         // update transient bar auto hide
         if (isAnyTransientBarShown()) {
@@ -156,6 +149,7 @@
                 FLAG_CONTENT_CONTROLS);
     }
 
+    @Override
     public void checkUserAutoHide(MotionEvent event) {
         boolean shouldHide = isAnyTransientBarShown()
                 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar.
@@ -196,6 +190,12 @@
         return false;
     }
 
+    @Override
+    public void stop() {
+        mHandler.removeCallbacks(mAutoHide);
+    }
+
+    @Override
     public void dump(@NonNull PrintWriter pw) {
         pw.println("AutoHideController:");
         pw.println("\tmAutoHideSuspended=" + mAutoHideSuspended);
@@ -205,10 +205,7 @@
         pw.println("\tgetUserAutoHideTimeout=" + getUserAutoHideTimeout());
     }
 
-    /**
-     * Injectable factory for creating a {@link AutoHideController}.
-     */
-    public static class Factory {
+    public static class Factory implements AutoHideController.Factory {
         private final Handler mHandler;
         private final IWindowManager mIWindowManager;
 
@@ -219,8 +216,9 @@
         }
 
         /** Create an {@link AutoHideController} */
+        @Override
         public AutoHideController create(Context context) {
-            return new AutoHideController(context, mHandler, mIWindowManager);
+            return new AutoHideControllerImpl(context, mHandler, mIWindowManager);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
new file mode 100644
index 0000000..744f969
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+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 javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/** Provides per display instances of [AutoHideController] */
+interface AutoHideControllerStore : PerDisplayStore<AutoHideController>
+
+@SysUISingleton
+class MultiDisplayAutoHideControllerStore
+@Inject
+constructor(
+    @Background backgroundApplicationScope: CoroutineScope,
+    displayRepository: DisplayRepository,
+    private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
+    private val autoHideControllerFactory: AutoHideControllerImpl.Factory,
+) :
+    AutoHideControllerStore,
+    PerDisplayStoreImpl<AutoHideController>(backgroundApplicationScope, displayRepository) {
+
+    init {
+        StatusBarConnectedDisplays.assertInNewMode()
+    }
+
+    override fun createInstanceForDisplay(displayId: Int): AutoHideController {
+        val displayWindowProperties =
+            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+        return autoHideControllerFactory.create(displayWindowProperties.context)
+    }
+
+    override suspend fun onDisplayRemovalAction(instance: AutoHideController) {
+        instance.stop()
+    }
+
+    override val instanceClass = AutoHideController::class.java
+}
+
+@SysUISingleton
+class SingleDisplayAutoHideControllerStore
+@Inject
+constructor(defaultController: AutoHideController) :
+    AutoHideControllerStore,
+    PerDisplayStore<AutoHideController> by SingleDisplayStore(defaultController) {
+
+    init {
+        StatusBarConnectedDisplays.assertInLegacyMode()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 5209d0f..7f95fb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -66,7 +66,7 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 80c8e8b..c6af328 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -171,14 +171,12 @@
 import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.shade.ShadeController;
-import com.android.systemui.shade.ShadeExpandsOnStatusBarLongPress;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.shade.ShadeExpansionListener;
 import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.shade.ShadeLogger;
 import com.android.systemui.shade.ShadeSurface;
 import com.android.systemui.shade.ShadeViewController;
-import com.android.systemui.shade.StatusBarLongPressGestureDetector;
 import com.android.systemui.shared.recents.utilities.Utilities;
 import com.android.systemui.shared.statusbar.phone.BarTransitions;
 import com.android.systemui.statusbar.AutoHideUiElement;
@@ -223,7 +221,7 @@
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
 import com.android.systemui.statusbar.policy.ExtensionController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
@@ -368,7 +366,6 @@
 
     private PhoneStatusBarViewController mPhoneStatusBarViewController;
     private PhoneStatusBarTransitions mStatusBarTransitions;
-    private final Provider<StatusBarLongPressGestureDetector> mStatusBarLongPressGestureDetector;
     private final AuthRippleController mAuthRippleController;
     @WindowVisibleState private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
     private final NotificationShadeWindowController mNotificationShadeWindowController;
@@ -404,7 +401,7 @@
     private final KeyguardBypassController mKeyguardBypassController;
     private final KeyguardStateController mKeyguardStateController;
     private final HeadsUpManager mHeadsUpManager;
-    private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    private final ShadeTouchableRegionManager mShadeTouchableRegionManager;
     private final FalsingCollector mFalsingCollector;
     private final FalsingManager mFalsingManager;
     private final BroadcastDispatcher mBroadcastDispatcher;
@@ -674,7 +671,6 @@
             ShadeController shadeController,
             WindowRootViewVisibilityInteractor windowRootViewVisibilityInteractor,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-            Provider<StatusBarLongPressGestureDetector> statusBarLongPressGestureDetector,
             ViewMediatorCallback viewMediatorCallback,
             InitController initController,
             @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
@@ -685,7 +681,7 @@
             KeyguardIndicationController keyguardIndicationController,
             DemoModeController demoModeController,
             Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
-            StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+            ShadeTouchableRegionManager shadeTouchableRegionManager,
             BrightnessSliderController.Factory brightnessSliderFactory,
             ScreenOffAnimationController screenOffAnimationController,
             WallpaperController wallpaperController,
@@ -728,7 +724,7 @@
         mHeadsUpManager = headsUpManager;
         mBackActionInteractor = backActionInteractor;
         mKeyguardIndicationController = keyguardIndicationController;
-        mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
+        mShadeTouchableRegionManager = shadeTouchableRegionManager;
         mFalsingCollector = falsingCollector;
         mFalsingManager = falsingManager;
         mBroadcastDispatcher = broadcastDispatcher;
@@ -782,7 +778,6 @@
         mShadeController = shadeController;
         mWindowRootViewVisibilityInteractor = windowRootViewVisibilityInteractor;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
-        mStatusBarLongPressGestureDetector = statusBarLongPressGestureDetector;
         mKeyguardViewMediatorCallback = viewMediatorCallback;
         mInitController = initController;
         mPluginDependencyProvider = pluginDependencyProvider;
@@ -1237,7 +1232,7 @@
             mStatusBarInitializer.initializeStatusBar();
         }
 
-        mStatusBarTouchableRegionManager.setup(getNotificationShadeWindowView());
+        mShadeTouchableRegionManager.setup(getNotificationShadeWindowView());
 
         if (!StatusBarConnectedDisplays.isEnabled()) {
             createNavigationBar(result);
@@ -1532,11 +1527,6 @@
                 // to touch outside the customizer to close it, such as on the status or nav bar.
                 mShadeController.onStatusBarTouch(event);
             }
-            if (ShadeExpandsOnStatusBarLongPress.isEnabled()
-                    && mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
-                mStatusBarLongPressGestureDetector.get().handleTouch(event);
-            }
-
             return getNotificationShadeWindowView().onTouchEvent(event);
         };
     }
@@ -1866,10 +1856,10 @@
             pw.println("  mHeadsUpManager: null");
         }
 
-        if (mStatusBarTouchableRegionManager != null) {
-            mStatusBarTouchableRegionManager.dump(pw, args);
+        if (mShadeTouchableRegionManager != null) {
+            mShadeTouchableRegionManager.dump(pw, args);
         } else {
-            pw.println("  mStatusBarTouchableRegionManager: null");
+            pw.println("  mShadeTouchableRegionManager: null");
         }
 
         if (mLightBarController != null) {
@@ -2576,7 +2566,7 @@
             dismissVolumeDialog();
             mWakeUpCoordinator.setFullyAwake(false);
             mKeyguardBypassController.onStartedGoingToSleep();
-            mStatusBarTouchableRegionManager.updateTouchableRegion();
+            mShadeTouchableRegionManager.updateTouchableRegion();
 
             // The unlocked screen off and fold to aod animations might use our LightRevealScrim -
             // we need to be expanded for it to be visible.
@@ -2665,7 +2655,7 @@
             // once we fully woke up.
             updateRevealEffect(true /* wakingUp */);
             updateNotificationPanelTouchState();
-            mStatusBarTouchableRegionManager.updateTouchableRegion();
+            mShadeTouchableRegionManager.updateTouchableRegion();
 
             // If we are waking up during the screen off animation, we should undo making the
             // expanded visible (we did that so the LightRevealScrim would be visible).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index ec92990..57e26d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -54,8 +54,8 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener;
 import com.android.systemui.util.Assert;
 import com.android.systemui.util.CopyOnLoopListenerSet;
 import com.android.systemui.util.IListenerSet;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 8de03d8..b9639a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -47,9 +47,9 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.phone.fragment.dagger.HomeStatusBarScope;
 import com.android.systemui.statusbar.policy.Clock;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener;
 import com.android.systemui.util.ViewController;
 
 import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.kt
index a6374a6..cd9b9d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone
 
+import android.content.Context
 import android.view.WindowInsetsController
 import com.android.internal.colorextraction.ColorExtractor
 import com.android.internal.view.AppearanceRegion
@@ -64,4 +65,8 @@
         scrimBehindAlpha: Float,
         scrimInFrontColor: ColorExtractor.GradientColors,
     )
+
+    fun interface Factory {
+        fun create(context: Context): LightBarController
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
index ccb9a11..1a4f3ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
@@ -22,6 +22,7 @@
 import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
 import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
+import android.content.Context;
 import android.graphics.Rect;
 import android.util.Log;
 import android.view.Display;
@@ -34,12 +35,15 @@
 
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.view.AppearanceRegion;
+import com.android.systemui.dagger.qualifiers.Application;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.statusbar.data.model.StatusBarAppearance;
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore;
 import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository;
+import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.util.Compile;
 import com.android.systemui.util.kotlin.JavaAdapterKt;
@@ -55,6 +59,8 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
+import javax.inject.Inject;
+
 /**
  * Controls how light status bar flag applies to the icons.
  */
@@ -67,6 +73,7 @@
 
     private static final float NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD = 0.1f;
 
+    private final int mDisplayId;
     private final CoroutineScope mCoroutineScope;
     private final SysuiDarkIconDispatcher mStatusBarIconController;
     private final BatteryController mBatteryController;
@@ -140,6 +147,7 @@
             DumpManager dumpManager,
             @Main CoroutineContext mainContext,
             BiometricUnlockController biometricUnlockController) {
+        mDisplayId = displayId;
         mCoroutineScope = coroutineScope;
         mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher;
         mBatteryController = batteryController;
@@ -155,7 +163,12 @@
 
     @Override
     public void start() {
-        mDumpManager.registerCriticalDumpable(mDumpableName, this);
+        if (mDisplayId == Display.DEFAULT_DISPLAY) {
+            // Can only register on default display, because NavigationBar creates its own instance
+            // as well as PerDisplayStore.
+            // TODO: b/380394368 - make sure there is only one instance per display.
+            mDumpManager.registerCriticalDumpable(mDumpableName, this);
+        }
         mBatteryController.addCallback(this);
         mNavigationMode = mNavModeController.addListener(mNavigationModeListener);
         JavaAdapterKt.collectFlow(
@@ -490,4 +503,36 @@
                 DarkIconDispatcher darkIconDispatcher,
                 StatusBarModePerDisplayRepository statusBarModePerDisplayRepository);
     }
+
+    public static class LegacyFactory implements LightBarController.Factory {
+
+        private final Factory mFactory;
+        private final CoroutineScope mApplicationScope;
+        private final DarkIconDispatcherStore mDarkIconDispatcherStore;
+        private final StatusBarModeRepositoryStore mStatusBarModeRepositoryStore;
+
+        @Inject
+        public LegacyFactory(
+                LightBarControllerImpl.Factory factory,
+                @Application CoroutineScope applicationScope,
+                DarkIconDispatcherStore darkIconDispatcherStore,
+                StatusBarModeRepositoryStore statusBarModeRepositoryStore) {
+            mFactory = factory;
+            mApplicationScope = applicationScope;
+            mDarkIconDispatcherStore = darkIconDispatcherStore;
+            mStatusBarModeRepositoryStore = statusBarModeRepositoryStore;
+        }
+
+        @NonNull
+        @Override
+        public LightBarController create(@NonNull Context context) {
+            // TODO: b/380394368 - Make sure correct per display instances are used.
+            return mFactory.create(
+                    context.getDisplayId(),
+                    mApplicationScope,
+                    mDarkIconDispatcherStore.getDefaultDisplay(),
+                    mStatusBarModeRepositoryStore.getDefaultDisplay()
+            );
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManager.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManager.java
index d2c2003..bea8397 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManager.java
@@ -47,8 +47,8 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener;
 import com.android.systemui.util.kotlin.JavaAdapter;
 
 import java.io.PrintWriter;
@@ -62,7 +62,7 @@
  * of HeadsUpNotifications.
  */
 @SysUISingleton
-public final class StatusBarTouchableRegionManager implements Dumpable {
+public final class ShadeTouchableRegionManager implements Dumpable {
     private static final String TAG = "TouchableRegionManager";
 
     private final Context mContext;
@@ -90,7 +90,7 @@
     private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener;
 
     @Inject
-    public StatusBarTouchableRegionManager(
+    public ShadeTouchableRegionManager(
             Context context,
             NotificationShadeWindowController notificationShadeWindowController,
             ConfigurationController configurationController,
@@ -165,7 +165,7 @@
 
     @Override
     public void dump(PrintWriter pw, String[] args) {
-        pw.println("StatusBarTouchableRegionManager state:");
+        pw.println("ShadeTouchableRegionManager state:");
         pw.print("  mTouchableRegion=");
         pw.println(mTouchableRegion);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index af98311..e33baf7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -79,8 +79,8 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowDragController;
 import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.HeadsUpUtil;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.wmshell.BubblesManager;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 79ea59c..b3cc047 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -69,7 +69,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.util.Set;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
index 58386b0..4f32aaa26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
@@ -35,7 +35,10 @@
 import com.android.systemui.statusbar.data.repository.PrivacyDotWindowControllerStoreModule
 import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
 import com.android.systemui.statusbar.events.PrivacyDotViewControllerModule
+import com.android.systemui.statusbar.phone.AutoHideControllerStore
 import com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks
+import com.android.systemui.statusbar.phone.MultiDisplayAutoHideControllerStore
+import com.android.systemui.statusbar.phone.SingleDisplayAutoHideControllerStore
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
 import com.android.systemui.statusbar.window.data.repository.StatusBarWindowStateRepositoryStore
 import com.android.systemui.statusbar.window.data.repository.StatusBarWindowStateRepositoryStoreImpl
@@ -120,6 +123,7 @@
             statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
             initializerStore: StatusBarInitializerStore,
             statusBarWindowControllerStore: StatusBarWindowControllerStore,
+            autoHideControllerStore: AutoHideControllerStore,
             statusBarOrchestratorFactory: StatusBarOrchestrator.Factory,
         ): StatusBarOrchestrator {
             return statusBarOrchestratorFactory.create(
@@ -129,6 +133,7 @@
                 statusBarModeRepositoryStore.defaultDisplay,
                 initializerStore.defaultDisplay,
                 statusBarWindowControllerStore.defaultDisplay,
+                autoHideControllerStore.defaultDisplay,
             )
         }
 
@@ -186,5 +191,32 @@
                 singleDisplayStoreLazy.get()
             }
         }
+
+        @Provides
+        @SysUISingleton
+        fun autoHideStore(
+            singleDisplayLazy: Lazy<SingleDisplayAutoHideControllerStore>,
+            multiDisplayLazy: Lazy<MultiDisplayAutoHideControllerStore>,
+        ): AutoHideControllerStore {
+            return if (StatusBarConnectedDisplays.isEnabled) {
+                multiDisplayLazy.get()
+            } else {
+                singleDisplayLazy.get()
+            }
+        }
+
+        @Provides
+        @SysUISingleton
+        @IntoMap
+        @ClassKey(AutoHideControllerStore::class)
+        fun storeAsCoreStartable(
+            multiDisplayLazy: Lazy<MultiDisplayAutoHideControllerStore>
+        ): CoreStartable {
+            return if (StatusBarConnectedDisplays.isEnabled) {
+                multiDisplayLazy.get()
+            } else {
+                CoreStartable.NOP
+            }
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index aac2cd1..78926c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -25,6 +25,7 @@
 import android.content.Context
 import android.view.View
 import androidx.annotation.VisibleForTesting
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.CoreStartable
 import com.android.systemui.Dumpable
@@ -58,7 +59,6 @@
 import java.util.concurrent.Executor
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /** A controller to handle the ongoing call chip in the collapsed status bar. */
 @SysUISingleton
@@ -122,9 +122,9 @@
                             entry.sbn.uid,
                             entry.sbn.notification.extras.getInt(
                                 Notification.EXTRA_CALL_TYPE,
-                                -1
+                                -1,
                             ) == CALL_TYPE_ONGOING,
-                            statusBarSwipedAway = callNotificationInfo?.statusBarSwipedAway ?: false
+                            statusBarSwipedAway = callNotificationInfo?.statusBarSwipedAway ?: false,
                         )
                     if (newOngoingCallInfo == callNotificationInfo) {
                         return
@@ -236,7 +236,7 @@
                     bool1 = Flags.statusBarCallChipNotificationIcon()
                     bool2 = currentInfo.notificationIconView != null
                 },
-                { "Creating OngoingCallModel.InCall. notifIconFlag=$bool1 hasIcon=$bool2" }
+                { "Creating OngoingCallModel.InCall. notifIconFlag=$bool1 hasIcon=$bool2" },
             )
             val icon =
                 if (Flags.statusBarCallChipNotificationIcon()) {
@@ -288,7 +288,7 @@
                     str1 = notifModel.callType.name
                     bool1 = notifModel.statusBarChipIconView != null
                 },
-                { "NotifInteractorCallModel: key=$str1 when=$long1 callType=$str2 hasIcon=$bool1" }
+                { "NotifInteractorCallModel: key=$str1 when=$long1 callType=$str2 hasIcon=$bool1" },
             )
 
             val newOngoingCallInfo =
@@ -299,7 +299,7 @@
                     notifModel.contentIntent,
                     notifModel.uid,
                     isOngoing = true,
-                    statusBarSwipedAway = callNotificationInfo?.statusBarSwipedAway ?: false
+                    statusBarSwipedAway = callNotificationInfo?.statusBarSwipedAway ?: false,
                 )
             if (newOngoingCallInfo == callNotificationInfo) {
                 return
@@ -378,7 +378,7 @@
                     ActivityTransitionAnimator.Controller.fromView(
                         backgroundView,
                         InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
-                    )
+                    ),
                 )
             }
         }
@@ -455,7 +455,7 @@
         /** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */
         val isOngoing: Boolean,
         /** True if the user has swiped away the status bar while in this phone call. */
-        val statusBarSwipedAway: Boolean
+        val statusBarSwipedAway: Boolean,
     ) {
         /**
          * Returns true if the notification information has a valid call start time. See
@@ -472,6 +472,9 @@
     /**
      * Observer to tell us when the app that posted the ongoing call notification is visible so that
      * we don't show the call chip at the same time (since the timers could be out-of-sync).
+     *
+     * For a more recommended architecture implementation, see
+     * [com.android.systemui.activity.data.repository.ActivityManagerRepository].
      */
     inner class CallAppUidObserver : UidObserver() {
         /** True if the application managing the call is visible to the user. */
@@ -512,7 +515,7 @@
                     uidObserver,
                     ActivityManager.UID_OBSERVER_PROCSTATE,
                     ActivityManager.PROCESS_STATE_UNKNOWN,
-                    context.opPackageName
+                    context.opPackageName,
                 )
                 isRegistered = true
             } catch (se: SecurityException) {
@@ -537,7 +540,7 @@
             uid: Int,
             procState: Int,
             procStateSeq: Long,
-            capability: Int
+            capability: Int,
         ) {
             val currentCallAppUid = callAppUid ?: return
             if (uid != currentCallAppUid) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index a115baa..52f80fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -24,6 +24,7 @@
 import android.media.MediaRouter.RouteInfo;
 import android.media.projection.MediaProjectionInfo;
 import android.media.projection.MediaProjectionManager;
+import android.media.projection.StopReason;
 import android.os.Handler;
 import android.util.ArrayMap;
 
@@ -190,7 +191,7 @@
         if (isProjection) {
             final MediaProjectionInfo projection = (MediaProjectionInfo) device.getTag();
             if (Objects.equals(mProjectionManager.getActiveProjectionInfo(), projection)) {
-                mProjectionManager.stopActiveProjection();
+                mProjectionManager.stopActiveProjection(StopReason.STOP_QS_TILE);
             } else {
                 mLogger.logStopCastingNoProjection(projection);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
index 616992e..56c9e9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
@@ -41,8 +41,8 @@
 import android.view.accessibility.AccessibilityNodeInfo
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction
 import android.widget.Button
-import com.android.systemui.res.R
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.res.R
 import com.android.systemui.shared.system.ActivityManagerWrapper
 import com.android.systemui.shared.system.DevicePolicyManagerWrapper
 import com.android.systemui.shared.system.PackageManagerWrapper
@@ -50,6 +50,7 @@
 import com.android.systemui.statusbar.NotificationUiAdjustment
 import com.android.systemui.statusbar.SmartReplyController
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.logging.NotificationLogger
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil
 import com.android.systemui.statusbar.policy.InflatedSmartReplyState.SuppressedActions
@@ -63,40 +64,42 @@
 import javax.inject.Inject
 import kotlin.system.measureTimeMillis
 
-
 /** Returns whether we should show the smart reply view and its smart suggestions. */
 fun shouldShowSmartReplyView(
     entry: NotificationEntry,
-    smartReplyState: InflatedSmartReplyState
+    smartReplyState: InflatedSmartReplyState,
 ): Boolean {
-    if (smartReplyState.smartReplies == null &&
-            smartReplyState.smartActions == null) {
+    if (smartReplyState.smartReplies == null && smartReplyState.smartActions == null) {
         // There are no smart replies and no smart actions.
         return false
     }
     // If we are showing the spinner we don't want to add the buttons.
-    val showingSpinner = entry.sbn.notification.extras
-            .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false)
+    val showingSpinner =
+        entry.sbn.notification.extras.getBoolean(
+            Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER,
+            false,
+        )
     if (showingSpinner) {
         return false
     }
     // If we are keeping the notification around while sending we don't want to add the buttons.
-    return !entry.sbn.notification.extras
-            .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false)
+    return !entry.sbn.notification.extras.getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false)
 }
 
 /** Determines if two [InflatedSmartReplyState] are visually similar. */
 fun areSuggestionsSimilar(
     left: InflatedSmartReplyState?,
-    right: InflatedSmartReplyState?
-): Boolean = when {
-    left === right -> true
-    left == null || right == null -> false
-    left.hasPhishingAction != right.hasPhishingAction -> false
-    left.smartRepliesList != right.smartRepliesList -> false
-    left.suppressedActionIndices != right.suppressedActionIndices -> false
-    else -> !NotificationUiAdjustment.areDifferent(left.smartActionsList, right.smartActionsList)
-}
+    right: InflatedSmartReplyState?,
+): Boolean =
+    when {
+        left === right -> true
+        left == null || right == null -> false
+        left.hasPhishingAction != right.hasPhishingAction -> false
+        left.smartRepliesList != right.smartRepliesList -> false
+        left.suppressedActionIndices != right.suppressedActionIndices -> false
+        else ->
+            !NotificationUiAdjustment.areDifferent(left.smartActionsList, right.smartActionsList)
+    }
 
 interface SmartReplyStateInflater {
     fun inflateSmartReplyState(entry: NotificationEntry): InflatedSmartReplyState
@@ -106,181 +109,211 @@
         notifPackageContext: Context,
         entry: NotificationEntry,
         existingSmartReplyState: InflatedSmartReplyState?,
-        newSmartReplyState: InflatedSmartReplyState
+        newSmartReplyState: InflatedSmartReplyState,
     ): InflatedSmartReplyViewHolder
 }
 
-/*internal*/ class SmartReplyStateInflaterImpl @Inject constructor(
+/*internal*/ class SmartReplyStateInflaterImpl
+@Inject
+constructor(
     private val constants: SmartReplyConstants,
     private val activityManagerWrapper: ActivityManagerWrapper,
     private val packageManagerWrapper: PackageManagerWrapper,
     private val devicePolicyManagerWrapper: DevicePolicyManagerWrapper,
     private val smartRepliesInflater: SmartReplyInflater,
-    private val smartActionsInflater: SmartActionInflater
+    private val smartActionsInflater: SmartActionInflater,
 ) : SmartReplyStateInflater {
 
     override fun inflateSmartReplyState(entry: NotificationEntry): InflatedSmartReplyState =
-            chooseSmartRepliesAndActions(entry)
+        chooseSmartRepliesAndActions(entry)
 
     override fun inflateSmartReplyViewHolder(
         sysuiContext: Context,
         notifPackageContext: Context,
         entry: NotificationEntry,
         existingSmartReplyState: InflatedSmartReplyState?,
-        newSmartReplyState: InflatedSmartReplyState
+        newSmartReplyState: InflatedSmartReplyState,
     ): InflatedSmartReplyViewHolder {
         if (!shouldShowSmartReplyView(entry, newSmartReplyState)) {
             return InflatedSmartReplyViewHolder(
-                    null /* smartReplyView */,
-                    null /* smartSuggestionButtons */)
+                null /* smartReplyView */,
+                null, /* smartSuggestionButtons */
+            )
         }
 
         // Only block clicks if the smart buttons are different from the previous set - to avoid
         // scenarios where a user incorrectly cannot click smart buttons because the
         // notification is updated.
         val delayOnClickListener =
-                !areSuggestionsSimilar(existingSmartReplyState, newSmartReplyState)
+            !areSuggestionsSimilar(existingSmartReplyState, newSmartReplyState)
 
         val smartReplyView = SmartReplyView.inflate(sysuiContext, constants)
 
         val smartReplies = newSmartReplyState.smartReplies
         smartReplyView.setSmartRepliesGeneratedByAssistant(smartReplies?.fromAssistant ?: false)
-        val smartReplyButtons = smartReplies?.let {
-            smartReplies.choices.asSequence().mapIndexed { index, choice ->
-                smartRepliesInflater.inflateReplyButton(
+        val smartReplyButtons =
+            smartReplies?.let {
+                smartReplies.choices.asSequence().mapIndexed { index, choice ->
+                    smartRepliesInflater.inflateReplyButton(
                         smartReplyView,
                         entry,
                         smartReplies,
                         index,
                         choice,
-                        delayOnClickListener)
-            }
-        } ?: emptySequence()
+                        delayOnClickListener,
+                    )
+                }
+            } ?: emptySequence()
 
-        val smartActionButtons = newSmartReplyState.smartActions?.let { smartActions ->
-            val themedPackageContext =
+        val smartActionButtons =
+            newSmartReplyState.smartActions?.let { smartActions ->
+                val themedPackageContext =
                     ContextThemeWrapper(notifPackageContext, sysuiContext.theme)
-            smartActions.actions.asSequence()
+                smartActions.actions
+                    .asSequence()
                     .filter { it.actionIntent != null }
                     .mapIndexed { index, action ->
                         smartActionsInflater.inflateActionButton(
-                                smartReplyView,
-                                entry,
-                                smartActions,
-                                index,
-                                action,
-                                delayOnClickListener,
-                                themedPackageContext)
+                            smartReplyView,
+                            entry,
+                            smartActions,
+                            index,
+                            action,
+                            delayOnClickListener,
+                            themedPackageContext,
+                        )
                     }
-        } ?: emptySequence()
+            } ?: emptySequence()
 
         return InflatedSmartReplyViewHolder(
-                smartReplyView,
-                (smartReplyButtons + smartActionButtons).toList())
+            smartReplyView,
+            (smartReplyButtons + smartActionButtons).toList(),
+        )
     }
 
     /**
      * Chose what smart replies and smart actions to display. App generated suggestions take
-     * precedence. So if the app provides any smart replies, we don't show any
-     * replies or actions generated by the NotificationAssistantService (NAS), and if the app
-     * provides any smart actions we also don't show any NAS-generated replies or actions.
+     * precedence. So if the app provides any smart replies, we don't show any replies or actions
+     * generated by the NotificationAssistantService (NAS), and if the app provides any smart
+     * actions we also don't show any NAS-generated replies or actions.
      */
     fun chooseSmartRepliesAndActions(entry: NotificationEntry): InflatedSmartReplyState {
         val notification = entry.sbn.notification
         val remoteInputActionPair = notification.findRemoteInputActionPair(false /* freeform */)
         val freeformRemoteInputActionPair =
-                notification.findRemoteInputActionPair(true /* freeform */)
+            notification.findRemoteInputActionPair(true /* freeform */)
         if (!constants.isEnabled) {
             if (DEBUG) {
-                Log.d(TAG, "Smart suggestions not enabled, not adding suggestions for " +
-                        entry.sbn.key)
+                Log.d(
+                    TAG,
+                    "Smart suggestions not enabled, not adding suggestions for " + entry.sbn.key,
+                )
             }
             return InflatedSmartReplyState(null, null, null, false)
         }
         // Only use smart replies from the app if they target P or above. We have this check because
         // the smart reply API has been used for other things (Wearables) in the past. The API to
         // add smart actions is new in Q so it doesn't require a target-sdk check.
-        val enableAppGeneratedSmartReplies = (!constants.requiresTargetingP() ||
-                entry.targetSdk >= Build.VERSION_CODES.P)
+        val enableAppGeneratedSmartReplies =
+            (!constants.requiresTargetingP() || entry.targetSdk >= Build.VERSION_CODES.P)
         val appGeneratedSmartActions = notification.contextualActions
 
-        var smartReplies: SmartReplies? = when {
-            enableAppGeneratedSmartReplies -> remoteInputActionPair?.let { pair ->
-                pair.second.actionIntent?.let { actionIntent ->
-                    if (pair.first.choices?.isNotEmpty() == true)
-                        SmartReplies(
-                                pair.first.choices.asList(),
-                                pair.first,
-                                actionIntent,
-                                false /* fromAssistant */)
-                    else null
-                }
+        var smartReplies: SmartReplies? =
+            when {
+                enableAppGeneratedSmartReplies ->
+                    remoteInputActionPair?.let { pair ->
+                        pair.second.actionIntent?.let { actionIntent ->
+                            if (pair.first.choices?.isNotEmpty() == true)
+                                SmartReplies(
+                                    pair.first.choices.asList(),
+                                    pair.first,
+                                    actionIntent,
+                                    false, /* fromAssistant */
+                                )
+                            else null
+                        }
+                    }
+                else -> null
             }
-            else -> null
-        }
-        var smartActions: SmartActions? = when {
-            appGeneratedSmartActions.isNotEmpty() ->
-                SmartActions(appGeneratedSmartActions, false /* fromAssistant */)
-            else -> null
-        }
+        var smartActions: SmartActions? =
+            when {
+                appGeneratedSmartActions.isNotEmpty() ->
+                    SmartActions(appGeneratedSmartActions, false /* fromAssistant */)
+                else -> null
+            }
         // Apps didn't provide any smart replies / actions, use those from NAS (if any).
         if (smartReplies == null && smartActions == null) {
             val entryReplies = entry.smartReplies
             val entryActions = entry.smartActions
-            if (entryReplies.isNotEmpty() &&
+            if (
+                entryReplies.isNotEmpty() &&
                     freeformRemoteInputActionPair != null &&
                     freeformRemoteInputActionPair.second.allowGeneratedReplies &&
-                    freeformRemoteInputActionPair.second.actionIntent != null) {
-                smartReplies = SmartReplies(
+                    freeformRemoteInputActionPair.second.actionIntent != null
+            ) {
+                smartReplies =
+                    SmartReplies(
                         entryReplies,
                         freeformRemoteInputActionPair.first,
                         freeformRemoteInputActionPair.second.actionIntent,
-                        true /* fromAssistant */)
+                        true, /* fromAssistant */
+                    )
             }
-            if (entryActions.isNotEmpty() &&
-                    notification.allowSystemGeneratedContextualActions) {
-                val systemGeneratedActions: List<Notification.Action> = when {
-                    activityManagerWrapper.isLockTaskKioskModeActive ->
-                        // Filter actions if we're in kiosk-mode - we don't care about screen
-                        // pinning mode, since notifications aren't shown there anyway.
-                        filterAllowlistedLockTaskApps(entryActions)
-                    else -> entryActions
-                }
+            if (entryActions.isNotEmpty() && notification.allowSystemGeneratedContextualActions) {
+                val systemGeneratedActions: List<Notification.Action> =
+                    when {
+                        activityManagerWrapper.isLockTaskKioskModeActive ->
+                            // Filter actions if we're in kiosk-mode - we don't care about screen
+                            // pinning mode, since notifications aren't shown there anyway.
+                            filterAllowlistedLockTaskApps(entryActions)
+                        else -> entryActions
+                    }
                 smartActions = SmartActions(systemGeneratedActions, true /* fromAssistant */)
             }
         }
-        val hasPhishingAction = smartActions?.actions?.any {
-            it.isContextual && it.semanticAction ==
-                    Notification.Action.SEMANTIC_ACTION_CONVERSATION_IS_PHISHING
-        } ?: false
+        val hasPhishingAction =
+            smartActions?.actions?.any {
+                it.isContextual &&
+                    it.semanticAction ==
+                        Notification.Action.SEMANTIC_ACTION_CONVERSATION_IS_PHISHING
+            } ?: false
         var suppressedActions: SuppressedActions? = null
         if (hasPhishingAction) {
             // If there is a phishing action, calculate the indices of the actions with RemoteInput
             //  as those need to be hidden from the view.
-            val suppressedActionIndices = notification.actions.mapIndexedNotNull { index, action ->
-                if (action.remoteInputs?.isNotEmpty() == true) index else null
-            }
+            val suppressedActionIndices =
+                notification.actions.mapIndexedNotNull { index, action ->
+                    if (action.remoteInputs?.isNotEmpty() == true) index else null
+                }
             suppressedActions = SuppressedActions(suppressedActionIndices)
         }
-        return InflatedSmartReplyState(smartReplies, smartActions, suppressedActions,
-                hasPhishingAction)
+        return InflatedSmartReplyState(
+            smartReplies,
+            smartActions,
+            suppressedActions,
+            hasPhishingAction,
+        )
     }
 
     /**
-     * Filter actions so that only actions pointing to allowlisted apps are permitted.
-     * This filtering is only meaningful when in lock-task mode.
+     * Filter actions so that only actions pointing to allowlisted apps are permitted. This
+     * filtering is only meaningful when in lock-task mode.
      */
     private fun filterAllowlistedLockTaskApps(
         actions: List<Notification.Action>
-    ): List<Notification.Action> = actions.filter { action ->
-        //  Only allow actions that are explicit (implicit intents are not handled in lock-task
-        //  mode), and link to allowlisted apps.
-        action.actionIntent?.intent?.let { intent ->
-            packageManagerWrapper.resolveActivity(intent, 0 /* flags */)
-        }?.let { resolveInfo ->
-            devicePolicyManagerWrapper.isLockTaskPermitted(resolveInfo.activityInfo.packageName)
-        } ?: false
-    }
+    ): List<Notification.Action> =
+        actions.filter { action ->
+            //  Only allow actions that are explicit (implicit intents are not handled in lock-task
+            //  mode), and link to allowlisted apps.
+            action.actionIntent
+                ?.intent
+                ?.let { intent -> packageManagerWrapper.resolveActivity(intent, 0 /* flags */) }
+                ?.let { resolveInfo ->
+                    devicePolicyManagerWrapper.isLockTaskPermitted(
+                        resolveInfo.activityInfo.packageName
+                    )
+                } ?: false
+        }
 }
 
 interface SmartActionInflater {
@@ -291,7 +324,7 @@
         actionIndex: Int,
         action: Notification.Action,
         delayOnClickListener: Boolean,
-        packageContext: Context
+        packageContext: Context,
     ): Button
 }
 
@@ -310,28 +343,32 @@
         val bitmap: Bitmap?
         val durationMillis = measureTimeMillis {
             val source = ImageDecoder.createSource(packageContext.contentResolver, icon.uri)
-            bitmap = ImageDecoder.decodeBitmap(source) { decoder, _, _ ->
-                decoder.setTargetSize(targetSize, targetSize)
-                decoder.allocator = ImageDecoder.ALLOCATOR_DEFAULT
-            }
+            bitmap =
+                ImageDecoder.decodeBitmap(source) { decoder, _, _ ->
+                    decoder.setTargetSize(targetSize, targetSize)
+                    decoder.allocator = ImageDecoder.ALLOCATOR_DEFAULT
+                }
         }
         if (durationMillis > ICON_TASK_TIMEOUT_MS) {
             Log.w(TAG, "Loading $icon took ${durationMillis / 1000f} sec")
         }
         checkNotNull(bitmap) { "ImageDecoder.decodeBitmap() returned null" }
     }
-    val bitmap = runCatching {
-        iconTaskThreadPool.execute(bitmapTask)
-        bitmapTask.get(ICON_TASK_TIMEOUT_MS, TimeUnit.MILLISECONDS)
-    }.getOrElse { ex ->
-        Log.e(TAG, "Failed to load $icon: $ex")
-        bitmapTask.cancel(true)
-        return null
-    }
+    val bitmap =
+        runCatching {
+                iconTaskThreadPool.execute(bitmapTask)
+                bitmapTask.get(ICON_TASK_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+            }
+            .getOrElse { ex ->
+                Log.e(TAG, "Failed to load $icon: $ex")
+                bitmapTask.cancel(true)
+                return null
+            }
     // TODO(b/288561520): rewrite Icon so that we don't need to duplicate this logic
     val bitmapDrawable = BitmapDrawable(packageContext.resources, bitmap)
-    val result = if (icon.type == Icon.TYPE_URI_ADAPTIVE_BITMAP)
-        AdaptiveIconDrawable(null, bitmapDrawable) else bitmapDrawable
+    val result =
+        if (icon.type == Icon.TYPE_URI_ADAPTIVE_BITMAP) AdaptiveIconDrawable(null, bitmapDrawable)
+        else bitmapDrawable
     if (icon.hasTint()) {
         result.mutate()
         result.setTintList(icon.tintList)
@@ -340,11 +377,13 @@
     return result
 }
 
-/* internal */ class SmartActionInflaterImpl @Inject constructor(
+/* internal */ class SmartActionInflaterImpl
+@Inject
+constructor(
     private val constants: SmartReplyConstants,
     private val activityStarter: ActivityStarter,
     private val smartReplyController: SmartReplyController,
-    private val headsUpManager: HeadsUpManager
+    private val headsUpManager: HeadsUpManager,
 ) : SmartActionInflater {
 
     override fun inflateActionButton(
@@ -354,17 +393,18 @@
         actionIndex: Int,
         action: Notification.Action,
         delayOnClickListener: Boolean,
-        packageContext: Context
+        packageContext: Context,
     ): Button =
-            (LayoutInflater.from(parent.context)
-                    .inflate(R.layout.smart_action_button, parent, false) as Button
-            ).apply {
+        (LayoutInflater.from(parent.context).inflate(R.layout.smart_action_button, parent, false)
+                as Button)
+            .apply {
                 text = action.title
 
-                // We received the Icon from the application - so use the Context of the application to
+                // We received the Icon from the application - so use the Context of the application
+                // to
                 // reference icon resources.
-                val newIconSize = context.resources
-                    .getDimensionPixelSize(R.dimen.smart_action_button_icon_size)
+                val newIconSize =
+                    context.resources.getDimensionPixelSize(R.dimen.smart_action_button_icon_size)
                 val iconDrawable =
                     loadIconDrawableWithTimeout(action.getIcon(), packageContext, newIconSize)
                         ?: GradientDrawable()
@@ -372,13 +412,15 @@
                 // Add the action icon to the Smart Action button.
                 setCompoundDrawablesRelative(iconDrawable, null, null, null)
 
-                val onClickListener = View.OnClickListener {
-                    onSmartActionClick(entry, smartActions, actionIndex, action)
-                }
+                val onClickListener =
+                    View.OnClickListener {
+                        onSmartActionClick(entry, smartActions, actionIndex, action)
+                    }
                 setOnClickListener(
-                        if (delayOnClickListener)
-                            DelayedOnClickListener(onClickListener, constants.onClickInitDelay)
-                        else onClickListener)
+                    if (delayOnClickListener)
+                        DelayedOnClickListener(onClickListener, constants.onClickInitDelay)
+                    else onClickListener
+                )
 
                 // Mark this as an Action button
                 (layoutParams as SmartReplyView.LayoutParams).mButtonType = SmartButtonType.ACTION
@@ -388,18 +430,31 @@
         entry: NotificationEntry,
         smartActions: SmartActions,
         actionIndex: Int,
-        action: Notification.Action
+        action: Notification.Action,
     ) =
-        if (smartActions.fromAssistant &&
-            SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY == action.semanticAction) {
-            entry.row.doSmartActionClick(entry.row.x.toInt() / 2,
-                entry.row.y.toInt() / 2, SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY)
-            smartReplyController
-                .smartActionClicked(entry, actionIndex, action, smartActions.fromAssistant)
+        if (
+            smartActions.fromAssistant &&
+                SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY == action.semanticAction
+        ) {
+            entry.row.doSmartActionClick(
+                entry.row.x.toInt() / 2,
+                entry.row.y.toInt() / 2,
+                SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY,
+            )
+            smartReplyController.smartActionClicked(
+                entry,
+                actionIndex,
+                action,
+                smartActions.fromAssistant,
+            )
         } else {
             activityStarter.startPendingIntentDismissingKeyguard(action.actionIntent, entry.row) {
-                smartReplyController
-                    .smartActionClicked(entry, actionIndex, action, smartActions.fromAssistant)
+                smartReplyController.smartActionClicked(
+                    entry,
+                    actionIndex,
+                    action,
+                    smartActions.fromAssistant,
+                )
             }
         }
 }
@@ -411,16 +466,18 @@
         smartReplies: SmartReplies,
         replyIndex: Int,
         choice: CharSequence,
-        delayOnClickListener: Boolean
+        delayOnClickListener: Boolean,
     ): Button
 }
 
-class SmartReplyInflaterImpl @Inject constructor(
+class SmartReplyInflaterImpl
+@Inject
+constructor(
     private val constants: SmartReplyConstants,
     private val keyguardDismissUtil: KeyguardDismissUtil,
     private val remoteInputManager: NotificationRemoteInputManager,
     private val smartReplyController: SmartReplyController,
-    private val context: Context
+    private val context: Context,
 ) : SmartReplyInflater {
 
     override fun inflateReplyButton(
@@ -429,37 +486,35 @@
         smartReplies: SmartReplies,
         replyIndex: Int,
         choice: CharSequence,
-        delayOnClickListener: Boolean
+        delayOnClickListener: Boolean,
     ): Button =
-            (LayoutInflater.from(parent.context)
-                    .inflate(R.layout.smart_reply_button, parent, false) as Button
-            ).apply {
+        (LayoutInflater.from(parent.context).inflate(R.layout.smart_reply_button, parent, false)
+                as Button)
+            .apply {
                 text = choice
-                val onClickListener = View.OnClickListener {
-                    onSmartReplyClick(
-                            entry,
-                            smartReplies,
-                            replyIndex,
-                            parent,
-                            this,
-                            choice)
-                }
-                setOnClickListener(
-                        if (delayOnClickListener)
-                            DelayedOnClickListener(onClickListener, constants.onClickInitDelay)
-                        else onClickListener)
-                accessibilityDelegate = object : View.AccessibilityDelegate() {
-                    override fun onInitializeAccessibilityNodeInfo(
-                        host: View,
-                        info: AccessibilityNodeInfo
-                    ) {
-                        super.onInitializeAccessibilityNodeInfo(host, info)
-                        val label = parent.resources
-                                .getString(R.string.accessibility_send_smart_reply)
-                        val action = AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, label)
-                        info.addAction(action)
+                val onClickListener =
+                    View.OnClickListener {
+                        onSmartReplyClick(entry, smartReplies, replyIndex, parent, this, choice)
                     }
-                }
+                setOnClickListener(
+                    if (delayOnClickListener)
+                        DelayedOnClickListener(onClickListener, constants.onClickInitDelay)
+                    else onClickListener
+                )
+                accessibilityDelegate =
+                    object : View.AccessibilityDelegate() {
+                        override fun onInitializeAccessibilityNodeInfo(
+                            host: View,
+                            info: AccessibilityNodeInfo,
+                        ) {
+                            super.onInitializeAccessibilityNodeInfo(host, info)
+                            val label =
+                                parent.resources.getString(R.string.accessibility_send_smart_reply)
+                            val action =
+                                AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, label)
+                            info.addAction(action)
+                        }
+                    }
                 // TODO: probably shouldn't do this here, bad API
                 // Mark this as a Reply button
                 (layoutParams as SmartReplyView.LayoutParams).mButtonType = SmartButtonType.REPLY
@@ -471,39 +526,52 @@
         replyIndex: Int,
         smartReplyView: SmartReplyView,
         button: Button,
-        choice: CharSequence
-    ) = keyguardDismissUtil.executeWhenUnlocked(!entry.isRowPinned) {
-        val canEditBeforeSend = constants.getEffectiveEditChoicesBeforeSending(
-                smartReplies.remoteInput.editChoicesBeforeSending)
-        if (canEditBeforeSend) {
-            remoteInputManager.activateRemoteInput(
+        choice: CharSequence,
+    ) =
+        keyguardDismissUtil.executeWhenUnlocked(!entry.isRowPinned) {
+            val canEditBeforeSend =
+                constants.getEffectiveEditChoicesBeforeSending(
+                    smartReplies.remoteInput.editChoicesBeforeSending
+                )
+            if (canEditBeforeSend) {
+                remoteInputManager.activateRemoteInput(
                     button,
                     arrayOf(smartReplies.remoteInput),
                     smartReplies.remoteInput,
                     smartReplies.pendingIntent,
-                    NotificationEntry.EditedSuggestionInfo(choice, replyIndex))
-        } else {
-            smartReplyController.smartReplySent(
+                    NotificationEntry.EditedSuggestionInfo(choice, replyIndex),
+                )
+            } else {
+                smartReplyController.smartReplySent(
                     entry,
                     replyIndex,
                     button.text,
                     NotificationLogger.getNotificationLocation(entry).toMetricsEventEnum(),
-                    false /* modifiedBeforeSending */)
-            entry.setHasSentReply()
-            try {
-                val intent = createRemoteInputIntent(smartReplies, choice)
-                val opts = ActivityOptions.makeBasic()
-                opts.setPendingIntentBackgroundActivityStartMode(
-                        ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
-                smartReplies.pendingIntent.send(context, 0, intent, /* onFinished */null,
-                        /* handler */ null, /* requiredPermission */ null, opts.toBundle())
-            } catch (e: PendingIntent.CanceledException) {
-                Log.w(TAG, "Unable to send smart reply", e)
+                    false, /* modifiedBeforeSending */
+                )
+                entry.setHasSentReply()
+                try {
+                    val intent = createRemoteInputIntent(smartReplies, choice)
+                    val opts = ActivityOptions.makeBasic()
+                    opts.setPendingIntentBackgroundActivityStartMode(
+                        ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+                    )
+                    smartReplies.pendingIntent.send(
+                        context,
+                        0,
+                        intent, /* onFinished */
+                        null,
+                        /* handler */ null, /* requiredPermission */
+                        null,
+                        opts.toBundle(),
+                    )
+                } catch (e: PendingIntent.CanceledException) {
+                    Log.w(TAG, "Unable to send smart reply", e)
+                }
+                smartReplyView.hideSmartSuggestions()
             }
-            smartReplyView.hideSmartSuggestions()
+            false // do not defer
         }
-        false // do not defer
-    }
 
     private fun createRemoteInputIntent(smartReplies: SmartReplies, choice: CharSequence): Intent {
         val results = Bundle()
@@ -516,12 +584,11 @@
 }
 
 /**
- * An OnClickListener wrapper that blocks the underlying OnClickListener for a given amount of
- * time.
+ * An OnClickListener wrapper that blocks the underlying OnClickListener for a given amount of time.
  */
 private class DelayedOnClickListener(
     private val mActualListener: View.OnClickListener,
-    private val mInitDelayMs: Long
+    private val mInitDelayMs: Long,
 ) : View.OnClickListener {
 
     private val mInitTimeMs = SystemClock.elapsedRealtime()
@@ -535,7 +602,7 @@
     }
 
     private fun hasFinishedInitialization(): Boolean =
-            SystemClock.elapsedRealtime() >= mInitTimeMs + mInitDelayMs
+        SystemClock.elapsedRealtime() >= mInitTimeMs + mInitDelayMs
 }
 
 private const val TAG = "SmartReplyViewInflater"
@@ -544,12 +611,12 @@
 // convenience function that swaps parameter order so that lambda can be placed at the end
 private fun KeyguardDismissUtil.executeWhenUnlocked(
     requiresShadeOpen: Boolean,
-    onDismissAction: () -> Boolean
+    onDismissAction: () -> Boolean,
 ) = executeWhenUnlocked(onDismissAction, requiresShadeOpen, false)
 
 // convenience function that swaps parameter order so that lambda can be placed at the end
 private fun ActivityStarter.startPendingIntentDismissingKeyguard(
     intent: PendingIntent,
     associatedView: View?,
-    runnable: () -> Unit
-) = startPendingIntentDismissingKeyguard(intent, runnable::invoke, associatedView)
\ No newline at end of file
+    runnable: () -> Unit,
+) = startPendingIntentDismissingKeyguard(intent, runnable::invoke, associatedView)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
index c4b028d..1963ba2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
@@ -18,14 +18,18 @@
 
 import android.view.LayoutInflater
 import android.view.View
-import android.view.ViewGroup
 import android.widget.ImageButton
 import androidx.annotation.LayoutRes
 import androidx.compose.ui.util.fastForEachIndexed
+import androidx.constraintlayout.motion.widget.MotionLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import com.android.internal.R as internalR
+import com.android.settingslib.Utils
 import com.android.systemui.lifecycle.WindowLifecycleState
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.lifecycle.viewModel
 import com.android.systemui.res.R
+import com.android.systemui.util.children
 import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
 import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerButtonViewModel
 import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerDrawerState
@@ -33,7 +37,6 @@
 import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerViewModelState
 import com.android.systemui.volume.dialog.ringer.ui.viewmodel.VolumeDialogRingerDrawerViewModel
 import javax.inject.Inject
-import kotlin.math.abs
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 
@@ -44,12 +47,8 @@
 
     fun bind(view: View) {
         with(view) {
-            val drawerAndRingerContainer =
-                requireViewById<View>(R.id.volume_ringer_and_drawer_container)
-            val drawerContainer = requireViewById<View>(R.id.volume_drawer_container)
-            val selectedButtonView =
-                requireViewById<ImageButton>(R.id.volume_new_ringer_active_button)
             val volumeDialogBackgroundView = requireViewById<View>(R.id.volume_dialog_background)
+            val drawerContainer = requireViewById<MotionLayout>(R.id.volume_ringer_drawer)
             repeatWhenAttached {
                 viewModel(
                     traceName = "VolumeDialogRingerViewBinder",
@@ -62,29 +61,26 @@
                                 is RingerViewModelState.Available -> {
                                     val uiModel = ringerState.uiModel
 
-                                    bindSelectedButton(viewModel, uiModel, selectedButtonView)
-                                    bindDrawerButtons(viewModel, uiModel.availableButtons)
+                                    bindDrawerButtons(viewModel, uiModel)
 
-                                    // Set up views background and visibility
-                                    drawerAndRingerContainer.visibility = View.VISIBLE
+                                    // Set up view background and visibility
+                                    drawerContainer.visibility = View.VISIBLE
                                     when (uiModel.drawerState) {
                                         is RingerDrawerState.Initial -> {
-                                            drawerContainer.visibility = View.GONE
-                                            selectedButtonView.visibility = View.VISIBLE
+                                            drawerContainer.closeDrawer(uiModel.currentButtonIndex)
                                             volumeDialogBackgroundView.setBackgroundResource(
                                                 R.drawable.volume_dialog_background
                                             )
                                         }
                                         is RingerDrawerState.Closed -> {
-                                            drawerContainer.visibility = View.GONE
-                                            selectedButtonView.visibility = View.VISIBLE
+                                            drawerContainer.closeDrawer(uiModel.currentButtonIndex)
                                             volumeDialogBackgroundView.setBackgroundResource(
                                                 R.drawable.volume_dialog_background
                                             )
                                         }
                                         is RingerDrawerState.Open -> {
-                                            drawerContainer.visibility = View.VISIBLE
-                                            selectedButtonView.visibility = View.GONE
+                                            // Open drawer
+                                            drawerContainer.transitionToEnd()
                                             if (
                                                 uiModel.currentButtonIndex !=
                                                     uiModel.availableButtons.size - 1
@@ -97,7 +93,7 @@
                                     }
                                 }
                                 is RingerViewModelState.Unavailable -> {
-                                    drawerAndRingerContainer.visibility = View.GONE
+                                    drawerContainer.visibility = View.GONE
                                     volumeDialogBackgroundView.setBackgroundResource(
                                         R.drawable.volume_dialog_background
                                     )
@@ -112,15 +108,21 @@
 
     private fun View.bindDrawerButtons(
         viewModel: VolumeDialogRingerDrawerViewModel,
-        availableButtons: List<RingerButtonViewModel?>,
+        uiModel: RingerViewModel,
     ) {
-        val drawerOptions = requireViewById<ViewGroup>(R.id.volume_drawer_options)
-        val count = availableButtons.size
-        drawerOptions.ensureChildCount(R.layout.volume_ringer_button, count)
+        val drawerContainer = requireViewById<MotionLayout>(R.id.volume_ringer_drawer)
+        val count = uiModel.availableButtons.size
+        drawerContainer.ensureChildCount(R.layout.volume_ringer_button, count)
 
-        availableButtons.fastForEachIndexed { index, ringerButton ->
+        uiModel.availableButtons.fastForEachIndexed { index, ringerButton ->
             ringerButton?.let {
-                drawerOptions.getChildAt(count - index - 1).bindDrawerButton(it, viewModel)
+                val view = drawerContainer.getChildAt(count - index - 1)
+                // TODO (b/369995871): object animator for button switch ( active <-> inactive )
+                if (index == uiModel.currentButtonIndex) {
+                    view.bindDrawerButton(uiModel.selectedButton, viewModel, isSelected = true)
+                } else {
+                    view.bindDrawerButton(it, viewModel)
+                }
             }
         }
     }
@@ -128,15 +130,29 @@
     private fun View.bindDrawerButton(
         buttonViewModel: RingerButtonViewModel,
         viewModel: VolumeDialogRingerDrawerViewModel,
+        isSelected: Boolean = false,
     ) {
         with(requireViewById<ImageButton>(R.id.volume_drawer_button)) {
             setImageResource(buttonViewModel.imageResId)
             contentDescription = context.getString(buttonViewModel.contentDescriptionResId)
-            setOnClickListener { viewModel.onRingerButtonClicked(buttonViewModel.ringerMode) }
+            if (isSelected) {
+                setBackgroundResource(R.drawable.volume_drawer_selection_bg)
+                setColorFilter(
+                    Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnPrimary)
+                )
+            } else {
+                setBackgroundResource(R.drawable.volume_ringer_item_bg)
+                setColorFilter(
+                    Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnSurface)
+                )
+            }
+            setOnClickListener {
+                viewModel.onRingerButtonClicked(buttonViewModel.ringerMode, isSelected)
+            }
         }
     }
 
-    private fun ViewGroup.ensureChildCount(@LayoutRes viewLayoutId: Int, count: Int) {
+    private fun MotionLayout.ensureChildCount(@LayoutRes viewLayoutId: Int, count: Int) {
         val childCountDelta = childCount - count
         when {
             childCountDelta > 0 -> {
@@ -144,21 +160,107 @@
             }
             childCountDelta < 0 -> {
                 val inflater = LayoutInflater.from(context)
-                repeat(abs(childCountDelta)) { inflater.inflate(viewLayoutId, this, true) }
+                repeat(-childCountDelta) {
+                    inflater.inflate(viewLayoutId, this, true)
+                    getChildAt(childCount - 1).id = View.generateViewId()
+                }
+                cloneConstraintSet(R.id.volume_dialog_ringer_drawer_open)
+                    .adjustOpenConstraintsForDrawer(this)
             }
         }
     }
 
-    private fun bindSelectedButton(
-        viewModel: VolumeDialogRingerDrawerViewModel,
-        uiModel: RingerViewModel,
-        selectedButtonView: ImageButton,
-    ) {
-        with(uiModel) {
-            selectedButtonView.setImageResource(selectedButton.imageResId)
-            selectedButtonView.setOnClickListener {
-                viewModel.onRingerButtonClicked(selectedButton.ringerMode)
+    private fun MotionLayout.closeDrawer(selectedIndex: Int) {
+        cloneConstraintSet(R.id.volume_dialog_ringer_drawer_close)
+            .adjustClosedConstraintsForDrawer(selectedIndex, this)
+        transitionToStart()
+    }
+
+    private fun ConstraintSet.adjustOpenConstraintsForDrawer(motionLayout: MotionLayout) {
+        motionLayout.children.forEachIndexed { index, button ->
+            setButtonPositionConstraints(motionLayout, index, button)
+            setAlpha(button.id, 1.0F)
+            constrainWidth(
+                button.id,
+                motionLayout.context.resources.getDimensionPixelSize(
+                    R.dimen.volume_dialog_ringer_drawer_button_size
+                ),
+            )
+            constrainHeight(
+                button.id,
+                motionLayout.context.resources.getDimensionPixelSize(
+                    R.dimen.volume_dialog_ringer_drawer_button_size
+                ),
+            )
+            if (index != motionLayout.childCount - 1) {
+                setMargin(
+                    button.id,
+                    ConstraintSet.BOTTOM,
+                    motionLayout.context.resources.getDimensionPixelSize(
+                        R.dimen.volume_dialog_components_spacing
+                    ),
+                )
             }
         }
+        motionLayout.updateState(R.id.volume_dialog_ringer_drawer_open, this)
+    }
+
+    private fun ConstraintSet.adjustClosedConstraintsForDrawer(
+        selectedIndex: Int,
+        motionLayout: MotionLayout,
+    ) {
+        motionLayout.children.forEachIndexed { index, button ->
+            setButtonPositionConstraints(motionLayout, index, button)
+            constrainWidth(
+                button.id,
+                motionLayout.context.resources.getDimensionPixelSize(
+                    R.dimen.volume_dialog_ringer_drawer_button_size
+                ),
+            )
+            if (selectedIndex != motionLayout.childCount - index - 1) {
+                setAlpha(button.id, 0.0F)
+                constrainHeight(button.id, 0)
+                setMargin(button.id, ConstraintSet.BOTTOM, 0)
+            } else {
+                setAlpha(button.id, 1.0F)
+                constrainHeight(
+                    button.id,
+                    motionLayout.context.resources.getDimensionPixelSize(
+                        R.dimen.volume_dialog_ringer_drawer_button_size
+                    ),
+                )
+            }
+        }
+        motionLayout.updateState(R.id.volume_dialog_ringer_drawer_close, this)
+    }
+
+    private fun ConstraintSet.setButtonPositionConstraints(
+        motionLayout: MotionLayout,
+        index: Int,
+        button: View,
+    ) {
+        if (motionLayout.getChildAt(index - 1) == null) {
+            connect(button.id, ConstraintSet.TOP, motionLayout.id, ConstraintSet.TOP)
+        } else {
+            connect(
+                button.id,
+                ConstraintSet.TOP,
+                motionLayout.getChildAt(index - 1).id,
+                ConstraintSet.BOTTOM,
+            )
+        }
+
+        if (motionLayout.getChildAt(index + 1) == null) {
+            connect(button.id, ConstraintSet.BOTTOM, motionLayout.id, ConstraintSet.BOTTOM)
+        } else {
+            connect(
+                button.id,
+                ConstraintSet.BOTTOM,
+                motionLayout.getChildAt(index + 1).id,
+                ConstraintSet.TOP,
+            )
+        }
+        connect(button.id, ConstraintSet.START, motionLayout.id, ConstraintSet.START)
+        connect(button.id, ConstraintSet.END, motionLayout.id, ConstraintSet.END)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
index e040638..624dcc7 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
@@ -84,8 +84,8 @@
             .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
             .build()
 
-    fun onRingerButtonClicked(ringerMode: RingerMode) {
-        if (drawerState.value is RingerDrawerState.Open) {
+    fun onRingerButtonClicked(ringerMode: RingerMode, isSelectedButton: Boolean = false) {
+        if (drawerState.value is RingerDrawerState.Open && !isSelectedButton) {
             Events.writeEvent(Events.EVENT_RINGER_TOGGLE, ringerMode.value)
             provideTouchFeedback(ringerMode)
             maybeShowToast(ringerMode)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
index bf13ceb..4bc5f23 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
@@ -45,6 +45,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.provider.Settings;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
@@ -56,6 +58,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.logging.CarrierTextManagerLogger;
+import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
@@ -200,6 +203,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testAirplaneMode() {
         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
         reset(mCarrierTextCallback);
@@ -220,8 +224,32 @@
         assertEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testAirplaneMode_flagEnabled() {
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(0)).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        mCarrierTextManager.updateCarrierText();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+        assertEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
+    }
+
     /** regression test for b/281706473, caused by sending NULL plmn / spn to the logger */
     @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testAirplaneMode_noSim_nullPlmn_nullSpn_doesNotCrash() {
         // GIVEN - sticy broadcast that returns a null PLMN and null SPN
         Intent stickyIntent = new Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
@@ -263,7 +291,52 @@
         // No assert, this test should not crash
     }
 
+    /** regression test for b/281706473, caused by sending NULL plmn / spn to the logger */
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testAirplaneMode_noSim_nullPlmn_nullSpn_doesNotCrash_flagEnabled() {
+        // GIVEN - sticy broadcast that returns a null PLMN and null SPN
+        Intent stickyIntent = new Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
+        stickyIntent.putExtra(TelephonyManager.EXTRA_SHOW_PLMN, true);
+        stickyIntent.removeExtra(TelephonyManager.EXTRA_PLMN);
+        stickyIntent.putExtra(TelephonyManager.EXTRA_SHOW_SPN, true);
+        stickyIntent.removeExtra(TelephonyManager.EXTRA_SPN);
+
+        mCarrierTextManager = new CarrierTextManager.Builder(
+                getContextSpyForStickyBroadcast(stickyIntent),
+                mContext.getResources(),
+                mWifiRepository,
+                mSatelliteViewModel,
+                mJavaAdapter,
+                mTelephonyManager,
+                mTelephonyListenerManager,
+                mWakefulnessLifecycle,
+                mMainExecutor,
+                mBgExecutor,
+                mKeyguardUpdateMonitor,
+                mLogger
+        )
+                .setShowAirplaneMode(true)
+                .setShowMissingSim(true)
+                .build();
+
+        // GIVEN - airplane mode is off (causing CTM to fetch the sticky broadcast)
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(0))
+                .thenReturn(TelephonyManager.SIM_STATE_NOT_READY);
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        // WHEN CTM fetches the broadcast and attempts to log the result, no crash results
+        mCarrierTextManager.updateCarrierText();
+
+        // No assert, this test should not crash
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCardIOError() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -299,6 +372,44 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCardIOError_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(0)).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(1)).thenReturn(
+                TelephonyManager.SIM_STATE_CARD_IO_ERROR);
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        mCarrierTextManager.mCallback.onSimStateChanged(3, 1,
+                TelephonyManager.SIM_STATE_CARD_IO_ERROR);
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+        assertEquals("TEST_CARRIER" + SEPARATOR + INVALID_CARD_TEXT, captor.getValue().carrierText);
+        // There's only one subscription in the list
+        assertEquals(1, captor.getValue().listOfCarriers.length);
+        assertEquals(TEST_CARRIER, captor.getValue().listOfCarriers[0]);
+
+        // Now it becomes single SIM active mode.
+        reset(mCarrierTextCallback);
+        when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
+        // Update carrier text. It should ignore error state of subId 3 in inactive slotId.
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+        assertEquals("TEST_CARRIER", captor.getValue().carrierText);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testWrongSlots() {
         reset(mCarrierTextCallback);
         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(
@@ -313,6 +424,22 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testWrongSlots_flagEnabled() {
+        reset(mCarrierTextCallback);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(
+                new ArrayList<>());
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_CARD_IO_ERROR);
+        // This should not produce an out of bounds error, even though there are no subscriptions
+        mCarrierTextManager.mCallback.onSimStateChanged(0, -3,
+                TelephonyManager.SIM_STATE_CARD_IO_ERROR);
+        mCarrierTextManager.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY);
+        verify(mCarrierTextCallback, never()).updateCarrierInfo(any());
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testMoreSlotsThanSubs() {
         reset(mCarrierTextCallback);
         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(
@@ -335,6 +462,29 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testMoreSlotsThanSubs_flagEnabled() {
+        reset(mCarrierTextCallback);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(
+                new ArrayList<>());
+
+        // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
+        // same answer as KeyguardUpdateMonitor. Remove when this is addressed
+        when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList()).thenReturn(
+                new ArrayList<>());
+
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_CARD_IO_ERROR);
+        // This should not produce an out of bounds error, even though there are no subscriptions
+        mCarrierTextManager.mCallback.onSimStateChanged(0, 1,
+                TelephonyManager.SIM_STATE_CARD_IO_ERROR);
+
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(
+                any(CarrierTextManager.CarrierTextCallbackInfo.class));
+    }
+
+    @Test
     public void testCallback() {
         reset(mCarrierTextCallback);
         mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
@@ -360,6 +510,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCreateInfo_OneValidSubscription() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -385,6 +536,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCreateInfo_OneValidSubscription_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
+        assertEquals(1, info.listOfCarriers.length);
+        assertEquals(TEST_CARRIER, info.listOfCarriers[0]);
+        assertEquals(1, info.subscriptionIds.length);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCreateInfo_OneValidSubscriptionWithRoaming() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -410,6 +588,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCreateInfo_OneValidSubscriptionWithRoaming_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION_ROAMING);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
+        assertEquals(1, info.listOfCarriers.length);
+        assertTrue(info.listOfCarriers[0].toString().contains(TEST_CARRIER));
+        assertEquals(1, info.subscriptionIds.length);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCarrierText_noTextOnReadySimWhenNull() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -434,6 +639,32 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCarrierText_noTextOnReadySimWhenNull_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION_NULL);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        assertTrue("Carrier text should be empty, instead it's " + captor.getValue().carrierText,
+                TextUtils.isEmpty(captor.getValue().carrierText));
+        assertFalse("No SIM should be available", captor.getValue().anySimReady);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCarrierText_noTextOnReadySimWhenNull_airplaneMode_wifiOn() {
         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
         reset(mCarrierTextCallback);
@@ -472,6 +703,46 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCarrierText_noTextOnReadySimWhenNull_airplaneMode_wifiOn_flagEnabled() {
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION_NULL);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+
+        assertFalse(mWifiRepository.isWifiConnectedWithValidSsid());
+        mWifiRepository.setWifiNetwork(
+                WifiNetworkModel.Active.Companion.of(
+                        /* isValidated= */ false,
+                        /* level= */ 0,
+                        /* ssid= */ "",
+                        /* hotspotDeviceType= */ WifiNetworkModel.HotspotDeviceType.NONE));
+        assertTrue(mWifiRepository.isWifiConnectedWithValidSsid());
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+        ServiceState ss = mock(ServiceState.class);
+        when(ss.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+        mKeyguardUpdateMonitor.mServiceStates.put(TEST_SUBSCRIPTION_NULL.getSubscriptionId(), ss);
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        assertFalse("No SIM should be available", captor.getValue().anySimReady);
+        // There's no airplane mode if at least one SIM is State.READY and there's wifi
+        assertFalse("Device should not be in airplane mode", captor.getValue().airplaneMode);
+        assertNotEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void carrierText_satelliteTextNull_isSatelliteFalse_textNotUsed() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -497,6 +768,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void carrierText_satelliteTextNull_isSatelliteFalse_textNotUsed_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        // WHEN the satellite text is null
+        mSatelliteViewModel.getCarrierText().setValue(null);
+        mTestScope.getTestScheduler().runCurrent();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+
+        // THEN satellite mode is false and the default subscription carrier text is used
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+        assertThat(captor.getValue().isInSatelliteMode).isFalse();
+        assertThat(captor.getValue().carrierText).isEqualTo(TEST_CARRIER);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void carrierText_hasSatelliteText_isSatelliteTrue_textUsed() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -522,6 +820,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void carrierText_hasSatelliteText_isSatelliteTrue_textUsed_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        // WHEN the satellite text is non-null
+        mSatelliteViewModel.getCarrierText().setValue("Satellite Test Text");
+        mTestScope.getTestScheduler().runCurrent();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+
+        // THEN satellite mode is true and the satellite text is used
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+        assertThat(captor.getValue().isInSatelliteMode).isTrue();
+        assertThat(captor.getValue().carrierText).isEqualTo("Satellite Test Text");
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void carrierText_satelliteTextUpdates_autoTriggersCallback() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -559,6 +884,45 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void carrierText_satelliteTextUpdates_autoTriggersCallback_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        // WHEN the satellite text is set
+        mSatelliteViewModel.getCarrierText().setValue("Test satellite text");
+        mTestScope.getTestScheduler().runCurrent();
+
+        // THEN we should automatically re-trigger #updateCarrierText and get callback info
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+        // AND use the satellite text as the carrier text
+        assertThat(captor.getValue().isInSatelliteMode).isTrue();
+        assertThat(captor.getValue().carrierText).isEqualTo("Test satellite text");
+
+        // WHEN the satellite text is reset to null
+        reset(mCarrierTextCallback);
+        mSatelliteViewModel.getCarrierText().setValue(null);
+        mTestScope.getTestScheduler().runCurrent();
+
+        // THEN we should automatically re-trigger #updateCarrierText and get callback info
+        // that doesn't include the satellite info
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+        assertThat(captor.getValue().isInSatelliteMode).isFalse();
+        assertThat(captor.getValue().carrierText).isEqualTo(TEST_CARRIER);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void carrierText_updatedWhileNotListening_getsNewValueWhenListening() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -602,6 +966,50 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void carrierText_updatedWhileNotListening_getsNewValueWhenListening_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        mSatelliteViewModel.getCarrierText().setValue("Old satellite text");
+        mTestScope.getTestScheduler().runCurrent();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+        assertThat(captor.getValue().carrierText).isEqualTo("Old satellite text");
+
+        // WHEN we stop listening
+        reset(mCarrierTextCallback);
+        mCarrierTextManager.setListening(null);
+
+        // AND the satellite text updates
+        mSatelliteViewModel.getCarrierText().setValue("New satellite text");
+
+        // THEN we don't get new callback info because we aren't listening
+        verify(mCarrierTextCallback, never()).updateCarrierInfo(any());
+
+        // WHEN we start listening again
+        reset(mCarrierTextCallback);
+        mCarrierTextManager.setListening(mCarrierTextCallback);
+
+        // THEN we should automatically re-trigger #updateCarrierText and get callback info
+        // that includes the new satellite state and text
+        mTestScope.getTestScheduler().runCurrent();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+        assertThat(captor.getValue().isInSatelliteMode).isTrue();
+        assertThat(captor.getValue().carrierText).isEqualTo("New satellite text");
+    }
+
+    @Test
     public void testCreateInfo_noSubscriptions() {
         reset(mCarrierTextCallback);
         when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(
@@ -622,6 +1030,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCarrierText_oneValidSubscription() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -644,6 +1053,30 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCarrierText_oneValidSubscription_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        assertThat(captor.getValue().carrierText).isEqualTo(TEST_CARRIER);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCarrierText_twoValidSubscriptions() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -668,6 +1101,32 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCarrierText_twoValidSubscriptions_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt())).thenReturn(
+                TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
+                captor.getValue().carrierText);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCarrierText_oneDisabledSub() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -693,6 +1152,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCarrierText_oneDisabledSub_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt()))
+                .thenReturn(TelephonyManager.SIM_STATE_READY)
+                .thenReturn(TelephonyManager.SIM_STATE_NOT_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        assertEquals(TEST_CARRIER,
+                captor.getValue().carrierText);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCarrierText_firstDisabledSub() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -718,6 +1204,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCarrierText_firstDisabledSub_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt()))
+                .thenReturn(TelephonyManager.SIM_STATE_NOT_READY)
+                .thenReturn(TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        assertEquals(TEST_CARRIER,
+                captor.getValue().carrierText);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
     public void testCarrierText_threeSubsMiddleDisabled() {
         reset(mCarrierTextCallback);
         List<SubscriptionInfo> list = new ArrayList<>();
@@ -744,6 +1257,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testCarrierText_threeSubsMiddleDisabled_flagEnabled() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        list.add(TEST_SUBSCRIPTION);
+        list.add(TEST_SUBSCRIPTION);
+        when(mKeyguardUpdateMonitor.getSimStateForSlotId(anyInt()))
+                .thenReturn(TelephonyManager.SIM_STATE_READY)
+                .thenReturn(TelephonyManager.SIM_STATE_NOT_READY)
+                .thenReturn(TelephonyManager.SIM_STATE_READY);
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextManager.CarrierTextCallbackInfo.class);
+
+        mCarrierTextManager.updateCarrierText();
+        FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
+                captor.getValue().carrierText);
+    }
+
+    @Test
     public void testGetStatusForIccState() {
         when(mKeyguardUpdateMonitor.isDeviceProvisioned()).thenReturn(false);
         assertEquals(CarrierTextManager.StatusMode.SimMissingLocked,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index a39ca5d..839a2bd 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -103,6 +103,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.FlagsParameterization;
 import android.service.dreams.IDreamManager;
@@ -200,8 +201,9 @@
     private static final String TEST_CARRIER_2 = "TEST_CARRIER_2";
     private static final int TEST_CARRIER_ID = 1;
     private static final String TEST_GROUP_UUID = "59b5c870-fc4c-47a4-a99e-9db826b48b24";
-    private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(1, "", 0,
-            TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "",
+    private static final int TEST_SLOT_ID = 3;
+    private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(1, "",
+            TEST_SLOT_ID, TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "",
             DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", false, TEST_GROUP_UUID,
             TEST_CARRIER_ID, 0);
     private static final SubscriptionInfo TEST_SUBSCRIPTION_2 = new SubscriptionInfo(2, "", 0,
@@ -483,7 +485,8 @@
     }
 
     @Test
-    public void testSimStateInitialized() {
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testSimStateInitialized_flagDisabled() {
         cleanupKeyguardUpdateMonitor();
         final int subId = 3;
         final int state = TelephonyManager.SIM_STATE_ABSENT;
@@ -500,6 +503,24 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testSimStateInitialized_flagEnabled() {
+        cleanupKeyguardUpdateMonitor();
+        final int state = TelephonyManager.SIM_STATE_ABSENT;
+        final int slotId = 0;
+        final int subId = 3;
+        when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
+        when(mTelephonyManager.getSimState(anyInt())).thenReturn(state);
+        when(mSubscriptionManager.getSubscriptionIds(anyInt())).thenReturn(new int[]{subId});
+
+        KeyguardUpdateMonitor testKUM = new TestableKeyguardUpdateMonitor(mContext);
+
+        mTestableLooper.processAllMessages();
+
+        assertThat(testKUM.getSimStateForSlotId(slotId)).isEqualTo(state);
+    }
+
+    @Test
     public void testIgnoresSimStateCallback_rebroadcast() {
         Intent intent = defaultSimStateChangedIntent();
 
@@ -1240,7 +1261,8 @@
     }
 
     @Test
-    public void testActiveSubscriptionBecomesInactive() {
+    @DisableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testActiveSubscriptionBecomesInactive_flagDisabled() {
         List<SubscriptionInfo> list = new ArrayList<>();
         list.add(TEST_SUBSCRIPTION);
         when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList()).thenReturn(list);
@@ -1263,6 +1285,28 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SIM_PIN_USE_SLOT_ID)
+    public void testActiveSubscriptionBecomesInactive_flagEnabled() {
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION);
+        when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList()).thenReturn(list);
+        mKeyguardUpdateMonitor.mPhoneStateListener.onActiveDataSubscriptionIdChanged(
+                TEST_SUBSCRIPTION.getSubscriptionId());
+        mTestableLooper.processAllMessages();
+        assertThat(mKeyguardUpdateMonitor.mSimDatasBySlotId.get(TEST_SLOT_ID))
+                .isNotNull();
+
+        when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList())
+                .thenReturn(new ArrayList<>());
+        mKeyguardUpdateMonitor.mPhoneStateListener.onActiveDataSubscriptionIdChanged(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        mTestableLooper.processAllMessages();
+
+        assertThat(mKeyguardUpdateMonitor.mSimDatasBySlotId.get(TEST_SLOT_ID))
+                .isNull();
+    }
+
+    @Test
     public void testActiveSubscriptionList_filtersProvisioningNetworks() {
         List<SubscriptionInfo> list = new ArrayList<>();
         list.add(TEST_SUBSCRIPTION_PROVISIONING);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
similarity index 96%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index f41d5c8..8552e48 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -63,8 +63,6 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
 import android.provider.Settings;
 import android.testing.TestableLooper;
 import android.testing.TestableResources;
@@ -90,7 +88,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 
-import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.AnimatorTestRule;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
@@ -612,46 +609,6 @@
                 .isEqualTo(expectedRatio);
     }
 
-    @DisableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
-    @Test
-    public void onScreenSizeAndDensityChanged_enabled_restoreSavedMagnifierWindow() {
-        int newSmallestScreenWidthDp =
-                mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
-        int windowFrameSize = mResources.getDimensionPixelSize(
-                com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
-        Size preferredWindowSize = new Size(windowFrameSize, windowFrameSize);
-        mSharedPreferences
-                .edit()
-                .putString(String.valueOf(newSmallestScreenWidthDp),
-                        preferredWindowSize.toString())
-                .commit();
-        mInstrumentation.runOnMainSync(() -> {
-            mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
-                    Float.NaN);
-        });
-
-        // Screen density and size change
-        mContext.getResources().getConfiguration().smallestScreenWidthDp = newSmallestScreenWidthDp;
-        final Rect testWindowBounds = new Rect(
-                mWindowManager.getCurrentWindowMetrics().getBounds());
-        testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
-                testWindowBounds.right + 100, testWindowBounds.bottom + 100);
-        mWindowManager.setWindowBounds(testWindowBounds);
-        mInstrumentation.runOnMainSync(() -> {
-            mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
-        });
-
-        // wait for rect update
-        waitForIdleSync();
-        ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
-        final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
-                R.dimen.magnification_mirror_surface_margin);
-        // The width and height of the view include the magnification frame and the margins.
-        assertThat(params.width).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
-        assertThat(params.height).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
-    }
-
-    @EnableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
     @Test
     public void onScreenSizeAndDensityChanged_enabled_restoreSavedMagnifierIndexAndWindow() {
         int newSmallestScreenWidthDp =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
index 425aad2..4aaa82e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
@@ -404,7 +404,7 @@
     @Test
     fun creatingRunnerWithLazyInitializationThrows_whenTheFlagsAreDisabled() {
         assertThrows(IllegalStateException::class.java) {
-            activityTransitionAnimator.createRunner(controller, initializeLazily = true)
+            activityTransitionAnimator.createRunner(controller, longLived = true)
         }
     }
 
@@ -414,7 +414,7 @@
     )
     @Test
     fun runnerCreatesDelegateLazily_whenPostingTimeouts() {
-        val runner = activityTransitionAnimator.createRunner(controller, initializeLazily = true)
+        val runner = activityTransitionAnimator.createRunner(controller, longLived = true)
         assertNull(runner.delegate)
         runner.postTimeouts()
         assertNotNull(runner.delegate)
@@ -426,7 +426,7 @@
     )
     @Test
     fun runnerCreatesDelegateLazily_onAnimationStart() {
-        val runner = activityTransitionAnimator.createRunner(controller, initializeLazily = true)
+        val runner = activityTransitionAnimator.createRunner(controller, longLived = true)
         assertNull(runner.delegate)
 
         // The delegate is cleaned up after execution (which happens in another thread), so what we
@@ -458,7 +458,7 @@
     )
     @Test
     fun runnerCreatesDelegateLazily_onAnimationTakeover() {
-        val runner = activityTransitionAnimator.createRunner(controller, initializeLazily = true)
+        val runner = activityTransitionAnimator.createRunner(controller, longLived = true)
         assertNull(runner.delegate)
 
         // The delegate is cleaned up after execution (which happens in another thread), so what we
@@ -489,7 +489,7 @@
     )
     @Test
     fun animationTakeoverThrows_whenTheFlagsAreDisabled() {
-        val runner = activityTransitionAnimator.createRunner(controller, initializeLazily = false)
+        val runner = activityTransitionAnimator.createRunner(controller, longLived = false)
         assertThrows(IllegalStateException::class.java) {
             runner.takeOverAnimation(
                 arrayOf(fakeWindow()),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
index ec42b7f..97abba7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
@@ -31,8 +31,8 @@
 @SmallTest
 class FontInterpolatorTest : SysuiTestCase() {
 
-    private val sFont = TextRunShaper.shapeTextRun("A", 0, 1, 0, 1, 0f, 0f, false, Paint())
-            .getFont(0)
+    private val sFont =
+        TextRunShaper.shapeTextRun("A", 0, 1, 0, 1, 0f, 0f, false, Paint()).getFont(0)
 
     private fun assertSameAxes(expect: Font, actual: Font) {
         val expectAxes = expect.axes?.also { it.sortBy { axis -> axis.tag } }
@@ -42,21 +42,20 @@
 
     private fun assertSameAxes(expectVarSettings: String, actual: Font) {
 
-        val expectAxes = FontVariationAxis.fromFontVariationSettings(expectVarSettings)?.also {
-            it.sortBy { axis -> axis.tag }
-        }
+        val expectAxes =
+            FontVariationAxis.fromFontVariationSettings(expectVarSettings)?.also {
+                it.sortBy { axis -> axis.tag }
+            }
         val actualAxes = actual.axes?.also { it.sortBy { axis -> axis.tag } }
         assertThat(actualAxes).isEqualTo(expectAxes)
     }
 
     @Test
     fun textInterpolation() {
-        val startFont = Font.Builder(sFont)
-                .setFontVariationSettings("'wght' 100, 'ital' 0, 'GRAD' 200")
-                .build()
-        val endFont = Font.Builder(sFont)
-                .setFontVariationSettings("'wght' 900, 'ital' 1, 'GRAD' 700")
-                .build()
+        val startFont =
+            Font.Builder(sFont).setFontVariationSettings("'wght' 100, 'ital' 0, 'GRAD' 200").build()
+        val endFont =
+            Font.Builder(sFont).setFontVariationSettings("'wght' 900, 'ital' 1, 'GRAD' 700").build()
 
         val interp = FontInterpolator()
         assertSameAxes(startFont, interp.lerp(startFont, endFont, 0f))
@@ -66,12 +65,8 @@
 
     @Test
     fun textInterpolation_DefaultValue() {
-        val startFont = Font.Builder(sFont)
-                .setFontVariationSettings("'wght' 100")
-                .build()
-        val endFont = Font.Builder(sFont)
-                .setFontVariationSettings("'ital' 1")
-                .build()
+        val startFont = Font.Builder(sFont).setFontVariationSettings("'wght' 100").build()
+        val endFont = Font.Builder(sFont).setFontVariationSettings("'ital' 1").build()
 
         val interp = FontInterpolator()
         assertSameAxes("'wght' 250, 'ital' 0.5", interp.lerp(startFont, endFont, 0.5f))
@@ -79,12 +74,8 @@
 
     @Test
     fun testInterpCache() {
-        val startFont = Font.Builder(sFont)
-                .setFontVariationSettings("'wght' 100")
-                .build()
-        val endFont = Font.Builder(sFont)
-                .setFontVariationSettings("'ital' 1")
-                .build()
+        val startFont = Font.Builder(sFont).setFontVariationSettings("'wght' 100").build()
+        val endFont = Font.Builder(sFont).setFontVariationSettings("'ital' 1").build()
 
         val interp = FontInterpolator()
         val resultFont = interp.lerp(startFont, endFont, 0.5f)
@@ -94,12 +85,8 @@
 
     @Test
     fun testAxesCache() {
-        val startFont = Font.Builder(sFont)
-                .setFontVariationSettings("'wght' 100")
-                .build()
-        val endFont = Font.Builder(sFont)
-                .setFontVariationSettings("'ital' 1")
-                .build()
+        val startFont = Font.Builder(sFont).setFontVariationSettings("'wght' 100").build()
+        val endFont = Font.Builder(sFont).setFontVariationSettings("'ital' 1").build()
 
         val interp = FontInterpolator()
         val resultFont = interp.lerp(startFont, endFont, 0.5f)
@@ -111,20 +98,12 @@
     fun testCacheMaxSize() {
         val interp = FontInterpolator()
 
-        val startFont = Font.Builder(sFont)
-                .setFontVariationSettings("'wght' 100")
-                .build()
-        val endFont = Font.Builder(sFont)
-                .setFontVariationSettings("'wght' 1")
-                .build()
+        val startFont = Font.Builder(sFont).setFontVariationSettings("'wght' 100").build()
+        val endFont = Font.Builder(sFont).setFontVariationSettings("'wght' 1").build()
         val resultFont = interp.lerp(startFont, endFont, 0.5f)
-        for (i in 0..interp.cacheMaxEntries + 1) {
-            val f1 = Font.Builder(sFont)
-                    .setFontVariationSettings("'wght' ${i * 100}")
-                    .build()
-            val f2 = Font.Builder(sFont)
-                    .setFontVariationSettings("'wght' $i")
-                    .build()
+        for (i in 0..(interp.fontCache as FontCacheImpl).cacheMaxEntries + 1) {
+            val f1 = Font.Builder(sFont).setFontVariationSettings("'wght' ${i * 100}").build()
+            val f2 = Font.Builder(sFont).setFontVariationSettings("'wght' $i").build()
             interp.lerp(f1, f2, 0.5f)
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
index 6ba1715..dcf38800 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
@@ -42,6 +42,8 @@
 @SmallTest
 class TextAnimatorTest : SysuiTestCase() {
 
+    private val typeface = Typeface.createFromFile("/system/fonts/Roboto-Regular.ttf")
+
     private fun makeLayout(text: String, paint: TextPaint): Layout {
         val width = ceil(Layout.getDesiredWidth(text, 0, text.length, paint)).toInt()
         return StaticLayout.Builder.obtain(text, 0, text.length, paint, width).build()
@@ -56,7 +58,7 @@
         `when`(textInterpolator.targetPaint).thenReturn(paint)
 
         val textAnimator =
-            TextAnimator(layout, null, {}).apply {
+            TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
                 this.textInterpolator = textInterpolator
                 this.animator = valueAnimator
             }
@@ -86,7 +88,7 @@
         `when`(textInterpolator.targetPaint).thenReturn(paint)
 
         val textAnimator =
-            TextAnimator(layout, null, {}).apply {
+            TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
                 this.textInterpolator = textInterpolator
                 this.animator = valueAnimator
             }
@@ -114,7 +116,7 @@
         val animationEndCallback = mock(Runnable::class.java)
 
         val textAnimator =
-            TextAnimator(layout, null, {}).apply {
+            TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
                 this.textInterpolator = textInterpolator
                 this.animator = valueAnimator
             }
@@ -122,7 +124,7 @@
         textAnimator.setTextStyle(
             weight = 400,
             animate = true,
-            onAnimationEnd = animationEndCallback
+            onAnimationEnd = animationEndCallback,
         )
 
         // Verify animationEnd callback has been added.
@@ -140,14 +142,11 @@
         val layout = makeLayout("Hello, World", PAINT)
         val valueAnimator = mock(ValueAnimator::class.java)
         val textInterpolator = mock(TextInterpolator::class.java)
-        val paint =
-            TextPaint().apply {
-                typeface = Typeface.createFromFile("/system/fonts/Roboto-Regular.ttf")
-            }
+        val paint = TextPaint().apply { this.typeface = typeface }
         `when`(textInterpolator.targetPaint).thenReturn(paint)
 
         val textAnimator =
-            TextAnimator(layout, null, {}).apply {
+            TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
                 this.textInterpolator = textInterpolator
                 this.animator = valueAnimator
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
index cca5f35..c6fbe3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
@@ -31,11 +31,11 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
+import java.io.File
+import kotlin.math.ceil
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import java.io.File
-import kotlin.math.ceil
 
 private const val TEXT = "Hello, World."
 private const val BIDI_TEXT = "abc\u05D0\u05D1\u05D2"
@@ -47,20 +47,23 @@
 private val VF_FONT = Font.Builder(File("/system/fonts/Roboto-Regular.ttf")).build()
 
 private fun Font.toTypeface() =
-        Typeface.CustomFallbackBuilder(FontFamily.Builder(this).build()).build()
+    Typeface.CustomFallbackBuilder(FontFamily.Builder(this).build()).build()
 
-internal val PAINT = TextPaint().apply {
-    typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 400").build().toTypeface()
-    textSize = 32f
-}
+internal val PAINT =
+    TextPaint().apply {
+        typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 400").build().toTypeface()
+        textSize = 32f
+    }
 
-private val START_PAINT = TextPaint(PAINT).apply {
-    typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 400").build().toTypeface()
-}
+private val START_PAINT =
+    TextPaint(PAINT).apply {
+        typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 400").build().toTypeface()
+    }
 
-private val END_PAINT = TextPaint(PAINT).apply {
-    typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 700").build().toTypeface()
-}
+private val END_PAINT =
+    TextPaint(PAINT).apply {
+        typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 700").build().toTypeface()
+    }
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
@@ -70,16 +73,17 @@
     private fun makeLayout(
         text: String,
         paint: TextPaint,
-        dir: TextDirectionHeuristic = TextDirectionHeuristics.LTR
+        dir: TextDirectionHeuristic = TextDirectionHeuristics.LTR,
     ): Layout {
         val width = ceil(Layout.getDesiredWidth(text, 0, text.length, paint)).toInt()
         return StaticLayout.Builder.obtain(text, 0, text.length, paint, width)
-                .setTextDirection(dir).build()
+            .setTextDirection(dir)
+            .build()
     }
 
     @Before
     fun setup() {
-        typefaceCache = TypefaceVariantCacheImpl(PAINT.typeface)
+        typefaceCache = TypefaceVariantCacheImpl(PAINT.typeface, 10)
     }
 
     @Test
@@ -135,10 +139,10 @@
         // end state.
         interp.progress = 0.5f
         val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
-        assertThat(actual.sameAs(makeLayout(TEXT, START_PAINT)
-            .toBitmap(BMP_WIDTH, BMP_HEIGHT))).isFalse()
-        assertThat(actual.sameAs(makeLayout(TEXT, END_PAINT)
-            .toBitmap(BMP_WIDTH, BMP_HEIGHT))).isFalse()
+        assertThat(actual.sameAs(makeLayout(TEXT, START_PAINT).toBitmap(BMP_WIDTH, BMP_HEIGHT)))
+            .isFalse()
+        assertThat(actual.sameAs(makeLayout(TEXT, END_PAINT).toBitmap(BMP_WIDTH, BMP_HEIGHT)))
+            .isFalse()
     }
 
     @Test
@@ -177,7 +181,8 @@
         // Just after created TextInterpolator, it should have 0 progress.
         assertThat(interp.progress).isEqualTo(0f)
         val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
-        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.LTR)
+        val expected =
+            makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.LTR)
                 .toBitmap(BMP_WIDTH, BMP_HEIGHT)
 
         assertThat(expected.sameAs(actual)).isTrue()
@@ -197,7 +202,8 @@
         // Just after created TextInterpolator, it should have 0 progress.
         assertThat(interp.progress).isEqualTo(0f)
         val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
-        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+        val expected =
+            makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
                 .toBitmap(BMP_WIDTH, BMP_HEIGHT)
 
         assertThat(expected.sameAs(actual)).isTrue()
@@ -207,10 +213,8 @@
     fun testGlyphCallback_Empty() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout, typefaceCache).apply {
-            glyphFilter = { glyph, progress ->
-            }
-        }
+        val interp =
+            TextInterpolator(layout, typefaceCache).apply { glyphFilter = { glyph, progress -> } }
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -219,7 +223,8 @@
 
         // Just after created TextInterpolator, it should have 0 progress.
         val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
-        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+        val expected =
+            makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
                 .toBitmap(BMP_WIDTH, BMP_HEIGHT)
 
         assertThat(expected.sameAs(actual)).isTrue()
@@ -229,11 +234,10 @@
     fun testGlyphCallback_Xcoordinate() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout, typefaceCache).apply {
-            glyphFilter = { glyph, progress ->
-                glyph.x += 30f
+        val interp =
+            TextInterpolator(layout, typefaceCache).apply {
+                glyphFilter = { glyph, progress -> glyph.x += 30f }
             }
-        }
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -242,7 +246,8 @@
 
         // Just after created TextInterpolator, it should have 0 progress.
         val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
-        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+        val expected =
+            makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
                 .toBitmap(BMP_WIDTH, BMP_HEIGHT)
 
         // The glyph position was modified by callback, so the bitmap should not be the same.
@@ -254,11 +259,10 @@
     fun testGlyphCallback_Ycoordinate() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout, typefaceCache).apply {
-            glyphFilter = { glyph, progress ->
-                glyph.y += 30f
+        val interp =
+            TextInterpolator(layout, typefaceCache).apply {
+                glyphFilter = { glyph, progress -> glyph.y += 30f }
             }
-        }
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -267,7 +271,8 @@
 
         // Just after created TextInterpolator, it should have 0 progress.
         val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
-        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+        val expected =
+            makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
                 .toBitmap(BMP_WIDTH, BMP_HEIGHT)
 
         // The glyph position was modified by callback, so the bitmap should not be the same.
@@ -279,11 +284,10 @@
     fun testGlyphCallback_TextSize() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout, typefaceCache).apply {
-            glyphFilter = { glyph, progress ->
-                glyph.textSize += 10f
+        val interp =
+            TextInterpolator(layout, typefaceCache).apply {
+                glyphFilter = { glyph, progress -> glyph.textSize += 10f }
             }
-        }
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -292,7 +296,8 @@
 
         // Just after created TextInterpolator, it should have 0 progress.
         val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
-        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+        val expected =
+            makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
                 .toBitmap(BMP_WIDTH, BMP_HEIGHT)
 
         // The glyph position was modified by callback, so the bitmap should not be the same.
@@ -304,11 +309,10 @@
     fun testGlyphCallback_Color() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout, typefaceCache).apply {
-            glyphFilter = { glyph, progress ->
-                glyph.color = Color.RED
+        val interp =
+            TextInterpolator(layout, typefaceCache).apply {
+                glyphFilter = { glyph, progress -> glyph.color = Color.RED }
             }
-        }
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -317,7 +321,8 @@
 
         // Just after created TextInterpolator, it should have 0 progress.
         val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
-        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+        val expected =
+            makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
                 .toBitmap(BMP_WIDTH, BMP_HEIGHT)
 
         // The glyph position was modified by callback, so the bitmap should not be the same.
@@ -327,7 +332,7 @@
 }
 
 private fun Layout.toBitmap(width: Int, height: Int) =
-        Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }!!
+    Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }!!
 
 private fun TextInterpolator.toBitmap(width: Int, height: Int) =
-        Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }
+    Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
similarity index 99%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
index a4653e7..77db977 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
@@ -29,7 +29,6 @@
 import org.junit.Test
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
-import platform.test.runner.parameterized.Parameter
 import org.junit.runner.RunWith
 
 @SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt
index 4d138b4..5d622ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt
@@ -122,9 +122,24 @@
 
     @Test
     @DisableFlags(Flags.FLAG_AUDIO_SHARING_QS_DIALOG_IMPROVEMENT)
+    fun testOnClick_connectedAudioSharingMediaDevice_flagOff_previewOn_createDialog() {
+        with(kosmos) {
+            testScope.runTest {
+                whenever(BluetoothUtils.isAudioSharingPreviewEnabled(any())).thenReturn(true)
+                bluetoothTileDialogAudioSharingRepository.setAudioSharingAvailable(true)
+                actionInteractorImpl.onClick(connectedAudioSharingMediaDeviceItem, dialog)
+                verify(dialogTransitionAnimator)
+                    .showFromDialog(any(), any(), eq(null), anyBoolean())
+            }
+        }
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_AUDIO_SHARING_QS_DIALOG_IMPROVEMENT)
     fun testOnClick_connectedAudioSharingMediaDevice_flagOff_shouldLaunchSettings() {
         with(kosmos) {
             testScope.runTest {
+                whenever(BluetoothUtils.isAudioSharingPreviewEnabled(any())).thenReturn(false)
                 bluetoothTileDialogAudioSharingRepository.setAudioSharingAvailable(true)
                 whenever(cachedBluetoothDevice.device).thenReturn(bluetoothDevice)
                 actionInteractorImpl.onClick(connectedAudioSharingMediaDeviceItem, dialog)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
index 2c17181..bfbdc50 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
@@ -24,9 +24,9 @@
 import android.os.Looper
 import android.os.PatternMatcher
 import android.os.UserHandle
-import androidx.test.filters.SmallTest
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
 import com.android.systemui.dump.DumpManager
@@ -40,8 +40,9 @@
 import junit.framework.Assert.assertSame
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.advanceUntilIdle
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -68,39 +69,28 @@
         val DEFAULT_PERMISSION: String? = null
 
         fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
+
         const val TEST_ACTION = "TEST_ACTION"
         const val TEST_SCHEME = "TEST_SCHEME"
         const val TEST_PATH = "TEST_PATH"
         const val TEST_TYPE = "test/type"
     }
 
-    @Mock
-    private lateinit var mockContext: Context
-    @Mock
-    private lateinit var mockUBRUser0: UserBroadcastDispatcher
-    @Mock
-    private lateinit var mockUBRUser1: UserBroadcastDispatcher
-    @Mock
-    private lateinit var broadcastReceiver: BroadcastReceiver
-    @Mock
-    private lateinit var broadcastReceiverOther: BroadcastReceiver
-    @Mock
-    private lateinit var intentFilter: IntentFilter
-    @Mock
-    private lateinit var intentFilterOther: IntentFilter
-    @Mock
-    private lateinit var mockHandler: Handler
-    @Mock
-    private lateinit var logger: BroadcastDispatcherLogger
-    @Mock
-    private lateinit var userTracker: UserTracker
-    @Mock
-    private lateinit var removalPendingStore: PendingRemovalStore
+    @Mock private lateinit var mockContext: Context
+    @Mock private lateinit var mockUBRUser0: UserBroadcastDispatcher
+    @Mock private lateinit var mockUBRUser1: UserBroadcastDispatcher
+    @Mock private lateinit var broadcastReceiver: BroadcastReceiver
+    @Mock private lateinit var broadcastReceiverOther: BroadcastReceiver
+    @Mock private lateinit var intentFilter: IntentFilter
+    @Mock private lateinit var intentFilterOther: IntentFilter
+    @Mock private lateinit var mockHandler: Handler
+    @Mock private lateinit var logger: BroadcastDispatcherLogger
+    @Mock private lateinit var userTracker: UserTracker
+    @Mock private lateinit var removalPendingStore: PendingRemovalStore
 
     private lateinit var mainExecutor: Executor
 
-    @Captor
-    private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>
+    @Captor private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>
 
     private lateinit var testableLooper: TestableLooper
     private lateinit var broadcastDispatcher: BroadcastDispatcher
@@ -112,7 +102,8 @@
         mainExecutor = FakeExecutor(FakeSystemClock())
         `when`(mockContext.mainExecutor).thenReturn(mainExecutor)
 
-        broadcastDispatcher = TestBroadcastDispatcher(
+        broadcastDispatcher =
+            TestBroadcastDispatcher(
                 mockContext,
                 mainExecutor,
                 testableLooper.looper,
@@ -121,7 +112,8 @@
                 logger,
                 userTracker,
                 removalPendingStore,
-                mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
+                mapOf(0 to mockUBRUser0, 1 to mockUBRUser1),
+            )
 
         // These should be valid filters
         `when`(intentFilter.countActions()).thenReturn(1)
@@ -131,10 +123,18 @@
 
     @Test
     fun testAddingReceiverToCorrectUBR() {
-        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
-                mockHandler, user0)
         broadcastDispatcher.registerReceiverWithHandler(
-                broadcastReceiverOther, intentFilterOther, mockHandler, user1)
+            broadcastReceiver,
+            intentFilter,
+            mockHandler,
+            user0,
+        )
+        broadcastDispatcher.registerReceiverWithHandler(
+            broadcastReceiverOther,
+            intentFilterOther,
+            mockHandler,
+            user1,
+        )
 
         testableLooper.processAllMessages()
 
@@ -152,7 +152,11 @@
     fun testAddingReceiverToCorrectUBR_executor() {
         broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mainExecutor, user0)
         broadcastDispatcher.registerReceiver(
-                broadcastReceiverOther, intentFilterOther, mainExecutor, user1)
+            broadcastReceiverOther,
+            intentFilterOther,
+            mainExecutor,
+            user1,
+        )
 
         testableLooper.processAllMessages()
 
@@ -169,7 +173,10 @@
     @Test
     fun testAddReceiverDefaultFlag_handler() {
         broadcastDispatcher.registerReceiverWithHandler(
-                broadcastReceiver, intentFilter, mockHandler)
+            broadcastReceiver,
+            intentFilter,
+            mockHandler,
+        )
         testableLooper.processAllMessages()
 
         verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG))
@@ -183,7 +190,11 @@
         val flag = 3
 
         broadcastDispatcher.registerReceiverWithHandler(
-                broadcastReceiver, intentFilter, mockHandler, flags = flag)
+            broadcastReceiver,
+            intentFilter,
+            mockHandler,
+            flags = flag,
+        )
         testableLooper.processAllMessages()
 
         verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(flag))
@@ -212,7 +223,7 @@
             broadcastReceiver,
             intentFilter,
             flags = flag,
-            permission = permission
+            permission = permission,
         )
         testableLooper.processAllMessages()
 
@@ -250,10 +261,18 @@
 
     @Test
     fun testRemovingReceiversRemovesFromAllUBR() {
-        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
-                mockHandler, user0)
-        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
-                mockHandler, user1)
+        broadcastDispatcher.registerReceiverWithHandler(
+            broadcastReceiver,
+            intentFilter,
+            mockHandler,
+            user0,
+        )
+        broadcastDispatcher.registerReceiverWithHandler(
+            broadcastReceiver,
+            intentFilter,
+            mockHandler,
+            user1,
+        )
 
         broadcastDispatcher.unregisterReceiver(broadcastReceiver)
 
@@ -265,10 +284,18 @@
 
     @Test
     fun testRemoveReceiverFromUser() {
-        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
-                mockHandler, user0)
-        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
-                mockHandler, user1)
+        broadcastDispatcher.registerReceiverWithHandler(
+            broadcastReceiver,
+            intentFilter,
+            mockHandler,
+            user0,
+        )
+        broadcastDispatcher.registerReceiverWithHandler(
+            broadcastReceiver,
+            intentFilter,
+            mockHandler,
+            user1,
+        )
 
         broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, user0)
 
@@ -282,13 +309,17 @@
     fun testRegisterCurrentAsActualUser() {
         `when`(userTracker.userId).thenReturn(user1.identifier)
 
-        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
-                mockHandler, UserHandle.CURRENT)
+        broadcastDispatcher.registerReceiverWithHandler(
+            broadcastReceiver,
+            intentFilter,
+            mockHandler,
+            UserHandle.CURRENT,
+        )
 
         testableLooper.processAllMessages()
 
-        verify(mockUBRUser1).registerReceiver(
-                capture(argumentCaptor), eq(Context.RECEIVER_EXPORTED))
+        verify(mockUBRUser1)
+            .registerReceiver(capture(argumentCaptor), eq(Context.RECEIVER_EXPORTED))
         assertSame(broadcastReceiver, argumentCaptor.value.receiver)
     }
 
@@ -300,41 +331,38 @@
 
     @Test(expected = IllegalArgumentException::class)
     fun testFilterMustNotContainDataScheme() {
-        val testFilter = IntentFilter(TEST_ACTION).apply {
-            addDataScheme(TEST_SCHEME)
-        }
+        val testFilter = IntentFilter(TEST_ACTION).apply { addDataScheme(TEST_SCHEME) }
         broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
     }
 
     @Test(expected = IllegalArgumentException::class)
     fun testFilterMustNotContainDataAuthority() {
-        val testFilter = IntentFilter(TEST_ACTION).apply {
-            addDataAuthority(mock(IntentFilter.AuthorityEntry::class.java))
-        }
+        val testFilter =
+            IntentFilter(TEST_ACTION).apply {
+                addDataAuthority(mock(IntentFilter.AuthorityEntry::class.java))
+            }
         broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
     }
 
     @Test(expected = IllegalArgumentException::class)
     fun testFilterMustNotContainDataPath() {
-        val testFilter = IntentFilter(TEST_ACTION).apply {
-            addDataPath(TEST_PATH, PatternMatcher.PATTERN_LITERAL)
-        }
+        val testFilter =
+            IntentFilter(TEST_ACTION).apply {
+                addDataPath(TEST_PATH, PatternMatcher.PATTERN_LITERAL)
+            }
         broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
     }
 
     @Test(expected = IllegalArgumentException::class)
     fun testFilterMustNotContainDataType() {
-        val testFilter = IntentFilter(TEST_ACTION).apply {
-            addDataType(TEST_TYPE)
-        }
+        val testFilter = IntentFilter(TEST_ACTION).apply { addDataType(TEST_TYPE) }
         broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
     }
 
     @Test(expected = IllegalArgumentException::class)
     fun testFilterMustNotSetPriority() {
-        val testFilter = IntentFilter(TEST_ACTION).apply {
-            priority = IntentFilter.SYSTEM_HIGH_PRIORITY
-        }
+        val testFilter =
+            IntentFilter(TEST_ACTION).apply { priority = IntentFilter.SYSTEM_HIGH_PRIORITY }
         broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
     }
 
@@ -366,12 +394,14 @@
 
         val inOrderUser0 = inOrder(mockUBRUser0, removalPendingStore)
         inOrderUser0.verify(mockUBRUser0).unregisterReceiver(broadcastReceiver)
-        inOrderUser0.verify(removalPendingStore)
+        inOrderUser0
+            .verify(removalPendingStore)
             .clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)
 
         val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
         inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
-        inOrderUser1.verify(removalPendingStore)
+        inOrderUser1
+            .verify(removalPendingStore)
             .clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)
     }
 
@@ -385,21 +415,21 @@
 
         val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
         inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
-        inOrderUser1.verify(removalPendingStore)
+        inOrderUser1
+            .verify(removalPendingStore)
             .clearPendingRemoval(broadcastReceiver, user1.identifier)
     }
 
     @Test
-    fun testBroadcastFlow() = runBlockingTest {
-        val flow = broadcastDispatcher.broadcastFlow(intentFilter, user1) { intent, receiver ->
-            intent to receiver
-        }
+    fun testBroadcastFlow() = runTest(UnconfinedTestDispatcher()) {
+        val flow =
+            broadcastDispatcher.broadcastFlow(intentFilter, user1) { intent, receiver ->
+                intent to receiver
+            }
 
         // Collect the values into collectedValues.
         val collectedValues = mutableListOf<Pair<Intent, BroadcastReceiver>>()
-        val job = launch {
-            flow.collect { collectedValues.add(it) }
-        }
+        val job = launch { flow.collect { collectedValues.add(it) } }
 
         testableLooper.processAllMessages()
         verify(mockUBRUser1).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG))
@@ -436,17 +466,18 @@
         logger: BroadcastDispatcherLogger,
         userTracker: UserTracker,
         removalPendingStore: PendingRemovalStore,
-        var mockUBRMap: Map<Int, UserBroadcastDispatcher>
-    ) : BroadcastDispatcher(
-        context,
-        mainExecutor,
-        backgroundRunningLooper,
-        backgroundRunningExecutor,
-        dumpManager,
-        logger,
-        userTracker,
-        removalPendingStore
-    ) {
+        var mockUBRMap: Map<Int, UserBroadcastDispatcher>,
+    ) :
+        BroadcastDispatcher(
+            context,
+            mainExecutor,
+            backgroundRunningLooper,
+            backgroundRunningExecutor,
+            dumpManager,
+            logger,
+            userTracker,
+            removalPendingStore,
+        ) {
         override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
             return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
         }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/education/domain/ui/view/ContextualEduDialogTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduDialogTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/education/domain/ui/view/ContextualEduDialogTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
deleted file mode 100644
index a9b6dd1..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
+++ /dev/null
@@ -1,103 +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.keyboard.shortcut.ui.viewmodel
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
-import com.android.systemui.keyboard.shortcut.shortcutCustomizationViewModelFactory
-import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testCase
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.res.R
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class ShortcutCustomizationViewModelTest : SysuiTestCase() {
-
-    private val kosmos = Kosmos().also { it.testCase = this }
-    private val testScope = kosmos.testScope
-    private val viewModel = kosmos.shortcutCustomizationViewModelFactory.create()
-
-    @Test
-    fun uiState_inactiveByDefault() {
-        testScope.runTest {
-            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
-
-            assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive)
-        }
-    }
-
-    @Test
-    fun uiState_correctlyUpdatedWhenAddShortcutCustomizationIsRequested() {
-        testScope.runTest {
-            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
-            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
-
-            assertThat(uiState).isEqualTo(expectedStandardAddShortcutUiState)
-        }
-    }
-
-    @Test
-    fun uiState_consumedOnAddDialogShown() {
-        testScope.runTest {
-            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
-            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
-            viewModel.onAddShortcutDialogShown()
-
-            assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).isDialogShowing)
-                .isTrue()
-        }
-    }
-
-    @Test
-    fun uiState_inactiveAfterDialogIsDismissed() {
-        testScope.runTest {
-            val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
-            viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
-            viewModel.onAddShortcutDialogShown()
-            viewModel.onAddShortcutDialogDismissed()
-            assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive)
-        }
-    }
-
-    private val standardAddShortcutRequest =
-        ShortcutCustomizationRequestInfo.Add(
-            label = "Standard shortcut",
-            categoryType = ShortcutCategoryType.System,
-            subCategoryLabel = "Standard subcategory",
-        )
-
-    private val expectedStandardAddShortcutUiState =
-        ShortcutCustomizationUiState.AddShortcutDialog(
-            shortcutLabel = "Standard shortcut",
-            shouldShowErrorMessage = false,
-            isValidKeyCombination = false,
-            defaultCustomShortcutModifierKey =
-                ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta),
-            isDialogShowing = false,
-        )
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
index bf4ef50..eb1b44b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
@@ -59,6 +59,7 @@
 import android.os.PowerExemptionManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.service.notification.StatusBarNotification;
 import android.testing.TestableLooper;
@@ -242,10 +243,14 @@
         mLocalMediaManager = spy(mMediaSwitchingController.mLocalMediaManager);
         when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(false);
         mMediaSwitchingController.mLocalMediaManager = mLocalMediaManager;
+
         mMediaSwitchingController.mInputRouteManager =
                 new InputRouteManager(mContext, mAudioManager);
         mInputRouteManager = spy(mMediaSwitchingController.mInputRouteManager);
         mMediaSwitchingController.mInputRouteManager = mInputRouteManager;
+        when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS))
+                .thenReturn(new AudioDeviceInfo[0]);
+
         MediaDescription.Builder builder = new MediaDescription.Builder();
         builder.setTitle(TEST_SONG);
         builder.setSubtitle(TEST_ARTIST);
@@ -483,11 +488,11 @@
         verify(mMediaDevice2, never()).setRangeZone(anyInt());
     }
 
+    @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
     @Test
     public void onDeviceListUpdate_verifyDeviceListCallback() {
         // This test relies on mMediaSwitchingController.start being called while the selected
-        // device
-        // list has exactly one item, and that item's id is:
+        // device list has exactly one item, and that item's id is:
         // - Different from both ids in mMediaDevices.
         // - Different from the id of the route published by the device under test (usually the
         //   built-in speakers).
@@ -511,16 +516,54 @@
 
         assertThat(devices.containsAll(mMediaDevices)).isTrue();
         assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+        // There should be 2 non-MediaDevice items: the "Speakers & Display" title, and the "Connect
+        // a device" button.
         assertThat(mMediaSwitchingController.getMediaItemList().size())
                 .isEqualTo(mMediaDevices.size() + 2);
         verify(mCb).onDeviceListChanged();
     }
 
+    @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+    @Test
+    public void onDeviceListUpdate_verifyDeviceListCallback_inputRouting() {
+        // This test relies on mMediaSwitchingController.start being called while the selected
+        // device list has exactly one item, and that item's id is:
+        // - Different from both ids in mMediaDevices.
+        // - Different from the id of the route published by the device under test (usually the
+        //   built-in speakers).
+        // So mock the selected device to respect these two preconditions.
+        MediaDevice mockSelectedMediaDevice = Mockito.mock(MediaDevice.class);
+        when(mockSelectedMediaDevice.getId()).thenReturn(TEST_DEVICE_3_ID);
+        doReturn(List.of(mockSelectedMediaDevice))
+                .when(mLocalMediaManager)
+                .getSelectedMediaDevice();
+
+        mMediaSwitchingController.start(mCb);
+        reset(mCb);
+
+        mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);
+        final List<MediaDevice> devices = new ArrayList<>();
+        for (MediaItem item : mMediaSwitchingController.getMediaItemList()) {
+            if (item.getMediaDevice().isPresent()) {
+                devices.add(item.getMediaDevice().get());
+            }
+        }
+
+        assertThat(devices.containsAll(mMediaDevices)).isTrue();
+        assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+        // When input routing is enabled, there should be 4 non-MediaDevice items: one for
+        // the "Output" title, one for the "Speakers & Displays" title, one for the "Connect a
+        // device" button, and one for the "Input" title.
+        assertThat(mMediaSwitchingController.getMediaItemList().size())
+                .isEqualTo(mMediaDevices.size() + 4);
+        verify(mCb).onDeviceListChanged();
+    }
+
+    @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
     @Test
     public void advanced_onDeviceListUpdateWithConnectedDeviceRemote_verifyItemSize() {
         // This test relies on mMediaSwitchingController.start being called while the selected
-        // device
-        // list has exactly one item, and that item's id is:
+        // device list has exactly one item, and that item's id is:
         // - Different from both ids in mMediaDevices.
         // - Different from the id of the route published by the device under test (usually the
         //   built-in speakers).
@@ -547,6 +590,7 @@
 
         assertThat(devices.containsAll(mMediaDevices)).isTrue();
         assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+        // There should be 1 non-MediaDevice item: the "Speakers & Display" title.
         assertThat(mMediaSwitchingController.getMediaItemList().size())
                 .isEqualTo(mMediaDevices.size() + 1);
         verify(mCb).onDeviceListChanged();
@@ -554,6 +598,45 @@
 
     @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
     @Test
+    public void advanced_onDeviceListUpdateWithConnectedDeviceRemote_verifyItemSize_inputRouting() {
+        // This test relies on mMediaSwitchingController.start being called while the selected
+        // device list has exactly one item, and that item's id is:
+        // - Different from both ids in mMediaDevices.
+        // - Different from the id of the route published by the device under test (usually the
+        //   built-in speakers).
+        // So mock the selected device to respect these two preconditions.
+        MediaDevice mockSelectedMediaDevice = Mockito.mock(MediaDevice.class);
+        when(mockSelectedMediaDevice.getId()).thenReturn(TEST_DEVICE_3_ID);
+        doReturn(List.of(mockSelectedMediaDevice))
+                .when(mLocalMediaManager)
+                .getSelectedMediaDevice();
+
+        when(mMediaDevice1.getFeatures())
+                .thenReturn(ImmutableList.of(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK));
+        when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice1);
+        mMediaSwitchingController.start(mCb);
+        reset(mCb);
+
+        mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);
+        final List<MediaDevice> devices = new ArrayList<>();
+        for (MediaItem item : mMediaSwitchingController.getMediaItemList()) {
+            if (item.getMediaDevice().isPresent()) {
+                devices.add(item.getMediaDevice().get());
+            }
+        }
+
+        assertThat(devices.containsAll(mMediaDevices)).isTrue();
+        assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+        // When input routing is enabled, there should be 3 non-MediaDevice items: one for
+        // the "Output" title, one for the "Speakers & Displays" title, and one for the "Input"
+        // title.
+        assertThat(mMediaSwitchingController.getMediaItemList().size())
+                .isEqualTo(mMediaDevices.size() + 3);
+        verify(mCb).onDeviceListChanged();
+    }
+
+    @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+    @Test
     public void onInputDeviceListUpdate_verifyDeviceListCallback() {
         AudioDeviceInfo[] audioDeviceInfos = {};
         when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
index bc3c0d9..d59a404 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
@@ -49,6 +49,7 @@
 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.views.NavigationBar;
 import com.android.systemui.recents.OverviewProxyService;
@@ -56,7 +57,7 @@
 import com.android.systemui.shared.recents.utilities.Utilities;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.AutoHideControllerStore;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -89,6 +90,11 @@
 
     private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
 
+    private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
+
+    private final AutoHideControllerStore mAutoHideControllerStore =
+            mKosmos.getAutoHideControllerStore();
+
     @Mock
     private CommandQueue mCommandQueue;
     @Mock
@@ -113,7 +119,7 @@
                         mTaskbarDelegate,
                         mNavigationBarFactory,
                         mock(DumpManager.class),
-                        mock(AutoHideController.class),
+                        mAutoHideControllerStore,
                         mock(LightBarController.class),
                         TaskStackChangeListeners.getTestInstance(),
                         Optional.of(mock(Pip.class)),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index d708489..7849ea5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -38,6 +38,7 @@
 import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED
 import android.content.pm.ShortcutManager
 import android.content.pm.UserInfo
+import android.content.res.Resources
 import android.graphics.drawable.Icon
 import android.os.UserHandle
 import android.os.UserManager
@@ -84,6 +85,7 @@
 import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.whenever
 
@@ -106,6 +108,7 @@
     @Mock private lateinit var shortcutManager: ShortcutManager
     @Mock private lateinit var activityManager: ActivityManager
     @Mock private lateinit var devicePolicyManager: DevicePolicyManager
+    private lateinit var spiedResources: Resources
     private val userTracker = FakeUserTracker()
     private val testDispatcher = UnconfinedTestDispatcher()
     private val testScope = TestScope(testDispatcher)
@@ -130,7 +133,7 @@
         whenever(
                 devicePolicyManager.getKeyguardDisabledFeatures(
                     /* admin= */ eq(null),
-                    /* userHandle= */ anyInt()
+                    /* userHandle= */ anyInt(),
                 )
             )
             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE)
@@ -139,6 +142,9 @@
         whenever(activityManager.getRunningTasks(anyInt())).thenReturn(emptyList())
         whenever(userManager.isManagedProfile(workUserInfo.id)).thenReturn(true)
         whenever(context.resources).thenReturn(getContext().resources)
+
+        spiedResources = spy(context.resources)
+        `when`(context.resources).thenReturn(spiedResources)
     }
 
     private fun createNoteTaskController(
@@ -161,7 +167,7 @@
             noteTaskBubblesController =
                 FakeNoteTaskBubbleController(context, testDispatcher, Optional.ofNullable(bubbles)),
             applicationScope = testScope,
-            bgCoroutineContext = testScope.backgroundScope.coroutineContext
+            bgCoroutineContext = testScope.backgroundScope.coroutineContext,
         )
 
     // region onBubbleExpandChanged
@@ -225,11 +231,7 @@
 
     @Test
     fun onBubbleExpandChanged_notKeyAppBubble_shouldDoNothing() {
-        createNoteTaskController()
-            .onBubbleExpandChanged(
-                isExpanding = true,
-                key = "any other key",
-            )
+        createNoteTaskController().onBubbleExpandChanged(isExpanding = true, key = "any other key")
 
         verifyNoMoreInteractions(bubbles, keyguardManager, userManager, eventLogger)
     }
@@ -251,11 +253,7 @@
     fun showNoteTaskAsUser_keyguardIsLocked_shouldStartActivityWithExpectedUserAndLogUiEvent() {
         val user10 = UserHandle.of(/* userId= */ 10)
         val expectedInfo =
-            NOTE_TASK_INFO.copy(
-                entryPoint = TAIL_BUTTON,
-                isKeyguardLocked = true,
-                user = user10,
-            )
+            NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true, user = user10)
         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
 
@@ -360,7 +358,7 @@
         secureSettings.putIntForUser(
             /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
             /* value= */ 10,
-            /* userHandle= */ userTracker.userId
+            /* userHandle= */ userTracker.userId,
         )
         val user10 = UserHandle.of(/* userId= */ 10)
 
@@ -373,10 +371,7 @@
         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
 
-        createNoteTaskController()
-            .showNoteTask(
-                entryPoint = expectedInfo.entryPoint!!,
-            )
+        createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
 
         val intentCaptor = argumentCaptor<Intent>()
         val userCaptor = argumentCaptor<UserHandle>()
@@ -456,6 +451,85 @@
         verifyNoMoreInteractions(bubbles)
     }
 
+    @Test
+    fun showNoteTask_stylusModePreferred_keyboardShortcut_shouldStartInDefaultUIMode() {
+        `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(1)
+        val expectedInfo =
+            NOTE_TASK_INFO.copy(entryPoint = KEYBOARD_SHORTCUT, isKeyguardLocked = true)
+        whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
+        whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
+
+        createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
+
+        val intentCaptor = argumentCaptor<Intent>()
+        val userCaptor = argumentCaptor<UserHandle>()
+        verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+        assertThat(intentCaptor.value).run {
+            hasAction(ACTION_CREATE_NOTE)
+            hasPackage(NOTE_TASK_PACKAGE_NAME)
+            extras().bool(EXTRA_USE_STYLUS_MODE).isFalse()
+        }
+    }
+
+    @Test
+    fun showNoteTask_stylusModePreferred_quickAffordance_shouldStartInStylusUIMode() {
+        `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(1)
+        val expectedInfo =
+            NOTE_TASK_INFO.copy(entryPoint = QUICK_AFFORDANCE, isKeyguardLocked = true)
+        whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
+        whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
+
+        createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
+
+        val intentCaptor = argumentCaptor<Intent>()
+        val userCaptor = argumentCaptor<UserHandle>()
+        verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+        assertThat(intentCaptor.value).run {
+            hasAction(ACTION_CREATE_NOTE)
+            hasPackage(NOTE_TASK_PACKAGE_NAME)
+            extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
+        }
+    }
+
+    @Test
+    fun showNoteTask_noUIRecommendation_quickAffordance_shouldStartInDefaultUIMode() {
+        `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(0)
+        val expectedInfo =
+            NOTE_TASK_INFO.copy(entryPoint = QUICK_AFFORDANCE, isKeyguardLocked = true)
+        whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
+        whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
+
+        createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
+
+        val intentCaptor = argumentCaptor<Intent>()
+        val userCaptor = argumentCaptor<UserHandle>()
+        verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+        assertThat(intentCaptor.value).run {
+            hasAction(ACTION_CREATE_NOTE)
+            hasPackage(NOTE_TASK_PACKAGE_NAME)
+            extras().bool(EXTRA_USE_STYLUS_MODE).isFalse()
+        }
+    }
+
+    @Test
+    fun showNoteTask_noUIRecommendation_tailButton_shouldStartInStylusUIMode() {
+        `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(0)
+        val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true)
+        whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
+        whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
+
+        createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
+
+        val intentCaptor = argumentCaptor<Intent>()
+        val userCaptor = argumentCaptor<UserHandle>()
+        verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+        assertThat(intentCaptor.value).run {
+            hasAction(ACTION_CREATE_NOTE)
+            hasPackage(NOTE_TASK_PACKAGE_NAME)
+            extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
+        }
+    }
+
     // endregion
 
     // region setNoteTaskShortcutEnabled
@@ -543,7 +617,7 @@
         whenever(
                 devicePolicyManager.getKeyguardDisabledFeatures(
                     /* admin= */ eq(null),
-                    /* userHandle= */ anyInt()
+                    /* userHandle= */ anyInt(),
                 )
             )
             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
@@ -559,7 +633,7 @@
         whenever(
                 devicePolicyManager.getKeyguardDisabledFeatures(
                     /* admin= */ eq(null),
-                    /* userHandle= */ anyInt()
+                    /* userHandle= */ anyInt(),
                 )
             )
             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
@@ -575,7 +649,7 @@
         whenever(
                 devicePolicyManager.getKeyguardDisabledFeatures(
                     /* admin= */ eq(null),
-                    /* userHandle= */ anyInt()
+                    /* userHandle= */ anyInt(),
                 )
             )
             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
@@ -591,7 +665,7 @@
         whenever(
                 devicePolicyManager.getKeyguardDisabledFeatures(
                     /* admin= */ eq(null),
-                    /* userHandle= */ anyInt()
+                    /* userHandle= */ anyInt(),
                 )
             )
             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
@@ -604,8 +678,9 @@
     // endregion
 
     // region showNoteTask, COPE devices
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun showNoteTask_copeDevices_quickAffordanceEntryPoint_managedProfileNotFound_shouldStartBubbleInTheMainProfile() { // ktlint-disable max-line-length
+    fun showNoteTask_copeDevices_quickAffordanceEntryPoint_managedProfileNotFound_shouldStartBubbleInTheMainProfile() {
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(listOf(mainUserInfo), mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
@@ -629,7 +704,7 @@
         secureSettings.putIntForUser(
             /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
             /* value= */ mainUserInfo.id,
-            /* userHandle= */ userTracker.userId
+            /* userHandle= */ userTracker.userId,
         )
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -836,12 +911,13 @@
         assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id))
     }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { // ktlint-disable max-line-length
+    fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() {
         secureSettings.putIntForUser(
             /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
             /* value= */ workUserInfo.id,
-            /* userHandle= */ userTracker.userId
+            /* userHandle= */ userTracker.userId,
         )
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -851,12 +927,13 @@
         assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id))
     }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { // ktlint-disable max-line-length
+    fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() {
         secureSettings.putIntForUser(
             /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
             /* value= */ mainUserInfo.id,
-            /* userHandle= */ userTracker.userId
+            /* userHandle= */ userTracker.userId,
         )
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -934,8 +1011,9 @@
         assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
     }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length
+    fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() {
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
         createNoteTaskController().startNotesRoleSetting(context, QUICK_AFFORDANCE)
@@ -947,8 +1025,9 @@
         assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
     }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length
+    fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() {
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
         createNoteTaskController().startNotesRoleSetting(context, entryPoint = null)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
index fac5ecb..f23553e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
@@ -23,6 +23,7 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.click
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithContentDescription
 import androidx.compose.ui.test.performClick
@@ -73,7 +74,7 @@
     }
 
     @Test
-    fun toggleIconTile_shouldBeLarge() {
+    fun toggleIconTileWithA11yAction_shouldBeLarge() {
         var tiles by mutableStateOf(TestEditTiles)
         val listState = EditTileListState(tiles, columns = 4, largeTilesSpan = 2)
         composeRule.setContent {
@@ -89,7 +90,7 @@
     }
 
     @Test
-    fun toggleLargeTile_shouldBeIcon() {
+    fun toggleLargeTileWithA11yAction_shouldBeIcon() {
         var tiles by mutableStateOf(TestEditTiles)
         val listState = EditTileListState(tiles, columns = 4, largeTilesSpan = 2)
         composeRule.setContent {
@@ -105,7 +106,7 @@
     }
 
     @Test
-    fun resizedLarge_shouldBeIcon() {
+    fun tapOnIconResizingHandle_shouldBeLarge() {
         var tiles by mutableStateOf(TestEditTiles)
         val listState = EditTileListState(tiles, columns = 4, largeTilesSpan = 2)
         composeRule.setContent {
@@ -116,12 +117,32 @@
         composeRule
             .onNodeWithContentDescription("tileA")
             .performClick() // Select
-            .performTouchInput { // Resize down
-                swipeRight()
+            .performTouchInput { // Tap on resizing handle
+                click(centerRight)
             }
         composeRule.waitForIdle()
 
-        assertThat(tiles.find { it.tile.tileSpec.spec == "tileA" }?.width).isEqualTo(1)
+        assertThat(tiles.find { it.tile.tileSpec.spec == "tileA" }?.width).isEqualTo(2)
+    }
+
+    @Test
+    fun tapOnLargeResizingHandle_shouldBeIcon() {
+        var tiles by mutableStateOf(TestEditTiles)
+        val listState = EditTileListState(tiles, columns = 4, largeTilesSpan = 2)
+        composeRule.setContent {
+            EditTileGridUnderTest(listState) { spec, toIcon -> tiles = tiles.resize(spec, toIcon) }
+        }
+        composeRule.waitForIdle()
+
+        composeRule
+            .onNodeWithContentDescription("tileD_large")
+            .performClick() // Select
+            .performTouchInput { // Tap on resizing handle
+                click(centerRight)
+            }
+        composeRule.waitForIdle()
+
+        assertThat(tiles.find { it.tile.tileSpec.spec == "tileD_large" }?.width).isEqualTo(1)
     }
 
     @Test
@@ -134,6 +155,26 @@
         composeRule.waitForIdle()
 
         composeRule
+            .onNodeWithContentDescription("tileA")
+            .performClick() // Select
+            .performTouchInput { // Resize up
+                swipeRight(startX = right, endX = right * 2)
+            }
+        composeRule.waitForIdle()
+
+        assertThat(tiles.find { it.tile.tileSpec.spec == "tileA" }?.width).isEqualTo(2)
+    }
+
+    @Test
+    fun resizedLarge_shouldBeIcon() {
+        var tiles by mutableStateOf(TestEditTiles)
+        val listState = EditTileListState(tiles, columns = 4, largeTilesSpan = 2)
+        composeRule.setContent {
+            EditTileGridUnderTest(listState) { spec, toIcon -> tiles = tiles.resize(spec, toIcon) }
+        }
+        composeRule.waitForIdle()
+
+        composeRule
             .onNodeWithContentDescription("tileD_large")
             .performClick() // Select
             .performTouchInput { // Resize down
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index 859f84e..e7fb470c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -33,6 +33,7 @@
 import androidx.test.filters.SmallTest
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.Flags
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB_ON_MOBILE
 import com.android.systemui.Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.ambient.touch.TouchHandler
@@ -630,6 +631,7 @@
             }
         }
 
+    @DisableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
     @Test
     fun onTouchEvent_shadeInteracting_movesNotDispatched() =
         with(kosmos) {
@@ -686,6 +688,7 @@
             }
         }
 
+    @DisableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
     @Test
     fun onTouchEvent_bouncerInteracting_movesNotDispatched() =
         with(kosmos) {
@@ -718,6 +721,19 @@
             }
         }
 
+    @EnableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+    @Test
+    fun onTouchEvent_onLockscreenAndGlanceableHubV2_touchIgnored() =
+        with(kosmos) {
+            testScope.runTest {
+                // On lockscreen.
+                goToScene(CommunalScenes.Blank)
+
+                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+                verify(containerView, never()).onTouchEvent(DOWN_EVENT)
+            }
+        }
+
     @Test
     fun disposeView_destroysTouchMonitor() {
         clearInvocations(touchMonitor)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt
index 2812bd3..b3a5872 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt
@@ -49,7 +49,7 @@
                     context,
                     context.resources,
                     ClockSettings(),
-                    TypefaceCache(messageBuffer) {
+                    TypefaceCache(messageBuffer, 20) {
                         // TODO(b/364680873): Move constant to config_clockFontFamily when shipping
                         return@TypefaceCache Typeface.create(
                             "google-sans-flex-clock",
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index 61d14b7..58864f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -76,7 +76,7 @@
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.FakeEventLog;
 import com.android.systemui.util.settings.FakeGlobalSettings;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
index f870200..28577b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
@@ -61,7 +61,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.util.time.FakeSystemClock;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index e313a05..5aee929 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -45,6 +45,7 @@
 import android.graphics.drawable.AnimationDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -67,6 +68,7 @@
 import com.android.systemui.statusbar.notification.FeedbackIcon;
 import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
 import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
@@ -393,7 +395,7 @@
         ExpandableNotificationRow row = mNotificationTestHelper.createRow();
         AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
         row.setAboveShelfChangedListener(listener);
-        row.setPinned(true);
+        row.setPinnedStatus(PinnedStatus.PinnedBySystem);
         verify(listener).onAboveShelfStateChanged(true);
     }
 
@@ -551,12 +553,26 @@
     }
 
     @Test
+    @DisableFlags(com.android.systemui.Flags.FLAG_NOTIFICATION_REENTRANT_DISMISS)
+    public void testCanDismiss_immediately() throws Exception {
+        ExpandableNotificationRow row =
+                mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
+        when(mNotificationTestHelper.getDismissibilityProvider().isDismissable(row.getEntry()))
+                .thenReturn(true);
+        row.performDismiss(false);
+        verify(mNotificationTestHelper.getOnUserInteractionCallback())
+                .registerFutureDismissal(any(), anyInt());
+    }
+
+    @Test
+    @EnableFlags(com.android.systemui.Flags.FLAG_NOTIFICATION_REENTRANT_DISMISS)
     public void testCanDismiss() throws Exception {
         ExpandableNotificationRow row =
                 mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
         when(mNotificationTestHelper.getDismissibilityProvider().isDismissable(row.getEntry()))
                 .thenReturn(true);
         row.performDismiss(false);
+        TestableLooper.get(this).processAllMessages();
         verify(mNotificationTestHelper.getOnUserInteractionCallback())
                 .registerFutureDismissal(any(), anyInt());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
index 723c0d7..2d35ea5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
@@ -65,11 +65,11 @@
 import com.android.systemui.statusbar.notification.NotificationActivityStarter
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+import com.android.systemui.statusbar.notification.headsup.headsUpManager
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.notificationLockscreenUserManager
 import com.android.systemui.statusbar.policy.deviceProvisionedController
-import com.android.systemui.statusbar.policy.headsUpManager
 import com.android.systemui.testKosmos
 import com.android.systemui.util.kotlin.JavaAdapter
 import com.android.systemui.wmshell.BubblesManager
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 d2350bc..11b19f9 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
@@ -103,7 +103,7 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.policy.AvalancheController;
+import com.android.systemui.statusbar.notification.headsup.AvalancheController;
 import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
 import com.android.systemui.wallpapers.domain.interactor.WallpaperInteractor;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index b142fc2..6912eda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -198,7 +198,7 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.ExtensionController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
 import com.android.systemui.statusbar.window.StatusBarWindowController;
@@ -334,7 +334,7 @@
     @Mock private CentralSurfacesCommandQueueCallbacks mCentralSurfacesCommandQueueCallbacks;
     @Mock private PluginManager mPluginManager;
     @Mock private ViewMediatorCallback mViewMediatorCallback;
-    @Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    @Mock private ShadeTouchableRegionManager mShadeTouchableRegionManager;
     @Mock private PluginDependencyProvider mPluginDependencyProvider;
     @Mock private ExtensionController mExtensionController;
     @Mock private UserInfoControllerImpl mUserInfoControllerImpl;
@@ -607,7 +607,6 @@
                 mShadeController,
                 mWindowRootViewVisibilityInteractor,
                 mStatusBarKeyguardViewManager,
-                () -> mStatusBarLongPressGestureDetector,
                 mViewMediatorCallback,
                 mInitController,
                 new Handler(TestableLooper.get(this).getLooper()),
@@ -618,7 +617,7 @@
                 mKeyguardIndicationController,
                 mDemoModeController,
                 mNotificationShadeDepthControllerLazy,
-                mStatusBarTouchableRegionManager,
+                mShadeTouchableRegionManager,
                 mBrightnessSliderFactory,
                 mScreenOffAnimationController,
                 mWallpaperController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index cace60c..2f30b74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -95,7 +95,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index a213c85..1d4b8e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -58,6 +58,7 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
 
 import kotlin.sequences.Sequence;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index aad8b4b..af14edd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -154,7 +154,7 @@
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -2575,78 +2575,6 @@
 
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
-    public void testEventLogging_bubbleBar_dragBarLeft() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
-        mPositioner.setIsLargeScreen(true);
-        mPositioner.setBubbleBarLocation(BubbleBarLocation.RIGHT);
-        FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
-        mBubbleController.registerBubbleStateListener(bubbleStateListener);
-
-        mEntryListener.onEntryAdded(mRow);
-        assertBarMode();
-
-        mBubbleController.setBubbleBarLocation(BubbleBarLocation.LEFT,
-                BubbleBarLocation.UpdateSource.DRAG_BAR);
-
-        verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_BAR);
-    }
-
-    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
-    @Test
-    public void testEventLogging_bubbleBar_dragBarRight() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
-        mPositioner.setIsLargeScreen(true);
-        mPositioner.setBubbleBarLocation(BubbleBarLocation.LEFT);
-        FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
-        mBubbleController.registerBubbleStateListener(bubbleStateListener);
-
-        mEntryListener.onEntryAdded(mRow);
-        assertBarMode();
-
-        mBubbleController.setBubbleBarLocation(BubbleBarLocation.RIGHT,
-                BubbleBarLocation.UpdateSource.DRAG_BAR);
-
-        verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_BAR);
-    }
-
-    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
-    @Test
-    public void testEventLogging_bubbleBar_dragBubbleLeft() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
-        mPositioner.setIsLargeScreen(true);
-        mPositioner.setBubbleBarLocation(BubbleBarLocation.RIGHT);
-        FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
-        mBubbleController.registerBubbleStateListener(bubbleStateListener);
-
-        mEntryListener.onEntryAdded(mRow);
-        assertBarMode();
-
-        mBubbleController.setBubbleBarLocation(BubbleBarLocation.LEFT,
-                BubbleBarLocation.UpdateSource.DRAG_BUBBLE);
-
-        verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_BUBBLE);
-    }
-
-    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
-    @Test
-    public void testEventLogging_bubbleBar_dragBubbleRight() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
-        mPositioner.setIsLargeScreen(true);
-        mPositioner.setBubbleBarLocation(BubbleBarLocation.LEFT);
-        FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
-        mBubbleController.registerBubbleStateListener(bubbleStateListener);
-
-        mEntryListener.onEntryAdded(mRow);
-        assertBarMode();
-
-        mBubbleController.setBubbleBarLocation(BubbleBarLocation.RIGHT,
-                BubbleBarLocation.UpdateSource.DRAG_BUBBLE);
-
-        verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_BUBBLE);
-    }
-
-    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
-    @Test
     public void testEventLogging_bubbleBar_expandAndCollapse() {
         mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
index 5063140..0ba7c85 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
@@ -62,6 +62,7 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
 import com.android.systemui.statusbar.notification.collection.NotifCollection
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger
 import com.android.systemui.statusbar.notification.stack.AmbientState
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
@@ -74,7 +75,6 @@
 import com.android.systemui.statusbar.phone.ScrimController
 import com.android.systemui.statusbar.phone.SystemUIDialogManager
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.policy.ZenModeController
 import com.android.systemui.statusbar.window.StatusBarWindowController
@@ -173,7 +173,7 @@
     interface Bindings {
         @Binds
         fun bindStatusBarStateController(
-            sysuiStatusBarStateController: SysuiStatusBarStateController,
+            sysuiStatusBarStateController: SysuiStatusBarStateController
         ): StatusBarStateController
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MotionEventHelper.java b/packages/SystemUI/tests/utils/src/com/android/systemui/accessibility/MotionEventHelper.java
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MotionEventHelper.java
rename to packages/SystemUI/tests/utils/src/com/android/systemui/accessibility/MotionEventHelper.java
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/TestableWindowManager.java b/packages/SystemUI/tests/utils/src/com/android/systemui/accessibility/TestableWindowManager.java
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/TestableWindowManager.java
rename to packages/SystemUI/tests/utils/src/com/android/systemui/accessibility/TestableWindowManager.java
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/activity/data/repository/ActivityManagerRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/activity/data/repository/ActivityManagerRepositoryKosmos.kt
new file mode 100644
index 0000000..a6e7133
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/activity/data/repository/ActivityManagerRepositoryKosmos.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.activity.data.repository
+
+import android.app.activityManager
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.log.core.Logger
+import kotlinx.coroutines.flow.MutableStateFlow
+
+val Kosmos.activityManagerRepository by Kosmos.Fixture { FakeActivityManagerRepository() }
+
+val Kosmos.realActivityManagerRepository by
+    Kosmos.Fixture { ActivityManagerRepositoryImpl(testDispatcher, activityManager) }
+
+class FakeActivityManagerRepository : ActivityManagerRepository {
+    private val uidFlows = mutableMapOf<Int, MutableList<MutableStateFlow<Boolean>>>()
+
+    var startingIsAppVisibleValue = false
+
+    override fun createIsAppVisibleFlow(
+        creationUid: Int,
+        logger: Logger,
+        identifyingLogTag: String,
+    ): MutableStateFlow<Boolean> {
+        val newFlow = MutableStateFlow(startingIsAppVisibleValue)
+        uidFlows.computeIfAbsent(creationUid) { mutableListOf() }.add(newFlow)
+        return newFlow
+    }
+
+    fun setIsAppVisible(uid: Int, isAppVisible: Boolean) {
+        uidFlows[uid]?.forEach { stateFlow -> stateFlow.value = isAppVisible }
+    }
+}
+
+val ActivityManagerRepository.fake
+    get() = this as FakeActivityManagerRepository
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt
index 4f4d1da..e0c0fbd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt
@@ -16,12 +16,14 @@
 
 package com.android.systemui.bluetooth.qsdialog
 
+import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testDispatcher
 
 val Kosmos.audioSharingInteractor: AudioSharingInteractor by
     Kosmos.Fixture {
         AudioSharingInteractorImpl(
+            applicationContext,
             localBluetoothManager,
             bluetoothTileDialogAudioSharingRepository,
             testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
index e36ad42..35e85bb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
@@ -18,6 +18,7 @@
 
 import com.android.systemui.brightness.domain.interactor.brightnessPolicyEnforcementInteractor
 import com.android.systemui.brightness.domain.interactor.screenBrightnessInteractor
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
 import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
@@ -33,6 +34,7 @@
                     hapticsViewModelFactory = sliderHapticsViewModelFactory,
                     brightnessMirrorShowingInteractor = brightnessMirrorShowingInteractor,
                     supportsMirroring = allowsMirroring,
+                    falsingInteractor = falsingInteractor,
                     brightnessWarningToast = brightnessWarningToast,
                 )
             }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
index 78ea700..ddcc926 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
@@ -57,6 +57,10 @@
         addDisplay(display(type, id = displayId))
     }
 
+    suspend fun addDisplays(vararg displays: Display) {
+        displays.forEach { addDisplay(it) }
+    }
+
     suspend fun addDisplay(display: Display) {
         flow.value += display
         displayAdditionEventFlow.emit(display)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorKosmos.kt
similarity index 64%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorKosmos.kt
index 5a04169..c2466bb 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractorKosmos.kt
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.systemui.display.domain.interactor
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+import com.android.systemui.display.data.repository.displayWindowPropertiesRepository
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.displayWindowPropertiesInteractor by
+    Kosmos.Fixture { DisplayWindowPropertiesInteractorImpl(displayWindowPropertiesRepository) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeServiceFake.java b/packages/SystemUI/tests/utils/src/com/android/systemui/doze/DozeServiceFake.java
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeServiceFake.java
rename to packages/SystemUI/tests/utils/src/com/android/systemui/doze/DozeServiceFake.java
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt
index b24b3ad..71746b5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.dreams.ui.viewmodel
 
+import com.android.systemui.communal.domain.interactor.communalInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.shade.domain.interactor.shadeInteractor
@@ -23,6 +24,7 @@
 val Kosmos.dreamUserActionsViewModel by
     Kosmos.Fixture {
         DreamUserActionsViewModel(
+            communalInteractor = communalInteractor,
             deviceUnlockedInteractor = deviceUnlockedInteractor,
             shadeInteractor = shadeInteractor,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index 9cb15c5..8d98ea3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.broadcast.broadcastDispatcher
 import com.android.systemui.keyboard.shortcut.data.repository.CustomShortcutCategoriesRepository
 import com.android.systemui.keyboard.shortcut.data.repository.DefaultShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.repository.InputGestureMaps
 import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesUtils
 import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
 import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperTestHelper
@@ -57,7 +58,7 @@
     Kosmos.Fixture { SystemShortcutsSource(mainResources) }
 
 var Kosmos.shortcutHelperMultiTaskingShortcutsSource: KeyboardShortcutGroupsSource by
-    Kosmos.Fixture { MultitaskingShortcutsSource(mainResources) }
+    Kosmos.Fixture { MultitaskingShortcutsSource(mainResources, applicationContext) }
 
 val Kosmos.shortcutHelperStateRepository by
     Kosmos.Fixture {
@@ -101,6 +102,8 @@
         )
     }
 
+val Kosmos.inputGestureMaps by Kosmos.Fixture { InputGestureMaps(applicationContext) }
+
 val Kosmos.customShortcutCategoriesRepository by
     Kosmos.Fixture {
         CustomShortcutCategoriesRepository(
@@ -110,6 +113,7 @@
             testDispatcher,
             shortcutCategoriesUtils,
             applicationContext,
+            inputGestureMaps,
         )
     }
 
@@ -173,7 +177,10 @@
     Kosmos.Fixture {
         object : ShortcutCustomizationViewModel.Factory {
             override fun create(): ShortcutCustomizationViewModel {
-                return ShortcutCustomizationViewModel(shortcutCustomizationInteractor)
+                return ShortcutCustomizationViewModel(
+                    applicationContext,
+                    shortcutCustomizationInteractor,
+                )
             }
         }
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
similarity index 100%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
index 007d229..f88ed07 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
@@ -16,18 +16,24 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import com.android.internal.widget.lockPatternUtils
 import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.keyguardRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.user.domain.interactor.selectedUserInteractor
 
 val Kosmos.keyguardEnabledInteractor by
     Kosmos.Fixture {
         KeyguardEnabledInteractor(
             applicationCoroutineScope,
+            testDispatcher,
             keyguardRepository,
             biometricSettingsRepository,
-            keyguardDismissTransitionInteractor,
+            selectedUserInteractor,
+            lockPatternUtils,
+            { keyguardDismissTransitionInteractor },
             internalTransitionInteractor = internalKeyguardTransitionInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorKosmos.kt
index 39236c7..2423949 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorKosmos.kt
@@ -24,5 +24,6 @@
         KeyguardLockWhileAwakeInteractor(
             biometricSettingsRepository = biometricSettingsRepository,
             keyguardEnabledInteractor = keyguardEnabledInteractor,
+            keyguardServiceLockNowInteractor = keyguardServiceLockNowInteractor,
         )
     }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceLockNowInteractor.kt
similarity index 68%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceLockNowInteractor.kt
index 5a04169..29335c5 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceLockNowInteractor.kt
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.systemui.keyguard.domain.interactor
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+
+val Kosmos.keyguardServiceLockNowInteractor by
+    Kosmos.Fixture { KeyguardServiceLockNowInteractor(backgroundScope = testScope) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt
index 63e168d..4aa132c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt
@@ -41,5 +41,7 @@
             lockPatternUtils,
             fakeSettings,
             selectedUserInteractor,
+            keyguardEnabledInteractor,
+            keyguardServiceLockNowInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
index b5e6f75..c0b39b1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import android.content.applicationContext
 import android.content.res.mainResources
 import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
@@ -28,12 +29,13 @@
 val Kosmos.keyguardClockViewModel by
     Kosmos.Fixture {
         KeyguardClockViewModel(
+            context = applicationContext,
             keyguardClockInteractor = keyguardClockInteractor,
             applicationScope = applicationCoroutineScope,
             aodNotificationIconViewModel = notificationIconContainerAlwaysOnDisplayViewModel,
             shadeInteractor = shadeInteractor,
             systemBarUtils = systemBarUtilsProxy,
             configurationInteractor = configurationInteractor,
-            resources = mainResources
+            resources = mainResources,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt
index a25b29fd..2311c0a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 
 val Kosmos.lockscreenUserActionsViewModel by Fixture {
@@ -27,5 +28,6 @@
         deviceEntryInteractor = deviceEntryInteractor,
         communalInteractor = communalInteractor,
         shadeInteractor = shadeInteractor,
+        occlusionInteractor = sceneContainerOcclusionInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
index 72cb1df..1556058 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
@@ -1,8 +1,12 @@
 package com.android.systemui.kosmos
 
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.FlowValue
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.settings.brightness.ui.BrightnessWarningToast
+import com.android.systemui.util.mockito.mock
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.test.StandardTestDispatcher
@@ -32,12 +36,15 @@
 fun Kosmos.useUnconfinedTestDispatcher() = apply { testDispatcher = UnconfinedTestDispatcher() }
 
 var Kosmos.testScope by Fixture { TestScope(testDispatcher) }
-var Kosmos.applicationCoroutineScope by Fixture { testScope.backgroundScope }
+var Kosmos.backgroundScope by Fixture { testScope.backgroundScope }
+var Kosmos.applicationCoroutineScope by Fixture { backgroundScope }
 var Kosmos.testCase: SysuiTestCase by Fixture()
 var Kosmos.backgroundCoroutineContext: CoroutineContext by Fixture {
-    testScope.backgroundScope.coroutineContext
+    backgroundScope.coroutineContext
 }
 var Kosmos.mainCoroutineContext: CoroutineContext by Fixture { testScope.coroutineContext }
+var Kosmos.brightnessWarningToast: BrightnessWarningToast by
+    Kosmos.Fixture { mock<BrightnessWarningToast>() }
 
 /**
  * Run this test body with a [Kosmos] as receiver, and using the [testScope] currently installed in
@@ -49,3 +56,5 @@
 fun Kosmos.runCurrent() = testScope.runCurrent()
 
 fun <T> Kosmos.collectLastValue(flow: Flow<T>) = testScope.collectLastValue(flow)
+
+fun <T> Kosmos.collectValues(flow: Flow<T>): FlowValue<List<T>> = testScope.collectValues(flow)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index 3d60abf..5b2c8dd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -78,6 +78,7 @@
 import com.android.systemui.statusbar.notification.domain.interactor.seenNotificationsInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
+import com.android.systemui.statusbar.phone.fakeAutoHideControllerStore
 import com.android.systemui.statusbar.phone.keyguardBypassController
 import com.android.systemui.statusbar.phone.scrimController
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepository
@@ -132,6 +133,7 @@
     val simBouncerInteractor by lazy { kosmos.simBouncerInteractor }
     val statusBarStateController by lazy { kosmos.statusBarStateController }
     val statusBarModePerDisplayRepository by lazy { kosmos.fakeStatusBarModePerDisplayRepository }
+    val autoHideControllerStore by lazy { kosmos.fakeAutoHideControllerStore }
     val interactionJankMonitor by lazy { kosmos.interactionJankMonitor }
     val fakeSceneContainerConfig by lazy { kosmos.sceneContainerConfig }
     val sceneInteractor by lazy { kosmos.sceneInteractor }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/FakeMediaProjectionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/FakeMediaProjectionRepository.kt
index d631f92..e6256a5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/FakeMediaProjectionRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/FakeMediaProjectionRepository.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.mediaprojection.data.repository
 
 import android.app.ActivityManager
+import android.media.projection.StopReason
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import kotlinx.coroutines.flow.MutableStateFlow
 
@@ -28,7 +29,7 @@
 
     var stopProjectingInvoked = false
 
-    override suspend fun stopProjecting() {
+    override suspend fun stopProjecting(@StopReason stopReason: Int) {
         stopProjectingInvoked = true
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeQSTile.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeQSTile.kt
index 562980d..06822a6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeQSTile.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeQSTile.kt
@@ -19,10 +19,12 @@
 import com.android.internal.logging.InstanceId
 import com.android.systemui.animation.Expandable
 import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.qs.TileDetailsViewModel
 
 class FakeQSTile(var user: Int, var available: Boolean = true) : QSTile {
     private var tileSpec: String? = null
     var destroyed = false
+    var hasDetailsViewModel: Boolean = true
     private var state = QSTile.State()
     val callbacks = mutableListOf<QSTile.Callback>()
 
@@ -91,6 +93,13 @@
         return false
     }
 
+    override fun getDetailsViewModel(): FakeTileDetailsViewModel? {
+        if (hasDetailsViewModel) {
+            return FakeTileDetailsViewModel(tileSpec)
+        }
+        return null
+    }
+
     fun changeState(newState: QSTile.State) {
         state = newState
         callbacks.forEach { it.onStateChanged(state) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsViewModel.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsViewModel.kt
new file mode 100644
index 0000000..555f019
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsViewModel.kt
@@ -0,0 +1,48 @@
+/*
+ * 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
+
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import com.android.systemui.plugins.qs.TileDetailsViewModel
+
+class FakeTileDetailsViewModel(var tileSpec: String?) : TileDetailsViewModel() {
+    private var _clickOnSettingsButton = 0
+
+    @Composable
+    override fun GetContentView() {
+        Text(
+            text = "Fake details content",
+            textAlign = TextAlign.Center,
+            fontWeight = FontWeight.ExtraBold,
+        )
+    }
+
+    override fun clickOnSettingsButton() {
+        _clickOnSettingsButton++
+    }
+
+    override fun getTitle(): String {
+        return tileSpec ?: " Fake title"
+    }
+
+    override fun getSubTitle(): String {
+        return tileSpec ?: "Fake sub title"
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
index 45d5b38..c574463 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
@@ -18,10 +18,12 @@
 
 import android.content.res.mainResources
 import androidx.lifecycle.LifecycleCoroutineScope
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
 import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.table.logcatTableLogBuffer
 import com.android.systemui.media.controls.ui.view.qqsMediaHost
 import com.android.systemui.media.controls.ui.view.qsMediaHost
 import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
@@ -57,7 +59,9 @@
                     configurationInteractor,
                     largeScreenHeaderHelper,
                     tileSquishinessInteractor,
+                    falsingInteractor,
                     inFirstPageViewModel,
+                    logcatTableLogBuffer(this@Fixture),
                     mediaInRowInLandscapeViewModelFactory,
                     qqsMediaHost,
                     qsMediaHost,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
index b5a6bf1..6fe860c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
@@ -19,12 +19,14 @@
 import com.android.systemui.haptics.msdl.tileHapticsViewModelFactoryProvider
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.InfiniteGridLayout
+import com.android.systemui.qs.panels.ui.viewmodel.detailsViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.iconTilesViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.infiniteGridViewModelFactory
 
 val Kosmos.infiniteGridLayout by
     Kosmos.Fixture {
         InfiniteGridLayout(
+            detailsViewModel,
             iconTilesViewModel,
             infiniteGridViewModelFactory,
             tileHapticsViewModelFactoryProvider,
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt
similarity index 69%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt
index 5a04169..dc22905 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.systemui.qs.panels.ui.viewmodel
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+
+val Kosmos.detailsViewModel by Kosmos.Fixture { DetailsViewModel(currentTilesInteractor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
new file mode 100644
index 0000000..b8d3ff4
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.viewmodel
+
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.editModeButtonViewModelFactory by
+    Kosmos.Fixture {
+        object : EditModeButtonViewModel.Factory {
+            override fun create(): EditModeButtonViewModel {
+                return EditModeButtonViewModel(editModeViewModel, falsingInteractor)
+            }
+        }
+    }
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 2e80293..5c71ba2 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
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs.panels.ui.viewmodel
 
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
 import com.android.systemui.development.ui.viewmodel.buildNumberViewModelFactory
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.qs.panels.domain.interactor.paginatedGridInteractor
@@ -28,5 +29,7 @@
             paginatedGridInteractor,
             inFirstPageViewModel,
             buildNumberViewModelFactory,
+            editModeButtonViewModelFactory,
+            falsingInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
index a908765..de9f629 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
@@ -18,6 +18,7 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.util.mockito.mock
 
 val Kosmos.qsTileViewModelAdaperFactory by
@@ -28,6 +29,7 @@
                     applicationCoroutineScope,
                     mock(),
                     qsTileViewModel,
+                    testDispatcher,
                 )
             }
         }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
index ce103ec..6afc0d80 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
@@ -18,6 +18,7 @@
 
 import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModelFactory
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.ui.viewmodel.detailsViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.quickQuickSettingsViewModelFactory
 import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
@@ -34,6 +35,7 @@
                     supportsBrightnessMirroring,
                     tileGridViewModel,
                     editModeViewModel,
+                    detailsViewModel,
                 )
             }
         }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/HeadsUpManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorKosmos.kt
similarity index 66%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/HeadsUpManagerKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorKosmos.kt
index a4db00c..12d4e90 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/HeadsUpManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorKosmos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy
+package com.android.systemui.scene.domain.interactor
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor
 
-var Kosmos.headsUpManager by Fixture { mock<HeadsUpManager>() }
+val Kosmos.disabledContentInteractor by Fixture {
+    DisabledContentInteractor(disableFlagsInteractor = disableFlagsInteractor)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
index f84c3bd..eb352ba 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
@@ -33,5 +33,6 @@
             sceneFamilyResolvers = { sceneFamilyResolvers },
             deviceUnlockedInteractor = { deviceUnlockedInteractor },
             keyguardEnabledInteractor = { keyguardEnabledInteractor },
+            disabledContentInteractor = disabledContentInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
index 7e6a727..82b5f63 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
@@ -37,6 +37,7 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.model.sysUiState
 import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.disabledContentInteractor
 import com.android.systemui.scene.domain.interactor.sceneBackInteractor
 import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -83,5 +84,6 @@
         alternateBouncerInteractor = alternateBouncerInteractor,
         vibratorHelper = vibratorHelper,
         msdlPlayer = msdlPlayer,
+        disabledContentInteractor = disabledContentInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryKosmos.kt
new file mode 100644
index 0000000..dbaa0b1
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryKosmos.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.data.repository
+
+import android.view.Display
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shade.display.ShadeDisplayPolicy
+import com.android.systemui.shade.display.SpecificDisplayIdPolicy
+
+val Kosmos.defaultShadeDisplayPolicy: ShadeDisplayPolicy by
+    Kosmos.Fixture { SpecificDisplayIdPolicy(Display.DEFAULT_DISPLAY) }
+
+val Kosmos.shadeDisplaysRepository: MutableShadeDisplaysRepository by
+    Kosmos.Fixture {
+        ShadeDisplaysRepositoryImpl(
+            defaultPolicy = defaultShadeDisplayPolicy,
+            bgScope = testScope.backgroundScope,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt
index 7097d31..694bb6e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModelFactory
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor
 import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
 
 val Kosmos.shadeSceneContentViewModel: ShadeSceneContentViewModel by Fixture {
@@ -35,6 +36,7 @@
         brightnessMirrorViewModelFactory = brightnessMirrorViewModelFactory,
         mediaCarouselInteractor = mediaCarouselInteractor,
         shadeInteractor = shadeInteractor,
+        disableFlagsInteractor = disableFlagsInteractor,
         footerActionsViewModelFactory = footerActionsViewModelFactory,
         footerActionsController = footerActionsController,
         unfoldTransitionInteractor = unfoldTransitionInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorFactoryKosmos.kt
new file mode 100644
index 0000000..1c095e1
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorFactoryKosmos.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.chips.notification.domain.interactor
+
+import com.android.systemui.activity.data.repository.activityManagerRepository
+import com.android.systemui.activity.data.repository.fake
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
+
+val Kosmos.singleNotificationChipInteractorFactory: SingleNotificationChipInteractor.Factory by
+    Kosmos.Fixture {
+        SingleNotificationChipInteractor.Factory { startingModel ->
+            SingleNotificationChipInteractor(
+                startingModel,
+                activityManagerRepository.fake,
+                logBuffer = statusBarChipsLogger,
+            )
+        }
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorKosmos.kt
index 74c7611..03e9f3d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorKosmos.kt
@@ -17,6 +17,16 @@
 package com.android.systemui.statusbar.chips.notification.domain.interactor
 
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
+import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
 
 val Kosmos.statusBarNotificationChipsInteractor: StatusBarNotificationChipsInteractor by
-    Kosmos.Fixture { StatusBarNotificationChipsInteractor() }
+    Kosmos.Fixture {
+        StatusBarNotificationChipsInteractor(
+            testScope.backgroundScope,
+            activeNotificationsInteractor,
+            singleNotificationChipInteractorFactory,
+            logBuffer = statusBarChipsLogger,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
index 68b28ad..4bcce86 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
@@ -19,13 +19,8 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
-import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
 
 val Kosmos.notifChipsViewModel: NotifChipsViewModel by
     Kosmos.Fixture {
-        NotifChipsViewModel(
-            applicationCoroutineScope,
-            activeNotificationsInteractor,
-            statusBarNotificationChipsInteractor,
-        )
+        NotifChipsViewModel(applicationCoroutineScope, statusBarNotificationChipsInteractor)
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarOrchestratorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarOrchestratorFactory.kt
index 9197dcd..2d88ae8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarOrchestratorFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarOrchestratorFactory.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.core
 
 import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository
+import com.android.systemui.statusbar.phone.AutoHideController
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.statusbar.window.data.repository.StatusBarWindowStatePerDisplayRepository
 import kotlinx.coroutines.CoroutineScope
@@ -36,6 +37,7 @@
         statusBarModeRepository: StatusBarModePerDisplayRepository,
         statusBarInitializer: StatusBarInitializer,
         statusBarWindowController: StatusBarWindowController,
+        autoHideController: AutoHideController,
     ): StatusBarOrchestrator =
         mock<StatusBarOrchestrator>().also { createdOrchestrators[displayId] = it }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
index 28edae7..8c37bd7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.statusbar.data.repository.statusBarModeRepository
 import com.android.systemui.statusbar.mockNotificationRemoteInputManager
 import com.android.systemui.statusbar.phone.mockAutoHideController
+import com.android.systemui.statusbar.phone.multiDisplayAutoHideControllerStore
 import com.android.systemui.statusbar.window.data.repository.fakeStatusBarWindowStatePerDisplayRepository
 import com.android.systemui.statusbar.window.data.repository.statusBarWindowStateRepositoryStore
 import com.android.systemui.statusbar.window.fakeStatusBarWindowController
@@ -50,9 +51,9 @@
             fakeStatusBarInitializer,
             fakeStatusBarWindowController,
             applicationCoroutineScope.coroutineContext,
+            mockAutoHideController,
             mockDemoModeController,
             mockPluginDependencyProvider,
-            mockAutoHideController,
             mockNotificationRemoteInputManager,
             { mockNotificationShadeWindowViewController },
             mockShadeSurface,
@@ -80,6 +81,7 @@
             statusBarInitializerStore,
             statusBarWindowControllerStore,
             statusBarInitializerStore,
+            multiDisplayAutoHideControllerStore,
             privacyDotWindowControllerStore,
             lightBarControllerStore,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeHeadsUpRowRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeHeadsUpRowRepository.kt
index 980d65f..7de22d8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeHeadsUpRowRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeHeadsUpRowRepository.kt
@@ -16,13 +16,27 @@
 
 package com.android.systemui.statusbar.notification.data.repository
 
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import kotlinx.coroutines.flow.MutableStateFlow
 
 class FakeHeadsUpRowRepository(override val key: String, override val elementKey: Any = Any()) :
     HeadsUpRowRepository {
-    constructor(key: String, isPinned: Boolean) : this(key = key) {
-        this.isPinned.value = isPinned
+    constructor(
+        key: String,
+        elementKey: Any = Any(),
+        isPinned: Boolean,
+    ) : this(key = key, elementKey = elementKey) {
+        this.pinnedStatus.value = if (isPinned) PinnedStatus.PinnedBySystem else PinnedStatus.NotPinned
     }
 
-    override val isPinned: MutableStateFlow<Boolean> = MutableStateFlow(false)
+    constructor(
+        key: String,
+        elementKey: Any = Any(),
+        pinnedStatus: PinnedStatus,
+    ) : this(key = key, elementKey = elementKey) {
+        this.pinnedStatus.value = pinnedStatus
+    }
+
+    override val pinnedStatus: MutableStateFlow<PinnedStatus> =
+        MutableStateFlow(PinnedStatus.NotPinned)
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/HeadsUpManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerKosmos.kt
similarity index 92%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/HeadsUpManagerKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerKosmos.kt
index a4db00c..de9485d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/HeadsUpManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerKosmos.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy
+package com.android.systemui.statusbar.notification.headsup
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/FakePromotedNotificationsProvider.kt
similarity index 60%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/FakePromotedNotificationsProvider.kt
index 5a04169..88caf6e 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/FakePromotedNotificationsProvider.kt
@@ -14,8 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.systemui.statusbar.notification.promoted
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+
+class FakePromotedNotificationsProvider : PromotedNotificationsProvider {
+    val promotedEntries = mutableSetOf<NotificationEntry>()
+
+    override fun shouldPromote(entry: NotificationEntry): Boolean {
+        return promotedEntries.contains(entry)
+    }
 }
diff --git a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodConfigState.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
similarity index 61%
rename from ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodConfigState.java
rename to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
index 7d3d8b9..5e9f12b 100644
--- a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodConfigState.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
@@ -13,10 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.platform.test.ravenwood;
 
-/** Stub class. The actual implementation is in junit-impl-src. */
-public class RavenwoodConfigState {
-    public RavenwoodConfigState(RavenwoodConfig config) {
+package com.android.systemui.statusbar.notification.promoted
+
+import android.content.applicationContext
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.promotedNotificationContentExtractor by
+    Kosmos.Fixture {
+        PromotedNotificationContentExtractor(
+            promotedNotificationsProvider,
+            applicationContext,
+            promotedNotificationLogger,
+        )
     }
-}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLoggerKosmos.kt
similarity index 68%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLoggerKosmos.kt
index 5a04169..2805d1e 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLoggerKosmos.kt
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package com.android.systemui.statusbar.notification.promoted
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.logcatLogBuffer
+
+val Kosmos.promotedNotificationLogger by
+    Kosmos.Fixture { PromotedNotificationLogger(logcatLogBuffer("PromotedNotifLog")) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderKosmos.kt
index a7aa0b4..580f617 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderKosmos.kt
@@ -18,4 +18,5 @@
 
 import com.android.systemui.kosmos.Kosmos
 
-val Kosmos.promotedNotificationsProvider by Kosmos.Fixture { PromotedNotificationsProviderImpl() }
+var Kosmos.promotedNotificationsProvider: PromotedNotificationsProvider by
+    Kosmos.Fixture { PromotedNotificationsProviderImpl() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
index 31d3908..2d3f68f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.media.controls.util.MediaFeatureFlag
 import com.android.systemui.media.dialog.MediaOutputDialogManager
 import com.android.systemui.plugins.ActivityStarter
@@ -60,9 +61,13 @@
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.icon.IconBuilder
 import com.android.systemui.statusbar.notification.icon.IconManager
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationLogger
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationsProviderImpl
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.CoordinateOnClickListener
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.ExpandableNotificationRowLogger
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener
@@ -77,7 +82,6 @@
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil
-import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.SmartActionInflaterImpl
 import com.android.systemui.statusbar.policy.SmartReplyConstants
 import com.android.systemui.statusbar.policy.SmartReplyInflaterImpl
@@ -221,6 +225,17 @@
                 Mockito.mock(ConversationNotificationManager::class.java, STUB_ONLY),
             )
 
+        val promotedNotificationsProvider = PromotedNotificationsProviderImpl()
+        val promotedNotificationLog = logcatLogBuffer("PromotedNotifLog")
+        val promotedNotificationLogger = PromotedNotificationLogger(promotedNotificationLog)
+
+        val promotedNotificationContentExtractor =
+            PromotedNotificationContentExtractor(
+                promotedNotificationsProvider,
+                context,
+                promotedNotificationLogger,
+            )
+
         mContentBinder =
             if (NotificationRowContentBinderRefactor.isEnabled)
                 NotificationRowContentBinderImpl(
@@ -231,6 +246,7 @@
                     smartReplyStateInflater,
                     notifLayoutInflaterFactoryProvider,
                     Mockito.mock(HeadsUpStyleProvider::class.java, STUB_ONLY),
+                    promotedNotificationContentExtractor,
                     Mockito.mock(NotificationRowContentBinderLogger::class.java, STUB_ONLY),
                 )
             else
@@ -243,6 +259,7 @@
                     smartReplyStateInflater,
                     notifLayoutInflaterFactoryProvider,
                     Mockito.mock(HeadsUpStyleProvider::class.java, STUB_ONLY),
+                    promotedNotificationContentExtractor,
                     Mockito.mock(NotificationRowContentBinderLogger::class.java, STUB_ONLY),
                 )
         mContentBinder.setInflateSynchronously(true)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallbackKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallbackKosmos.kt
index 1e3897b..ec54c33 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallbackKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallbackKosmos.kt
@@ -22,7 +22,7 @@
 import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl
 import com.android.systemui.statusbar.notification.collection.notifCollection
 import com.android.systemui.statusbar.notification.collection.render.notificationVisibilityProvider
-import com.android.systemui.statusbar.policy.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.headsUpManager
 
 var Kosmos.onUserInteractionCallback: OnUserInteractionCallback by
     Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmKosmos.kt
index e20ce27..a5c4bfd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmKosmos.kt
@@ -18,7 +18,7 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.statusbar.policy.AvalancheController
+import com.android.systemui.statusbar.notification.headsup.AvalancheController
 import com.android.systemui.util.mockito.mock
 
 var Kosmos.stackScrollAlgorithmSectionProvider by Fixture {
@@ -29,6 +29,4 @@
     mock<StackScrollAlgorithm.BypassController>()
 }
 
-var Kosmos.avalancheController by Fixture {
-    mock<AvalancheController>()
-}
+var Kosmos.avalancheController by Fixture { mock<AvalancheController>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
index 9c3f510..e972c2c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
-import com.android.systemui.statusbar.policy.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.headsUpManager
 
 val Kosmos.windowRootViewVisibilityInteractor by Fixture {
     WindowRootViewVisibilityInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt
index 090ce31..b99e93a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt
@@ -16,9 +16,49 @@
 
 package com.android.systemui.statusbar.phone
 
+import android.content.Context
+import android.os.Handler
+import android.view.Display
+import android.view.IWindowManager
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.display.data.repository.fakeDisplayWindowPropertiesRepository
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.kosmos.applicationCoroutineScope
+import org.mockito.Mockito.mock
 
-val Kosmos.mockAutoHideController by Kosmos.Fixture { mock<AutoHideController>() }
+val Kosmos.mockAutoHideController: AutoHideController by
+    Kosmos.Fixture { mock(AutoHideController::class.java) }
 
-var Kosmos.autoHideController by Kosmos.Fixture { mockAutoHideController }
+val Kosmos.fakeAutoHideControllerFactory by Kosmos.Fixture { FakeAutoHideControllerFactory() }
+
+val Kosmos.multiDisplayAutoHideControllerStore by
+    Kosmos.Fixture {
+        MultiDisplayAutoHideControllerStore(
+            applicationCoroutineScope,
+            displayRepository,
+            fakeDisplayWindowPropertiesRepository,
+            fakeAutoHideControllerFactory,
+        )
+    }
+
+val Kosmos.fakeAutoHideControllerStore by Kosmos.Fixture { FakeAutoHideControllerStore() }
+
+class FakeAutoHideControllerFactory :
+    AutoHideControllerImpl.Factory(mock(Handler::class.java), mock(IWindowManager::class.java)) {
+
+    override fun create(context: Context): AutoHideControllerImpl {
+        return mock(AutoHideControllerImpl::class.java)
+    }
+}
+
+class FakeAutoHideControllerStore : AutoHideControllerStore {
+
+    private val perDisplayMocks = mutableMapOf<Int, AutoHideController>()
+
+    override val defaultDisplay: AutoHideController
+        get() = forDisplay(Display.DEFAULT_DISPLAY)
+
+    override fun forDisplay(displayId: Int): AutoHideController {
+        return perDisplayMocks.computeIfAbsent(displayId) { mock(AutoHideController::class.java) }
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt
index 4a6757d..f86824a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt
@@ -26,10 +26,10 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.plugins.statusbar.statusBarStateController
 import com.android.systemui.shade.domain.interactor.shadeLockscreenInteractor
+import com.android.systemui.statusbar.notification.headsup.headsUpManager
 import com.android.systemui.statusbar.notificationShadeWindowController
 import com.android.systemui.statusbar.policy.batteryController
 import com.android.systemui.statusbar.policy.deviceProvisionedController
-import com.android.systemui.statusbar.policy.headsUpManager
 import com.android.systemui.statusbar.pulseExpansionHandler
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerKosmos.kt
similarity index 91%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerKosmos.kt
index 87ea147..5b7f23b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerKosmos.kt
@@ -24,16 +24,15 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.notification.headsup.headsUpManager
 import com.android.systemui.statusbar.notificationShadeWindowController
 import com.android.systemui.statusbar.policy.configurationController
-import com.android.systemui.statusbar.policy.headsUpManager
 import com.android.systemui.util.kotlin.JavaAdapter
 import com.android.systemui.util.mockito.mock
-import org.mockito.Mockito.mock
 
-var Kosmos.statusBarTouchableRegionManager by
+var Kosmos.shadeTouchableRegionManager by
     Kosmos.Fixture {
-        StatusBarTouchableRegionManager(
+        ShadeTouchableRegionManager(
             applicationContext,
             notificationShadeWindowController,
             configurationController,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt
index c6684af..6083414 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.statusbar.commandQueue
 import com.android.systemui.statusbar.notification.collection.provider.launchFullScreenIntentProvider
 import com.android.systemui.statusbar.notification.collection.render.notificationVisibilityProvider
+import com.android.systemui.statusbar.notification.headsup.headsUpManager
 import com.android.systemui.statusbar.notification.notificationTransitionAnimatorControllerProvider
 import com.android.systemui.statusbar.notification.row.onUserInteractionCallback
 import com.android.systemui.statusbar.notificationClickNotifier
@@ -43,7 +44,6 @@
 import com.android.systemui.statusbar.notificationPresenter
 import com.android.systemui.statusbar.notificationRemoteInputManager
 import com.android.systemui.statusbar.notificationShadeWindowController
-import com.android.systemui.statusbar.policy.headsUpManager
 import com.android.systemui.statusbar.policy.keyguardStateController
 import com.android.systemui.wmshell.bubblesManager
 import java.util.Optional
diff --git a/packages/Vcn/service-b/Android.bp b/packages/Vcn/service-b/Android.bp
index a462297..03ef4e6 100644
--- a/packages/Vcn/service-b/Android.bp
+++ b/packages/Vcn/service-b/Android.bp
@@ -19,6 +19,19 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+filegroup {
+    name: "vcn-location-sources",
+    srcs: select(release_flag("RELEASE_MOVE_VCN_TO_MAINLINE"), {
+        true: [
+            "vcn-location-flag/module/com/android/server/vcn/VcnLocation.java",
+        ],
+        default: [
+            "vcn-location-flag/platform/com/android/server/vcn/VcnLocation.java",
+        ],
+    }),
+    visibility: ["//frameworks/base/services/core"],
+}
+
 java_library {
     name: "service-connectivity-b-pre-jarjar",
     sdk_version: "system_server_current",
diff --git a/packages/Vcn/service-b/vcn-location-flag/module/com/android/server/vcn/VcnLocation.java b/packages/Vcn/service-b/vcn-location-flag/module/com/android/server/vcn/VcnLocation.java
new file mode 100644
index 0000000..6c7d24d
--- /dev/null
+++ b/packages/Vcn/service-b/vcn-location-flag/module/com/android/server/vcn/VcnLocation.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vcn;
+
+/**
+ * Class to represent that VCN is in a mainline module
+ *
+ * <p>This class is used to check whether VCN is in the non-updatable platform or in a mainline
+ * module.
+ */
+// When VCN is in a mainline module, this class (module/com/android/server/vcn/VcnLocation.java)
+// will be built in to the vcn-location-sources filegroup. When VCN is in the non-updatable
+// platform, platform/com/android/server/vcn/VcnLocation.java will be built in to the filegroup
+public class VcnLocation {
+    /** Indicate that VCN is the platform */
+    public static final boolean IS_VCN_IN_MAINLINE = true;
+}
diff --git a/packages/Vcn/service-b/vcn-location-flag/platform/com/android/server/vcn/VcnLocation.java b/packages/Vcn/service-b/vcn-location-flag/platform/com/android/server/vcn/VcnLocation.java
new file mode 100644
index 0000000..c6c82a5
--- /dev/null
+++ b/packages/Vcn/service-b/vcn-location-flag/platform/com/android/server/vcn/VcnLocation.java
@@ -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.server.vcn;
+
+/**
+ * Class to represent that VCN is in the platform
+ *
+ * <p>This class is used to check whether VCN is in the non-updatable platform or in a mainline
+ * module.
+ */
+// When VCN is in a mainline module, module/com/android/server/vcn/VcnLocation.java
+// will be built in to the vcn-location-sources filegroup. When VCN is in the non-updatable
+// platform, this class (platform/com/android/server/vcn/VcnLocation.java) will be built in to the
+// filegroup
+public class VcnLocation {
+    /** Indicate that VCN is the platform */
+    public static final boolean IS_VCN_IN_MAINLINE = false;
+}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
index 9b71f80..de3c5f2 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -133,9 +133,6 @@
 
         Log.v(TAG, "RavenwoodAwareTestRunner starting for " + testClass.getCanonicalName());
 
-        // This is needed to make AndroidJUnit4ClassRunner happy.
-        InstrumentationRegistry.registerInstance(null, Bundle.EMPTY);
-
         // Hook point to allow more customization.
         runAnnotatedMethodsOnRavenwood(RavenwoodTestRunnerInitializing.class, null);
 
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodConfigState.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodConfigState.java
deleted file mode 100644
index 870a10a..0000000
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodConfigState.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.platform.test.ravenwood;
-
-import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_EMPTY_RESOURCES_APK;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.annotation.Nullable;
-import android.app.ResourcesManager;
-import android.content.res.Resources;
-import android.view.DisplayAdjustments;
-
-import java.io.File;
-import java.util.HashMap;
-
-/**
- * Used to store various states associated with {@link RavenwoodConfig} that's inly needed
- * in junit-impl.
- *
- * We don't want to put it in junit-src to avoid having to recompile all the downstream
- * dependencies after changing this class.
- *
- * All members must be called from the runner's main thread.
- */
-public class RavenwoodConfigState {
-    private static final String TAG = "RavenwoodConfigState";
-
-    private final RavenwoodConfig mConfig;
-
-    // TODO: Move the other contexts from RavenwoodConfig to here too? They're used by
-    // RavenwoodRule too, but RavenwoodRule can probably use InstrumentationRegistry?
-    RavenwoodContext mSystemServerContext;
-
-    public RavenwoodConfigState(RavenwoodConfig config) {
-        mConfig = config;
-    }
-
-    /** Map from path -> resources. */
-    private final HashMap<File, Resources> mCachedResources = new HashMap<>();
-
-    /**
-     * Load {@link Resources} from an APK, with cache.
-     */
-    public Resources loadResources(@Nullable File apkPath) {
-        var cached = mCachedResources.get(apkPath);
-        if (cached != null) {
-            return cached;
-        }
-
-        var fileToLoad = apkPath != null ? apkPath : new File(RAVENWOOD_EMPTY_RESOURCES_APK);
-
-        assertTrue("File " + fileToLoad + " doesn't exist.", fileToLoad.isFile());
-
-        final String path = fileToLoad.getAbsolutePath();
-        final var emptyPaths = new String[0];
-
-        ResourcesManager.getInstance().initializeApplicationPaths(path, emptyPaths);
-
-        final var ret = ResourcesManager.getInstance().getResources(null, path,
-                emptyPaths, emptyPaths, emptyPaths,
-                emptyPaths, null, null,
-                new DisplayAdjustments().getCompatibilityInfo(),
-                RavenwoodRuntimeEnvironmentController.class.getClassLoader(), null);
-
-        assertNotNull(ret);
-
-        mCachedResources.put(apkPath, ret);
-        return ret;
-    }
-}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
index ec00e8f..6dfcf4ce 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
@@ -15,24 +15,23 @@
  */
 package android.platform.test.ravenwood;
 
-import static com.android.ravenwood.common.RavenwoodCommonUtils.ensureIsPublicMember;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-import static org.junit.Assert.fail;
-
-import android.annotation.Nullable;
 import android.util.Log;
+import android.util.Pair;
 
-import com.android.ravenwood.common.RavenwoodRuntimeException;
+import com.android.ravenwood.RavenwoodRuntimeNative;
 
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 
-import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
 
 /**
- * Used to store various states associated with the current test runner that's inly needed
+ * Used to store various states associated with the current test runner that's only needed
  * in junit-impl.
  *
  * We don't want to put it in junit-src to avoid having to recompile all the downstream
@@ -42,6 +41,11 @@
  */
 public final class RavenwoodRunnerState {
     private static final String TAG = "RavenwoodRunnerState";
+    private static final String RAVENWOOD_RULE_ERROR =
+            "RavenwoodRule(s) are not executed in the correct order";
+
+    private static final List<Pair<RavenwoodRule, RavenwoodPropertyState>> sActiveProperties =
+            new ArrayList<>();
 
     private final RavenwoodAwareTestRunner mRunner;
 
@@ -52,207 +56,95 @@
         mRunner = runner;
     }
 
-    /**
-     * The RavenwoodConfig used to configure the current Ravenwood environment.
-     * This can either come from mConfig or mRule.
-     */
-    private RavenwoodConfig mCurrentConfig;
-    /**
-     * The RavenwoodConfig declared in the test class
-     */
-    private RavenwoodConfig mConfig;
-    /**
-     * The RavenwoodRule currently in effect, declared in the test class
-     */
-    private RavenwoodRule mRule;
-    private boolean mHasRavenwoodRule;
     private Description mMethodDescription;
 
-    public RavenwoodConfig getConfig() {
-        return mCurrentConfig;
-    }
-
     public void enterTestRunner() {
         Log.i(TAG, "enterTestRunner: " + mRunner);
-
-        mHasRavenwoodRule = hasRavenwoodRule(mRunner.mTestJavaClass);
-        mConfig = extractConfiguration(mRunner.mTestJavaClass);
-
-        if (mConfig != null) {
-            if (mHasRavenwoodRule) {
-                fail("RavenwoodConfig and RavenwoodRule cannot be used in the same class."
-                        + " Suggest migrating to RavenwoodConfig.");
-            }
-            mCurrentConfig = mConfig;
-        } else if (!mHasRavenwoodRule) {
-            // If no RavenwoodConfig and no RavenwoodRule, use a default config
-            mCurrentConfig = new RavenwoodConfig.Builder().build();
-        }
-
-        if (mCurrentConfig != null) {
-            RavenwoodRuntimeEnvironmentController.init(mRunner);
-        }
+        RavenwoodRuntimeEnvironmentController.initForRunner();
     }
 
     public void enterTestClass() {
         Log.i(TAG, "enterTestClass: " + mRunner.mTestJavaClass.getName());
-
-        if (mCurrentConfig != null) {
-            RavenwoodRuntimeEnvironmentController.init(mRunner);
-        }
     }
 
     public void exitTestClass() {
         Log.i(TAG, "exitTestClass: " + mRunner.mTestJavaClass.getName());
-        try {
-            if (mCurrentConfig != null) {
-                RavenwoodRuntimeEnvironmentController.reset();
-            }
-        } finally {
-            mConfig = null;
-            mRule = null;
-        }
+        assertTrue(RAVENWOOD_RULE_ERROR, sActiveProperties.isEmpty());
+        RavenwoodRuntimeEnvironmentController.exitTestClass();
     }
 
     public void enterTestMethod(Description description) {
         mMethodDescription = description;
+        RavenwoodRuntimeEnvironmentController.initForMethod();
     }
 
     public void exitTestMethod() {
         mMethodDescription = null;
-        RavenwoodRuntimeEnvironmentController.reinit();
     }
 
     public void enterRavenwoodRule(RavenwoodRule rule) {
-        if (!mHasRavenwoodRule) {
-            fail("If you have a RavenwoodRule in your test, make sure the field type is"
-                    + " RavenwoodRule so Ravenwood can detect it.");
-        }
-        if (mRule != null) {
-            fail("Multiple nesting RavenwoodRule's are detected in the same class,"
-                    + " which is not supported.");
-        }
-        mRule = rule;
-        if (mCurrentConfig == null) {
-            mCurrentConfig = rule.getConfiguration();
-        }
-        RavenwoodRuntimeEnvironmentController.init(mRunner);
+        pushTestProperties(rule);
     }
 
     public void exitRavenwoodRule(RavenwoodRule rule) {
-        if (mRule != rule) {
-            fail("RavenwoodRule did not take effect.");
-        }
-        mRule = null;
+        popTestProperties(rule);
     }
 
-    /**
-     * @return a configuration from a test class, if any.
-     */
-    @Nullable
-    private static RavenwoodConfig extractConfiguration(Class<?> testClass) {
-        var field = findConfigurationField(testClass);
-        if (field == null) {
-            return null;
+    static class RavenwoodPropertyState {
+
+        final List<Pair<String, String>> mBackup;
+        final Set<String> mKeyReadable;
+        final Set<String> mKeyWritable;
+
+        RavenwoodPropertyState(RavenwoodTestProperties props) {
+            mBackup = props.mValues.keySet().stream()
+                    .map(key -> Pair.create(key, RavenwoodRuntimeNative.getSystemProperty(key)))
+                    .toList();
+            mKeyReadable = Set.copyOf(props.mKeyReadable);
+            mKeyWritable = Set.copyOf(props.mKeyWritable);
         }
 
-        try {
-            return (RavenwoodConfig) field.get(null);
-        } catch (IllegalAccessException e) {
-            throw new RavenwoodRuntimeException("Failed to fetch from the configuration field", e);
+        boolean isKeyAccessible(String key, boolean write) {
+            return write ? mKeyWritable.contains(key) : mKeyReadable.contains(key);
         }
-    }
 
-    /**
-     * @return true if the current target class (or its super classes) has any @Rule / @ClassRule
-     * fields of type RavenwoodRule.
-     *
-     * Note, this check won't detect cases where a Rule is of type
-     * {@link TestRule} and still be a {@link RavenwoodRule}. But that'll be detected at runtime
-     * as a failure, in {@link #enterRavenwoodRule}.
-     */
-    private static boolean hasRavenwoodRule(Class<?> testClass) {
-        for (var field : testClass.getDeclaredFields()) {
-            if (!field.isAnnotationPresent(Rule.class)
-                    && !field.isAnnotationPresent(ClassRule.class)) {
-                continue;
-            }
-            if (field.getType().equals(RavenwoodRule.class)) {
-                return true;
-            }
-        }
-        // JUnit supports rules as methods, so we need to check them too.
-        for (var method : testClass.getDeclaredMethods()) {
-            if (!method.isAnnotationPresent(Rule.class)
-                    && !method.isAnnotationPresent(ClassRule.class)) {
-                continue;
-            }
-            if (method.getReturnType().equals(RavenwoodRule.class)) {
-                return true;
-            }
-        }
-        // Look into the super class.
-        if (!testClass.getSuperclass().equals(Object.class)) {
-            return hasRavenwoodRule(testClass.getSuperclass());
-        }
-        return false;
-    }
-
-    /**
-     * Find and return a field with @RavenwoodConfig.Config, which must be of type
-     * RavenwoodConfig.
-     */
-    @Nullable
-    private static Field findConfigurationField(Class<?> testClass) {
-        Field foundField = null;
-
-        for (var field : testClass.getDeclaredFields()) {
-            final var hasAnot = field.isAnnotationPresent(RavenwoodConfig.Config.class);
-            final var isType = field.getType().equals(RavenwoodConfig.class);
-
-            if (hasAnot) {
-                if (isType) {
-                    // Good, use this field.
-                    if (foundField != null) {
-                        fail(String.format(
-                                "Class %s has multiple fields with %s",
-                                testClass.getCanonicalName(),
-                                "@RavenwoodConfig.Config"));
-                    }
-                    // Make sure it's static public
-                    ensureIsPublicMember(field, true);
-
-                    foundField = field;
+        void restore() {
+            mBackup.forEach(pair -> {
+                if (pair.second == null) {
+                    RavenwoodRuntimeNative.removeSystemProperty(pair.first);
                 } else {
-                    fail(String.format(
-                            "Field %s.%s has %s but type is not %s",
-                            testClass.getCanonicalName(),
-                            field.getName(),
-                            "@RavenwoodConfig.Config",
-                            "RavenwoodConfig"));
-                    return null; // unreachable
+                    RavenwoodRuntimeNative.setSystemProperty(pair.first, pair.second);
                 }
-            } else {
-                if (isType) {
-                    fail(String.format(
-                            "Field %s.%s does not have %s but type is %s",
-                            testClass.getCanonicalName(),
-                            field.getName(),
-                            "@RavenwoodConfig.Config",
-                            "RavenwoodConfig"));
-                    return null; // unreachable
-                } else {
-                    // Unrelated field, ignore.
-                    continue;
-                }
-            }
+            });
         }
-        if (foundField != null) {
-            return foundField;
+    }
+
+    private static void pushTestProperties(RavenwoodRule rule) {
+        sActiveProperties.add(Pair.create(rule, new RavenwoodPropertyState(rule.mProperties)));
+        rule.mProperties.mValues.forEach(RavenwoodRuntimeNative::setSystemProperty);
+    }
+
+    private static void popTestProperties(RavenwoodRule rule) {
+        var pair = sActiveProperties.removeLast();
+        assertNotNull(RAVENWOOD_RULE_ERROR, pair);
+        assertEquals(RAVENWOOD_RULE_ERROR, rule, pair.first);
+        pair.second.restore();
+    }
+
+    @SuppressWarnings("unused")  // Called from native code (ravenwood_sysprop.cpp)
+    private static void checkSystemPropertyAccess(String key, boolean write) {
+        if (write && RavenwoodSystemProperties.sDefaultValues.containsKey(key)) {
+            // The default core values should never be modified
+            throw new IllegalArgumentException(
+                    "Setting core system property '" + key + "' is not allowed");
         }
-        if (!testClass.getSuperclass().equals(Object.class)) {
-            return findConfigurationField(testClass.getSuperclass());
+
+        final boolean result = RavenwoodSystemProperties.isKeyAccessible(key, write)
+                || sActiveProperties.stream().anyMatch(p -> p.second.isKeyAccessible(key, write));
+
+        if (!result) {
+            throw new IllegalArgumentException((write ? "Write" : "Read")
+                    + " access to system property '" + key + "' denied via RavenwoodRule");
         }
-        return null;
     }
 }
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index 1c1f157..e730a29 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -16,8 +16,11 @@
 
 package android.platform.test.ravenwood;
 
+import static android.os.Process.FIRST_APPLICATION_UID;
+import static android.os.UserHandle.SYSTEM;
 import static android.platform.test.ravenwood.RavenwoodSystemServer.ANDROID_PACKAGE_NAME;
 
+import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_EMPTY_RESOURCES_APK;
 import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_INST_RESOURCE_APK;
 import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
 import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
@@ -25,7 +28,9 @@
 import static com.android.ravenwood.common.RavenwoodCommonUtils.parseNullableInt;
 import static com.android.ravenwood.common.RavenwoodCommonUtils.withDefault;
 
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
@@ -53,6 +58,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.Log;
+import android.view.DisplayAdjustments;
 
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -62,19 +68,21 @@
 import com.android.ravenwood.RavenwoodRuntimeNative;
 import com.android.ravenwood.RavenwoodRuntimeState;
 import com.android.ravenwood.common.RavenwoodCommonUtils;
-import com.android.ravenwood.common.RavenwoodRuntimeException;
 import com.android.ravenwood.common.SneakyThrow;
 import com.android.server.LocalServices;
 import com.android.server.compat.PlatformCompat;
 
+import org.junit.internal.management.ManagementFactory;
 import org.junit.runner.Description;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
@@ -84,8 +92,7 @@
 import java.util.function.Supplier;
 
 /**
- * Responsible for initializing and de-initializing the environment, according to a
- * {@link RavenwoodConfig}.
+ * Responsible for initializing and the environment.
  */
 public class RavenwoodRuntimeEnvironmentController {
     private static final String TAG = "RavenwoodRuntimeEnvironmentController";
@@ -112,8 +119,6 @@
 
     private static ScheduledFuture<?> sPendingTimeout;
 
-    private static long sOriginalIdentityToken = -1;
-
     /**
      * When enabled, attempt to detect uncaught exceptions from background threads.
      */
@@ -146,6 +151,10 @@
         return res;
     }
 
+    /** Map from path -> resources. */
+    private static final HashMap<File, Resources> sCachedResources = new HashMap<>();
+    private static Set<String> sAdoptedPermissions = Collections.emptySet();
+
     private static final Object sInitializationLock = new Object();
 
     @GuardedBy("sInitializationLock")
@@ -154,15 +163,16 @@
     @GuardedBy("sInitializationLock")
     private static Throwable sExceptionFromGlobalInit;
 
-    private static RavenwoodAwareTestRunner sRunner;
-    private static RavenwoodSystemProperties sProps;
-
     private static final int DEFAULT_TARGET_SDK_LEVEL = VERSION_CODES.CUR_DEVELOPMENT;
     private static final String DEFAULT_PACKAGE_NAME = "com.android.ravenwoodtests.defaultname";
 
+    private static final int sMyPid = new Random().nextInt(100, 32768);
     private static int sTargetSdkLevel;
     private static String sTestPackageName;
     private static String sTargetPackageName;
+    private static Instrumentation sInstrumentation;
+    private static final long sCallingIdentity =
+            packBinderIdentityToken(false, FIRST_APPLICATION_UID, sMyPid);
 
     /**
      * Initialize the global environment.
@@ -181,7 +191,7 @@
                     Log.e(TAG, "globalInit() failed", th);
 
                     sExceptionFromGlobalInit = th;
-                    throw th;
+                    SneakyThrow.sneakyThrow(th);
                 }
             } else {
                 // Subsequent calls. If the first call threw, just throw the same error, to prevent
@@ -196,14 +206,19 @@
         }
     }
 
-    private static void globalInitInner() {
+    private static void globalInitInner() throws IOException {
         if (RAVENWOOD_VERBOSE_LOGGING) {
             Log.v(TAG, "globalInit() called here...", new RuntimeException("NOT A CRASH"));
         }
+        if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
+            Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
+        }
 
         // Some process-wide initialization. (maybe redirect stdout/stderr)
         RavenwoodCommonUtils.loadJniLibrary(LIBRAVENWOOD_INITIALIZER_NAME);
 
+        dumpCommandLineArgs();
+
         // We haven't initialized liblog yet, so directly write to System.out here.
         RavenwoodCommonUtils.log(TAG, "globalInitInner()");
 
@@ -217,7 +232,6 @@
 
         // Do the basic set up for the android sysprops.
         RavenwoodSystemProperties.initialize();
-        setSystemProperties(null);
 
         // Do this after loading RAVENWOOD_NATIVE_RUNTIME_NAME (which backs Os.setenv()),
         // before loadFrameworkNativeCode() (which uses $ANDROID_LOG_TAGS).
@@ -248,6 +262,74 @@
         loadRavenwoodProperties();
 
         assertMockitoVersion();
+
+        Log.i(TAG, "TargetPackageName=" + sTargetPackageName);
+        Log.i(TAG, "TestPackageName=" + sTestPackageName);
+        Log.i(TAG, "TargetSdkLevel=" + sTargetSdkLevel);
+
+        RavenwoodRuntimeState.sUid = FIRST_APPLICATION_UID;
+        RavenwoodRuntimeState.sPid = sMyPid;
+        RavenwoodRuntimeState.sTargetSdkLevel = sTargetSdkLevel;
+
+        ServiceManager.init$ravenwood();
+        LocalServices.removeAllServicesForTest();
+
+        ActivityManager.init$ravenwood(SYSTEM.getIdentifier());
+
+        final var main = new HandlerThread(MAIN_THREAD_NAME);
+        main.start();
+        Looper.setMainLooperForTest(main.getLooper());
+
+        final boolean isSelfInstrumenting =
+                Objects.equals(sTestPackageName, sTargetPackageName);
+
+        // This will load the resources from the apk set to `resource_apk` in the build file.
+        // This is supposed to be the "target app"'s resources.
+        final Supplier<Resources> targetResourcesLoader = () -> {
+            var file = new File(RAVENWOOD_RESOURCE_APK);
+            return loadResources(file.exists() ? file : null);
+        };
+
+        // Set up test context's (== instrumentation context's) resources.
+        // If the target package name == test package name, then we use the main resources.
+        final Supplier<Resources> instResourcesLoader;
+        if (isSelfInstrumenting) {
+            instResourcesLoader = targetResourcesLoader;
+        } else {
+            instResourcesLoader = () -> {
+                var file = new File(RAVENWOOD_INST_RESOURCE_APK);
+                return loadResources(file.exists() ? file : null);
+            };
+        }
+
+        var instContext = new RavenwoodContext(
+                sTestPackageName, main, instResourcesLoader);
+        var targetContext = new RavenwoodContext(
+                sTargetPackageName, main, targetResourcesLoader);
+
+        // Set up app context.
+        var appContext = new RavenwoodContext(sTargetPackageName, main, targetResourcesLoader);
+        appContext.setApplicationContext(appContext);
+        if (isSelfInstrumenting) {
+            instContext.setApplicationContext(appContext);
+            targetContext.setApplicationContext(appContext);
+        } else {
+            // When instrumenting into another APK, the test context doesn't have an app context.
+            targetContext.setApplicationContext(appContext);
+        }
+
+        final Supplier<Resources> systemResourcesLoader = () -> loadResources(null);
+
+        var systemServerContext =
+                new RavenwoodContext(ANDROID_PACKAGE_NAME, main, systemResourcesLoader);
+
+        sInstrumentation = new Instrumentation();
+        sInstrumentation.basicInit(instContext, targetContext, null);
+        InstrumentationRegistry.registerInstance(sInstrumentation, Bundle.EMPTY);
+
+        RavenwoodSystemServer.init(systemServerContext);
+
+        initializeCompatIds();
     }
 
     private static void loadRavenwoodProperties() {
@@ -262,134 +344,41 @@
     }
 
     /**
-     * Initialize the environment.
+     * Partially reset and initialize before each test class invocation
      */
-    public static void init(RavenwoodAwareTestRunner runner) {
-        if (RAVENWOOD_VERBOSE_LOGGING) {
-            Log.v(TAG, "init() called here: " + runner, new RuntimeException("STACKTRACE"));
-        }
-        if (sRunner == runner) {
-            return;
-        }
-        if (sRunner != null) {
-            reset();
-        }
-        sRunner = runner;
-        try {
-            initInner(runner.mState.getConfig());
-        } catch (Exception th) {
-            Log.e(TAG, "init() failed", th);
+    public static void initForRunner() {
+        var targetContext = sInstrumentation.getTargetContext();
+        var instContext = sInstrumentation.getContext();
+        // We need to recreate the mock UiAutomation for each test class, because sometimes tests
+        // will call Mockito.framework().clearInlineMocks() after execution.
+        sInstrumentation.basicInit(instContext, targetContext, createMockUiAutomation());
 
-            RavenwoodCommonUtils.runIgnoringException(()-> reset());
+        // Reset some global state
+        Process_ravenwood.reset();
+        DeviceConfig_host.reset();
+        Binder.restoreCallingIdentity(sCallingIdentity);
 
-            SneakyThrow.sneakyThrow(th);
-        }
-    }
-
-    private static void initInner(RavenwoodConfig config) throws IOException {
-        if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
-            maybeThrowPendingUncaughtException(false);
-            Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
-        }
-
-        config.mTargetPackageName = sTargetPackageName;
-        config.mTestPackageName = sTestPackageName;
-        config.mTargetSdkLevel = sTargetSdkLevel;
-
-        Log.i(TAG, "TargetPackageName=" + sTargetPackageName);
-        Log.i(TAG, "TestPackageName=" + sTestPackageName);
-        Log.i(TAG, "TargetSdkLevel=" + sTargetSdkLevel);
-
-        RavenwoodRuntimeState.sUid = config.mUid;
-        RavenwoodRuntimeState.sPid = config.mPid;
-        RavenwoodRuntimeState.sTargetSdkLevel = config.mTargetSdkLevel;
-        sOriginalIdentityToken = Binder.clearCallingIdentity();
-        reinit();
-        setSystemProperties(config.mSystemProperties);
-
-        ServiceManager.init$ravenwood();
-        LocalServices.removeAllServicesForTest();
-
-        ActivityManager.init$ravenwood(config.mCurrentUser);
-
-        final var main = new HandlerThread(MAIN_THREAD_NAME);
-        main.start();
-        Looper.setMainLooperForTest(main.getLooper());
-
-        final boolean isSelfInstrumenting =
-                Objects.equals(config.mTestPackageName, config.mTargetPackageName);
-
-        // This will load the resources from the apk set to `resource_apk` in the build file.
-        // This is supposed to be the "target app"'s resources.
-        final Supplier<Resources> targetResourcesLoader = () -> {
-            var file = new File(RAVENWOOD_RESOURCE_APK);
-            return config.mState.loadResources(file.exists() ? file : null);
-        };
-
-        // Set up test context's (== instrumentation context's) resources.
-        // If the target package name == test package name, then we use the main resources.
-        final Supplier<Resources> instResourcesLoader;
-        if (isSelfInstrumenting) {
-            instResourcesLoader = targetResourcesLoader;
-        } else {
-            instResourcesLoader = () -> {
-                var file = new File(RAVENWOOD_INST_RESOURCE_APK);
-                return config.mState.loadResources(file.exists() ? file : null);
-            };
-        }
-
-        var instContext = new RavenwoodContext(
-                config.mTestPackageName, main, instResourcesLoader);
-        var targetContext = new RavenwoodContext(
-                config.mTargetPackageName, main, targetResourcesLoader);
-
-        // Set up app context.
-        var appContext = new RavenwoodContext(
-                config.mTargetPackageName, main, targetResourcesLoader);
-        appContext.setApplicationContext(appContext);
-        if (isSelfInstrumenting) {
-            instContext.setApplicationContext(appContext);
-            targetContext.setApplicationContext(appContext);
-        } else {
-            // When instrumenting into another APK, the test context doesn't have an app context.
-            targetContext.setApplicationContext(appContext);
-        }
-        config.mInstContext = instContext;
-        config.mTargetContext = targetContext;
-
-        final Supplier<Resources> systemResourcesLoader = () -> config.mState.loadResources(null);
-
-        config.mState.mSystemServerContext =
-                new RavenwoodContext(ANDROID_PACKAGE_NAME, main, systemResourcesLoader);
-
-        // Prepare other fields.
-        config.mInstrumentation = new Instrumentation();
-        config.mInstrumentation.basicInit(instContext, targetContext, createMockUiAutomation());
-        InstrumentationRegistry.registerInstance(config.mInstrumentation, Bundle.EMPTY);
-
-        RavenwoodSystemServer.init(config);
-
-        initializeCompatIds(config);
+        SystemProperties.clearChangeCallbacksForTest();
 
         if (ENABLE_TIMEOUT_STACKS) {
             sPendingTimeout = sTimeoutExecutor.schedule(
                     RavenwoodRuntimeEnvironmentController::dumpStacks,
                     TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
         }
-    }
-
-    /**
-     * Partially re-initialize after each test method invocation
-     */
-    public static void reinit() {
-        // sRunner could be null, if there was a failure in the initialization.
-        if (sRunner != null) {
-            var config = sRunner.mState.getConfig();
-            Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid));
+        if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
+            maybeThrowPendingUncaughtException(false);
         }
     }
 
-    private static void initializeCompatIds(RavenwoodConfig config) {
+    /**
+     * Partially reset and initialize before each test method invocation
+     */
+    public static void initForMethod() {
+        // TODO(b/375272444): this is a hacky workaround to ensure binder identity
+        Binder.restoreCallingIdentity(sCallingIdentity);
+    }
+
+    private static void initializeCompatIds() {
         // Set up compat-IDs for the app side.
         // TODO: Inside the system server, all the compat-IDs should be enabled,
         // Due to the `AppCompatCallbacks.install(new long[0], new long[0])` call in
@@ -397,8 +386,8 @@
 
         // Compat framework only uses the package name and the target SDK level.
         ApplicationInfo appInfo = new ApplicationInfo();
-        appInfo.packageName = config.mTargetPackageName;
-        appInfo.targetSdkVersion = config.mTargetSdkLevel;
+        appInfo.packageName = sTargetPackageName;
+        appInfo.targetSdkVersion = sTargetSdkLevel;
 
         PlatformCompat platformCompat = null;
         try {
@@ -415,65 +404,42 @@
     }
 
     /**
-     * De-initialize.
-     *
-     * Note, we call this method when init() fails too, so this method should deal with
-     * any partially-initialized states.
+     * Load {@link Resources} from an APK, with cache.
      */
-    public static void reset() {
-        if (RAVENWOOD_VERBOSE_LOGGING) {
-            Log.v(TAG, "reset() called here", new RuntimeException("STACKTRACE"));
+    private static Resources loadResources(@Nullable File apkPath) {
+        var cached = sCachedResources.get(apkPath);
+        if (cached != null) {
+            return cached;
         }
-        if (sRunner == null) {
-            throw new RavenwoodRuntimeException("Internal error: reset() already called");
-        }
-        var config = sRunner.mState.getConfig();
-        sRunner = null;
 
+        var fileToLoad = apkPath != null ? apkPath : new File(RAVENWOOD_EMPTY_RESOURCES_APK);
+
+        assertTrue("File " + fileToLoad + " doesn't exist.", fileToLoad.isFile());
+
+        final String path = fileToLoad.getAbsolutePath();
+        final var emptyPaths = new String[0];
+
+        ResourcesManager.getInstance().initializeApplicationPaths(path, emptyPaths);
+
+        final var ret = ResourcesManager.getInstance().getResources(null, path,
+                emptyPaths, emptyPaths, emptyPaths,
+                emptyPaths, null, null,
+                new DisplayAdjustments().getCompatibilityInfo(),
+                RavenwoodRuntimeEnvironmentController.class.getClassLoader(), null);
+
+        assertNotNull(ret);
+
+        sCachedResources.put(apkPath, ret);
+        return ret;
+    }
+
+    /**
+     * A callback when a test class finishes its execution, mostly only for debugging.
+     */
+    public static void exitTestClass() {
         if (ENABLE_TIMEOUT_STACKS) {
             sPendingTimeout.cancel(false);
         }
-
-        RavenwoodSystemServer.reset(config);
-
-        InstrumentationRegistry.registerInstance(null, Bundle.EMPTY);
-        config.mInstrumentation = null;
-        if (config.mInstContext != null) {
-            ((RavenwoodContext) config.mInstContext).cleanUp();
-            config.mInstContext = null;
-        }
-        if (config.mTargetContext != null) {
-            ((RavenwoodContext) config.mTargetContext).cleanUp();
-            config.mTargetContext = null;
-        }
-        if (config.mState.mSystemServerContext != null) {
-            config.mState.mSystemServerContext.cleanUp();
-        }
-
-        if (Looper.getMainLooper() != null) {
-            Looper.getMainLooper().quit();
-        }
-        Looper.clearMainLooperForTest();
-
-        ActivityManager.reset$ravenwood();
-
-        LocalServices.removeAllServicesForTest();
-        ServiceManager.reset$ravenwood();
-
-        setSystemProperties(null);
-        if (sOriginalIdentityToken != -1) {
-            Binder.restoreCallingIdentity(sOriginalIdentityToken);
-        }
-        RavenwoodRuntimeState.reset();
-        Process_ravenwood.reset();
-        DeviceConfig_host.reset();
-
-        try {
-            ResourcesManager.setInstance(null); // Better structure needed.
-        } catch (Exception e) {
-            // AOSP-CHANGE: AOSP doesn't support resources yet.
-        }
-
         if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
             maybeThrowPendingUncaughtException(true);
         }
@@ -518,19 +484,6 @@
         }
     }
 
-    /**
-     * Set the current configuration to the actual SystemProperties.
-     */
-    private static void setSystemProperties(@Nullable RavenwoodSystemProperties systemProperties) {
-        SystemProperties.clearChangeCallbacksForTest();
-        RavenwoodRuntimeNative.clearSystemProperties();
-        if (systemProperties == null) systemProperties = new RavenwoodSystemProperties();
-        sProps = new RavenwoodSystemProperties(systemProperties, true);
-        for (var entry : systemProperties.getValues().entrySet()) {
-            RavenwoodRuntimeNative.setSystemProperty(entry.getKey(), entry.getValue());
-        }
-    }
-
     private static final String MOCKITO_ERROR = "FATAL: Unsupported Mockito detected!"
             + " Your test or its dependencies use one of the \"mockito-target-*\""
             + " modules as static library, which is unusable on host side."
@@ -555,37 +508,42 @@
 
     // TODO: use the real UiAutomation class instead of a mock
     private static UiAutomation createMockUiAutomation() {
-        final Set[] adoptedPermission = { Collections.emptySet() };
+        sAdoptedPermissions = Collections.emptySet();
         var mock = mock(UiAutomation.class, inv -> {
             HostTestUtils.onThrowMethodCalled();
             return null;
         });
         doAnswer(inv -> {
-            adoptedPermission[0] = UiAutomation.ALL_PERMISSIONS;
+            sAdoptedPermissions = UiAutomation.ALL_PERMISSIONS;
             return null;
         }).when(mock).adoptShellPermissionIdentity();
         doAnswer(inv -> {
             if (inv.getArgument(0) == null) {
-                adoptedPermission[0] = UiAutomation.ALL_PERMISSIONS;
+                sAdoptedPermissions = UiAutomation.ALL_PERMISSIONS;
             } else {
-                adoptedPermission[0] = Set.of(inv.getArguments());
+                sAdoptedPermissions = (Set) Set.of(inv.getArguments());
             }
             return null;
         }).when(mock).adoptShellPermissionIdentity(any());
         doAnswer(inv -> {
-            adoptedPermission[0] = Collections.emptySet();
+            sAdoptedPermissions = Collections.emptySet();
             return null;
         }).when(mock).dropShellPermissionIdentity();
-        doAnswer(inv -> adoptedPermission[0]).when(mock).getAdoptedShellPermissions();
+        doAnswer(inv -> sAdoptedPermissions).when(mock).getAdoptedShellPermissions();
         return mock;
     }
 
-    @SuppressWarnings("unused")  // Called from native code (ravenwood_sysprop.cpp)
-    private static void checkSystemPropertyAccess(String key, boolean write) {
-        boolean result = write ? sProps.isKeyWritable(key) : sProps.isKeyReadable(key);
-        if (!result) {
-            throw new IllegalArgumentException((write ? "Write" : "Read")
-                    + " access to system property '" + key + "' denied via RavenwoodConfig");
+    private static void dumpCommandLineArgs() {
+        Log.i(TAG, "JVM arguments:");
+
+        // Note, we use the wrapper in JUnit4, not the actual class (
+        // java.lang.management.ManagementFactory), because we can't see the later at the build
+        // because this source file is compiled for the device target, where ManagementFactory
+        // doesn't exist.
+        var args = ManagementFactory.getRuntimeMXBean().getInputArguments();
+
+        for (var arg : args) {
+            Log.i(TAG, "  " + arg);
         }
     }
 }
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
similarity index 74%
rename from ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
rename to ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index 9bd376a..c545baa 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package android.platform.test.ravenwood;
 
 import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
@@ -21,26 +20,30 @@
 
 import android.util.Log;
 
+import com.android.ravenwood.RavenwoodRuntimeNative;
+
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
 
+/**
+ * A class to manage the core default system properties of the Ravenwood environment.
+ */
 public class RavenwoodSystemProperties {
     private static final String TAG = "RavenwoodSystemProperties";
 
-    /** We pull in propeties from this file. */
+    /** We pull in properties from this file. */
     private static final String RAVENWOOD_BUILD_PROP = "ravenwood-data/ravenwood-build.prop";
 
     /** This is the actual build.prop we use to build the device (contents depends on lunch). */
     private static final String DEVICE_BUILD_PROP = "ravenwood-data/build.prop";
 
     /** The default values. */
-    private static final Map<String, String> sDefaultValues = new HashMap<>();
+    static final Map<String, String> sDefaultValues = new HashMap<>();
 
     private static final String[] PARTITIONS = {
             "bootimage",
@@ -91,7 +94,7 @@
                 var deviceValue = deviceProps.get(deviceKey);
                 if (deviceValue == null) {
                     throw new RuntimeException("Failed to initialize system properties. Key '"
-                             + deviceKey + "' doesn't exist in the device side build.prop");
+                            + deviceKey + "' doesn't exist in the device side build.prop");
                 }
                 value = deviceValue;
             } else {
@@ -115,6 +118,7 @@
                 }
             }
         }
+
         if (RAVENWOOD_VERBOSE_LOGGING) {
             // Dump all properties for local debugging.
             Log.v(TAG, "All system properties:");
@@ -122,35 +126,12 @@
                 Log.v(TAG, "" + key + "=" + sDefaultValues.get(key));
             }
         }
+
+        // Actually set the system properties
+        sDefaultValues.forEach(RavenwoodRuntimeNative::setSystemProperty);
     }
 
-    private volatile boolean mIsImmutable;
-
-    private final Map<String, String> mValues = new HashMap<>();
-
-    /** Set of additional keys that should be considered readable */
-    private final Set<String> mKeyReadable = new HashSet<>();
-
-    /** Set of additional keys that should be considered writable */
-    private final Set<String> mKeyWritable = new HashSet<>();
-
-    public RavenwoodSystemProperties() {
-        mValues.putAll(sDefaultValues);
-    }
-
-    /** Copy constructor */
-    public RavenwoodSystemProperties(RavenwoodSystemProperties source, boolean immutable) {
-        mKeyReadable.addAll(source.mKeyReadable);
-        mKeyWritable.addAll(source.mKeyWritable);
-        mValues.putAll(source.mValues);
-        mIsImmutable = immutable;
-    }
-
-    public Map<String, String> getValues() {
-        return new HashMap<>(mValues);
-    }
-
-    public boolean isKeyReadable(String key) {
+    private static boolean isKeyReadable(String key) {
         final String root = getKeyRoot(key);
 
         if (root.startsWith("debug.")) return true;
@@ -183,10 +164,10 @@
                 return true;
         }
 
-        return mKeyReadable.contains(key);
+        return false;
     }
 
-    public boolean isKeyWritable(String key) {
+    private static boolean isKeyWritable(String key) {
         final String root = getKeyRoot(key);
 
         if (root.startsWith("debug.")) return true;
@@ -194,42 +175,11 @@
         // For PropertyInvalidatedCache
         if (root.startsWith("cache_key.")) return true;
 
-        return mKeyWritable.contains(key);
+        return false;
     }
 
-    private void ensureNotImmutable() {
-        if (mIsImmutable) {
-            throw new RuntimeException("Unable to update immutable instance");
-        }
-    }
-
-    public void setValue(String key, Object value) {
-        ensureNotImmutable();
-
-        final String valueString = (value == null) ? null : String.valueOf(value);
-        if ((valueString == null) || valueString.isEmpty()) {
-            mValues.remove(key);
-        } else {
-            mValues.put(key, valueString);
-        }
-    }
-
-    public void setAccessNone(String key) {
-        ensureNotImmutable();
-        mKeyReadable.remove(key);
-        mKeyWritable.remove(key);
-    }
-
-    public void setAccessReadOnly(String key) {
-        ensureNotImmutable();
-        mKeyReadable.add(key);
-        mKeyWritable.remove(key);
-    }
-
-    public void setAccessReadWrite(String key) {
-        ensureNotImmutable();
-        mKeyReadable.add(key);
-        mKeyWritable.add(key);
+    static boolean isKeyAccessible(String key, boolean write) {
+        return write ? isKeyWritable(key) : isKeyReadable(key);
     }
 
     /**
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
index 438a2bf..3346635 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
@@ -33,7 +33,7 @@
 import com.android.server.compat.PlatformCompatNative;
 import com.android.server.utils.TimingsTraceAndSlog;
 
-import java.util.List;
+import java.util.Collection;
 import java.util.Set;
 
 public class RavenwoodSystemServer {
@@ -68,27 +68,24 @@
     private static TimingsTraceAndSlog sTimings;
     private static SystemServiceManager sServiceManager;
 
-    public static void init(RavenwoodConfig config) {
+    public static void init(Context systemServerContext) {
         // Always start PlatformCompat, regardless of the requested services.
         // PlatformCompat is not really a SystemService, so it won't receive boot phases / etc.
         // This initialization code is copied from SystemServer.java.
-        PlatformCompat platformCompat = new PlatformCompat(config.mState.mSystemServerContext);
+        PlatformCompat platformCompat = new PlatformCompat(systemServerContext);
         ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat);
         ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE,
                 new PlatformCompatNative(platformCompat));
 
-        // Avoid overhead if no services required
-        if (config.mServicesRequired.isEmpty()) return;
-
         sStartedServices = new ArraySet<>();
         sTimings = new TimingsTraceAndSlog();
-        sServiceManager = new SystemServiceManager(config.mState.mSystemServerContext);
+        sServiceManager = new SystemServiceManager(systemServerContext);
         sServiceManager.setStartInfo(false,
                 SystemClock.elapsedRealtime(),
                 SystemClock.uptimeMillis());
         LocalServices.addService(SystemServiceManager.class, sServiceManager);
 
-        startServices(config.mServicesRequired);
+        startServices(sKnownServices.keySet());
         sServiceManager.sealStartedServices();
 
         // TODO: expand to include additional boot phases when relevant
@@ -96,7 +93,7 @@
         sServiceManager.startBootPhase(sTimings, SystemService.PHASE_BOOT_COMPLETED);
     }
 
-    public static void reset(RavenwoodConfig config) {
+    public static void reset() {
         // TODO: consider introducing shutdown boot phases
 
         LocalServices.removeServiceForTest(SystemServiceManager.class);
@@ -105,7 +102,7 @@
         sStartedServices = null;
     }
 
-    private static void startServices(List<Class<?>> serviceClasses) {
+    private static void startServices(Collection<Class<?>> serviceClasses) {
         for (Class<?> serviceClass : serviceClasses) {
             // Quietly ignore duplicate requests if service already started
             if (sStartedServices.contains(serviceClass)) continue;
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
index 7ca9239..3ed0f50 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
@@ -15,21 +15,13 @@
  */
 package android.platform.test.ravenwood;
 
-import static android.os.Process.FIRST_APPLICATION_UID;
-import static android.os.UserHandle.SYSTEM;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.Instrumentation;
-import android.content.Context;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * @deprecated This class will be removed. Reach out to g/ravenwood if you need any features in it.
@@ -45,37 +37,10 @@
     public @interface Config {
     }
 
-    private static final int NOBODY_UID = 9999;
-
-    private static final AtomicInteger sNextPid = new AtomicInteger(100);
-
-    int mCurrentUser = SYSTEM.getIdentifier();
-
-    /**
-     * Unless the test author requests differently, run as "nobody", and give each collection of
-     * tests its own unique PID.
-     */
-    int mUid = FIRST_APPLICATION_UID;
-    int mPid = sNextPid.getAndIncrement();
-
-    String mTestPackageName;
-    String mTargetPackageName;
-
-    int mTargetSdkLevel;
-
-    final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties();
-
-    final List<Class<?>> mServicesRequired = new ArrayList<>();
-
-    volatile Context mInstContext;
-    volatile Context mTargetContext;
-    volatile Instrumentation mInstrumentation;
-
     /**
      * Stores internal states / methods associated with this config that's only needed in
      * junit-impl.
      */
-    final RavenwoodConfigState mState = new RavenwoodConfigState(this);
     private RavenwoodConfig() {
     }
 
@@ -159,34 +124,11 @@
             return this;
         }
 
-        Builder setSystemPropertyImmutableReal(@NonNull String key,
-                @Nullable Object value) {
-            mConfig.mSystemProperties.setValue(key, value);
-            mConfig.mSystemProperties.setAccessReadOnly(key);
-            return this;
-        }
-
-        Builder setSystemPropertyMutableReal(@NonNull String key,
-                @Nullable Object value) {
-            mConfig.mSystemProperties.setValue(key, value);
-            mConfig.mSystemProperties.setAccessReadWrite(key);
-            return this;
-        }
-
         /**
-         * Configure the set of system services that are required for this test to operate.
-         *
-         * For example, passing {@code android.hardware.SerialManager.class} as an argument will
-         * ensure that the underlying service is created, initialized, and ready to use for the
-         * duration of the test. The {@code SerialManager} instance can be obtained via
-         * {@code RavenwoodRule.getContext()} and {@code Context.getSystemService()}, and
-         * {@code SerialManagerInternal} can be obtained via {@code LocalServices.getService()}.
+         * @deprecated no longer used. All supported services are available.
          */
+        @Deprecated
         public Builder setServicesRequired(@NonNull Class<?>... services) {
-            mConfig.mServicesRequired.clear();
-            for (Class<?> service : services) {
-                mConfig.mServicesRequired.add(service);
-            }
             return this;
         }
 
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index 5681a90..e49d3d9 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -92,19 +92,11 @@
         }
     }
 
-    private final RavenwoodConfig mConfiguration;
-
-    public RavenwoodRule() {
-        mConfiguration = new RavenwoodConfig.Builder().build();
-    }
-
-    private RavenwoodRule(RavenwoodConfig config) {
-        mConfiguration = config;
-    }
+    final RavenwoodTestProperties mProperties = new RavenwoodTestProperties();
 
     public static class Builder {
-        private final RavenwoodConfig.Builder mBuilder =
-                new RavenwoodConfig.Builder();
+
+        private final RavenwoodRule mRule = new RavenwoodRule();
 
         public Builder() {
         }
@@ -152,7 +144,8 @@
          * Has no effect on non-Ravenwood environments.
          */
         public Builder setSystemPropertyImmutable(@NonNull String key, @Nullable Object value) {
-            mBuilder.setSystemPropertyImmutableReal(key, value);
+            mRule.mProperties.setValue(key, value);
+            mRule.mProperties.setAccessReadOnly(key);
             return this;
         }
 
@@ -167,26 +160,21 @@
          * Has no effect on non-Ravenwood environments.
          */
         public Builder setSystemPropertyMutable(@NonNull String key, @Nullable Object value) {
-            mBuilder.setSystemPropertyMutableReal(key, value);
+            mRule.mProperties.setValue(key, value);
+            mRule.mProperties.setAccessReadWrite(key);
             return this;
         }
 
         /**
-         * Configure the set of system services that are required for this test to operate.
-         *
-         * For example, passing {@code android.hardware.SerialManager.class} as an argument will
-         * ensure that the underlying service is created, initialized, and ready to use for the
-         * duration of the test. The {@code SerialManager} instance can be obtained via
-         * {@code RavenwoodRule.getContext()} and {@code Context.getSystemService()}, and
-         * {@code SerialManagerInternal} can be obtained via {@code LocalServices.getService()}.
+         * @deprecated no longer used. All supported services are available.
          */
+        @Deprecated
         public Builder setServicesRequired(@NonNull Class<?>... services) {
-            mBuilder.setServicesRequired(services);
             return this;
         }
 
         public RavenwoodRule build() {
-            return new RavenwoodRule(mBuilder.build());
+            return mRule;
         }
     }
 
@@ -227,7 +215,7 @@
 
     @Override
     public Statement apply(Statement base, Description description) {
-        if (!RavenwoodConfig.isOnRavenwood()) {
+        if (!IS_ON_RAVENWOOD) {
             return base;
         }
         return new Statement() {
@@ -296,8 +284,4 @@
     public static RavenwoodPrivate private$ravenwood() {
         return sRavenwoodPrivate;
     }
-
-    RavenwoodConfig getConfiguration() {
-        return mConfiguration;
-    }
 }
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodTestProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodTestProperties.java
new file mode 100644
index 0000000..66a26b5
--- /dev/null
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodTestProperties.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.platform.test.ravenwood;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A class to store system properties defined by tests.
+ */
+public class RavenwoodTestProperties {
+    final Map<String, String> mValues = new HashMap<>();
+
+    /** Set of additional keys that should be considered readable */
+    final Set<String> mKeyReadable = new HashSet<>();
+
+    /** Set of additional keys that should be considered writable */
+    final Set<String> mKeyWritable = new HashSet<>();
+
+    public void setValue(String key, Object value) {
+        final String valueString = (value == null) ? null : String.valueOf(value);
+        if ((valueString == null) || valueString.isEmpty()) {
+            mValues.remove(key);
+        } else {
+            mValues.put(key, valueString);
+        }
+    }
+
+    public void setAccessNone(String key) {
+        mKeyReadable.remove(key);
+        mKeyWritable.remove(key);
+    }
+
+    public void setAccessReadOnly(String key) {
+        mKeyReadable.add(key);
+        mKeyWritable.remove(key);
+    }
+
+    public void setAccessReadWrite(String key) {
+        mKeyReadable.add(key);
+        mKeyWritable.add(key);
+    }
+}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java
index 7b940b4..9a78989 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java
@@ -56,7 +56,11 @@
 
     public static native boolean setSystemProperty(String key, String value);
 
-    public static native void clearSystemProperties();
+    public static native boolean removeSystemProperty(String key);
+
+    public static void clearSystemProperties() {
+        removeSystemProperty(null);
+    }
 
     public static native int gettid();
 
diff --git a/ravenwood/runtime-jni/jni_helper.h b/ravenwood/runtime-jni/jni_helper.h
index 561fb3b..25d7519 100644
--- a/ravenwood/runtime-jni/jni_helper.h
+++ b/ravenwood/runtime-jni/jni_helper.h
@@ -26,6 +26,7 @@
 constexpr const char* kCommonUtils = "com/android/ravenwood/common/RavenwoodCommonUtils";
 constexpr const char* kRuntimeEnvController =
         "android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController";
+constexpr const char* kRunnerState = "android/platform/test/ravenwood/RavenwoodRunnerState";
 constexpr const char* kRuntimeNative = "com/android/ravenwood/RavenwoodRuntimeNative";
 
 // We have to explicitly decode the string to real UTF-8, because when using GetStringUTFChars
diff --git a/ravenwood/runtime-jni/ravenwood_sysprop.cpp b/ravenwood/runtime-jni/ravenwood_sysprop.cpp
index aafc426..a78aa8d 100644
--- a/ravenwood/runtime-jni/ravenwood_sysprop.cpp
+++ b/ravenwood/runtime-jni/ravenwood_sysprop.cpp
@@ -117,7 +117,7 @@
 // ---- JNI ----
 
 static JavaVM* gVM = nullptr;
-static jclass gEnvController = nullptr;
+static jclass gRunnerState = nullptr;
 static jmethodID gCheckSystemPropertyAccess;
 
 static void reloadNativeLibrary(JNIEnv* env, jclass, jstring javaPath) {
@@ -128,11 +128,11 @@
 
 // Call back into Java code to check property access
 static void check_system_property_access(const char* key, bool write) {
-    if (gVM != nullptr && gEnvController != nullptr) {
+    if (gVM != nullptr && gRunnerState != nullptr) {
         JNIEnv* env;
         if (gVM->GetEnv((void**)&env, JNI_VERSION_1_4) >= 0) {
             ALOGI("%s access to system property '%s'", write ? "Write" : "Read", key);
-            env->CallStaticVoidMethod(gEnvController, gCheckSystemPropertyAccess,
+            env->CallStaticVoidMethod(gRunnerState, gCheckSystemPropertyAccess,
                                       env->NewStringUTF(key), write ? JNI_TRUE : JNI_FALSE);
             return;
         }
@@ -155,16 +155,29 @@
     return property_set(key.c_str(), value.c_str()) ? JNI_TRUE : JNI_FALSE;
 }
 
-static void clearSystemProperties(JNIEnv*, jclass) {
+static jboolean removeSystemProperty(JNIEnv* env, jclass, jstring javaKey) {
     std::lock_guard lock(g_properties_lock);
-    g_properties.clear();
+
+    if (javaKey == nullptr) {
+        g_properties.clear();
+        return JNI_TRUE;
+    } else {
+        ScopedUtfChars key(env, javaKey);
+        auto it = g_properties.find(key);
+        if (it != g_properties.end()) {
+            g_properties.erase(it);
+            return JNI_TRUE;
+        } else {
+            return JNI_FALSE;
+        }
+    }
 }
 
 static const JNINativeMethod sMethods[] = {
         {"reloadNativeLibrary", "(Ljava/lang/String;)V", (void*)reloadNativeLibrary},
         {"getSystemProperty", "(Ljava/lang/String;)Ljava/lang/String;", (void*)getSystemProperty},
         {"setSystemProperty", "(Ljava/lang/String;Ljava/lang/String;)Z", (void*)setSystemProperty},
-        {"clearSystemProperties", "()V", (void*)clearSystemProperties},
+        {"removeSystemProperty", "(Ljava/lang/String;)Z", (void*)removeSystemProperty},
 };
 
 extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
@@ -174,9 +187,9 @@
     gVM = vm;
 
     // Fetch several references for future use
-    gEnvController = FindGlobalClassOrDie(env, kRuntimeEnvController);
+    gRunnerState = FindGlobalClassOrDie(env, kRunnerState);
     gCheckSystemPropertyAccess =
-            GetStaticMethodIDOrDie(env, gEnvController, "checkSystemPropertyAccess",
+            GetStaticMethodIDOrDie(env, gRunnerState, "checkSystemPropertyAccess",
                                    "(Ljava/lang/String;Z)V");
 
     // Expose raw property methods as JNI methods
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodMultipleRuleTest.java b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodMultipleRuleTest.java
deleted file mode 100644
index c25d2b4..0000000
--- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodMultipleRuleTest.java
+++ /dev/null
@@ -1,57 +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.ravenwoodtest.bivalenttest;
-
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodRule;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Assume;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-
-/**
- * Make sure having multiple RavenwoodRule's is detected.
- * (But only when running on ravenwod. Otherwise it'll be ignored.)
- */
-@RunWith(AndroidJUnit4.class)
-public class RavenwoodMultipleRuleTest {
-
-    @Rule(order = Integer.MIN_VALUE)
-    public final ExpectedException mExpectedException = ExpectedException.none();
-
-    @Rule
-    public final RavenwoodRule mRavenwood1 = new RavenwoodRule();
-
-    @Rule
-    public final RavenwoodRule mRavenwood2 = new RavenwoodRule();
-
-    public RavenwoodMultipleRuleTest() {
-        // We can't call it within the test method because the exception happens before
-        // calling the method, so set it up here.
-        if (RavenwoodConfig.isOnRavenwood()) {
-            mExpectedException.expectMessage("Multiple nesting RavenwoodRule");
-        }
-    }
-
-    @Test
-    public void testMultipleRulesNotAllowed() {
-        Assume.assumeTrue(RavenwoodConfig.isOnRavenwood());
-    }
-}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRuleValidationTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRuleValidationTest.java
new file mode 100644
index 0000000..f9e73db
--- /dev/null
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRuleValidationTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.ravenwoodtest.runnercallbacktests;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.SystemProperties;
+import android.platform.test.annotations.NoRavenizer;
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+/**
+ * Test for RavenwoodRule.
+ */
+@NoRavenizer // This class shouldn't be executed with RavenwoodAwareTestRunner.
+public class RavenwoodRuleValidationTest extends RavenwoodRunnerTestBase {
+
+    public static class RuleInBaseClass {
+        static String PROPERTY_KEY = "debug.ravenwood.prop.in.base";
+        static String PROPERTY_VAL = "ravenwood";
+        @Rule
+        public final RavenwoodRule mRavenwood1 = new RavenwoodRule.Builder()
+                .setSystemPropertyImmutable(PROPERTY_KEY, PROPERTY_VAL).build();
+    }
+
+    /**
+     * Make sure that RavenwoodRule in a base class takes effect.
+     */
+    @RunWith(AndroidJUnit4.class)
+    // CHECKSTYLE:OFF
+    @Expected("""
+    testRunStarted: classes
+    testSuiteStarted: classes
+    testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRuleValidationTest$RuleInBaseClassSuccessTest
+    testStarted: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRuleValidationTest$RuleInBaseClassSuccessTest)
+    testFinished: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRuleValidationTest$RuleInBaseClassSuccessTest)
+    testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRuleValidationTest$RuleInBaseClassSuccessTest
+    testSuiteFinished: classes
+    testRunFinished: 1,0,0,0
+    """)
+    // CHECKSTYLE:ON
+    public static class RuleInBaseClassSuccessTest extends RuleInBaseClass {
+
+        @Test
+        public void testRuleInBaseClass() {
+            assertThat(SystemProperties.get(PROPERTY_KEY)).isEqualTo(PROPERTY_VAL);
+        }
+    }
+
+    /**
+     * Same as {@link RuleInBaseClass}, but the type of the rule field is not {@link RavenwoodRule}.
+     */
+    public abstract static class RuleWithDifferentTypeInBaseClass {
+        static String PROPERTY_KEY = "debug.ravenwood.prop.in.base.different.type";
+        static String PROPERTY_VAL = "ravenwood";
+        @Rule
+        public final TestRule mRavenwood1 = new RavenwoodRule.Builder()
+                .setSystemPropertyImmutable(PROPERTY_KEY, PROPERTY_VAL).build();
+    }
+
+    /**
+     * Make sure that RavenwoodRule in a base class takes effect, even if the field type is not
+     */
+    @RunWith(AndroidJUnit4.class)
+    // CHECKSTYLE:OFF
+    @Expected("""
+    testRunStarted: classes
+    testSuiteStarted: classes
+    testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRuleValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest
+    testStarted: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRuleValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest)
+    testFinished: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRuleValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest)
+    testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRuleValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest
+    testSuiteFinished: classes
+    testRunFinished: 1,0,0,0
+    """)
+    // CHECKSTYLE:ON
+    public static class RuleWithDifferentTypeInBaseClassSuccessTest extends RuleWithDifferentTypeInBaseClass {
+
+        @Test
+        public void testRuleInBaseClass() {
+            assertThat(SystemProperties.get(PROPERTY_KEY)).isEqualTo(PROPERTY_VAL);
+        }
+    }
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
deleted file mode 100644
index f94b98b..0000000
--- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
+++ /dev/null
@@ -1,484 +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.ravenwoodtest.runnercallbacktests;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.NoRavenizer;
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodRule;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestRule;
-import org.junit.runner.RunWith;
-
-
-/**
- * Test for @Config field extraction and validation.
- *
- * TODO(b/377765941) Most of the tests here will be obsolete and deleted with b/377765941, but
- * some of the tests may need to be re-implemented one way or another. (e.g. the package name
- * test.) Until that happens, we'll keep all tests here but add an {@code @Ignore} instead.
- */
-@NoRavenizer // This class shouldn't be executed with RavenwoodAwareTestRunner.
-public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase {
-    public abstract static class ConfigInBaseClass {
-        static String PACKAGE_NAME = "com.ConfigInBaseClass";
-
-        @RavenwoodConfig.Config
-        public static RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
-                .setPackageName(PACKAGE_NAME).build();
-    }
-
-    /**
-     * Make sure a config in the base class is detected.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigInBaseClassTest
-    testStarted: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigInBaseClassTest)
-    testFinished: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigInBaseClassTest)
-    testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigInBaseClassTest
-    testSuiteFinished: classes
-    testRunFinished: 1,0,0,0
-    """)
-    // CHECKSTYLE:ON
-    @Ignore // Package name is no longer set via config.
-    public static class ConfigInBaseClassTest extends ConfigInBaseClass {
-        @Test
-        public void test() {
-            assertThat(InstrumentationRegistry.getInstrumentation().getContext().getPackageName())
-                    .isEqualTo(PACKAGE_NAME);
-        }
-    }
-
-    /**
-     * Make sure a config in the base class is detected.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigOverridingTest
-    testStarted: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigOverridingTest)
-    testFinished: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigOverridingTest)
-    testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigOverridingTest
-    testSuiteFinished: classes
-    testRunFinished: 1,0,0,0
-    """)
-    // CHECKSTYLE:ON
-    @Ignore // Package name is no longer set via config.
-    public static class ConfigOverridingTest extends ConfigInBaseClass {
-        static String PACKAGE_NAME_OVERRIDE = "com.ConfigOverridingTest";
-
-        @RavenwoodConfig.Config
-        public static RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
-                .setPackageName(PACKAGE_NAME_OVERRIDE).build();
-
-        @Test
-        public void test() {
-            assertThat(InstrumentationRegistry.getInstrumentation().getContext().getPackageName())
-                    .isEqualTo(PACKAGE_NAME_OVERRIDE);
-        }
-    }
-
-    /**
-     * Test to make sure that if a test has a config error, the failure would be reported from
-     * each test method.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testStarted: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest)
-    testFailure: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest.sConfig expected to be public static
-    testFinished: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ErrorMustBeReportedFromEachTest)
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class ErrorMustBeReportedFromEachTest {
-        @RavenwoodConfig.Config
-        private static RavenwoodConfig sConfig = // Invalid because it's private.
-                new RavenwoodConfig.Builder().build();
-
-        @Test
-        public void testMethod1() {
-        }
-
-        @Test
-        public void testMethod2() {
-        }
-
-        @Test
-        public void testMethod3() {
-        }
-    }
-
-    /**
-     * Invalid because there are two @Config's.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testStarted: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateConfigTest)
-    testFailure: Class com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest.DuplicateConfigTest has multiple fields with @RavenwoodConfig.Config
-    testFinished: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateConfigTest)
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class DuplicateConfigTest {
-
-        @RavenwoodConfig.Config
-        public static RavenwoodConfig sConfig1 =
-                new RavenwoodConfig.Builder().build();
-
-        @RavenwoodConfig.Config
-        public static RavenwoodConfig sConfig2 =
-                new RavenwoodConfig.Builder().build();
-
-        @Test
-        public void testConfig() {
-        }
-    }
-
-    /**
-     * @Config's must be static.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testStarted: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonStaticConfigTest)
-    testFailure: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonStaticConfigTest.sConfig expected to be public static
-    testFinished: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonStaticConfigTest)
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class NonStaticConfigTest {
-
-        @RavenwoodConfig.Config
-        public RavenwoodConfig sConfig =
-                new RavenwoodConfig.Builder().build();
-
-        @Test
-        public void testConfig() {
-        }
-    }
-
-    /**
-     * @Config's must be public.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testStarted: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonPublicConfigTest)
-    testFailure: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonPublicConfigTest.sConfig expected to be public static
-    testFinished: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$NonPublicConfigTest)
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class NonPublicConfigTest {
-
-        @RavenwoodConfig.Config
-        RavenwoodConfig sConfig =
-                new RavenwoodConfig.Builder().build();
-
-        @Test
-        public void testConfig() {
-        }
-    }
-
-    /**
-     * @Config's must be of type RavenwoodConfig.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testStarted: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WrongTypeConfigTest)
-    testFailure: Field com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest.WrongTypeConfigTest.sConfig has @RavenwoodConfig.Config but type is not RavenwoodConfig
-    testFinished: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WrongTypeConfigTest)
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class WrongTypeConfigTest {
-
-        @RavenwoodConfig.Config
-        public static Object sConfig =
-                new RavenwoodConfig.Builder().build();
-
-        @Test
-        public void testConfig() {
-        }
-
-    }
-
-    /**
-     * @Rule must be of type RavenwoodRule.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WrongTypeRuleTest
-    testStarted: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WrongTypeRuleTest)
-    testFailure: If you have a RavenwoodRule in your test, make sure the field type is RavenwoodRule so Ravenwood can detect it.
-    testFinished: testConfig(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WrongTypeRuleTest)
-    testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WrongTypeRuleTest
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class WrongTypeRuleTest {
-
-        @Rule
-        public TestRule mRule = new RavenwoodRule.Builder().build();
-
-        @Test
-        public void testConfig() {
-        }
-
-    }
-
-    /**
-     * Config can't be used with a (instance) Rule.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testStarted: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WithInstanceRuleTest)
-    testFailure: RavenwoodConfig and RavenwoodRule cannot be used in the same class. Suggest migrating to RavenwoodConfig.
-    testFinished: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WithInstanceRuleTest)
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class WithInstanceRuleTest {
-
-        @RavenwoodConfig.Config
-        public static RavenwoodConfig sConfig =
-                new RavenwoodConfig.Builder().build();
-
-        @Rule
-        public RavenwoodRule mRule = new RavenwoodRule.Builder().build();
-
-        @Test
-        public void testConfig() {
-        }
-    }
-
-    /**
-     * Config can't be used with a (static) Rule.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testStarted: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WithStaticRuleTest)
-    testFailure: Failed to instantiate class androidx.test.ext.junit.runners.AndroidJUnit4
-    testFinished: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$WithStaticRuleTest)
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class WithStaticRuleTest {
-
-        @RavenwoodConfig.Config
-        public static RavenwoodConfig sConfig =
-                new RavenwoodConfig.Builder().build();
-
-        @Rule
-        public static RavenwoodRule sRule = new RavenwoodRule.Builder().build();
-
-        @Test
-        public void testConfig() {
-        }
-    }
-
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateRulesTest
-    testStarted: testMultipleRulesNotAllowed(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateRulesTest)
-    testFailure: Multiple nesting RavenwoodRule's are detected in the same class, which is not supported.
-    testFinished: testMultipleRulesNotAllowed(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateRulesTest)
-    testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$DuplicateRulesTest
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class DuplicateRulesTest {
-
-        @Rule
-        public final RavenwoodRule mRavenwood1 = new RavenwoodRule();
-
-        @Rule
-        public final RavenwoodRule mRavenwood2 = new RavenwoodRule();
-
-        @Test
-        public void testMultipleRulesNotAllowed() {
-        }
-    }
-
-    public static class RuleInBaseClass {
-        static String PACKAGE_NAME = "com.RuleInBaseClass";
-        @Rule
-        public final RavenwoodRule mRavenwood1 = new RavenwoodRule.Builder()
-                .setPackageName(PACKAGE_NAME).build();
-    }
-
-    /**
-     * Make sure that RavenwoodRule in a base class takes effect.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleInBaseClassSuccessTest
-    testStarted: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleInBaseClassSuccessTest)
-    testFinished: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleInBaseClassSuccessTest)
-    testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleInBaseClassSuccessTest
-    testSuiteFinished: classes
-    testRunFinished: 1,0,0,0
-    """)
-    // CHECKSTYLE:ON
-    @Ignore // Package name is no longer set via config.
-    public static class RuleInBaseClassSuccessTest extends RuleInBaseClass {
-
-        @Test
-        public void testRuleInBaseClass() {
-            assertThat(InstrumentationRegistry.getInstrumentation().getContext().getPackageName())
-                    .isEqualTo(PACKAGE_NAME);
-        }
-    }
-
-    /**
-     * Make sure that having a config and a rule in a base class should fail.
-     * RavenwoodRule.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testStarted: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleInBaseClassTest)
-    testFailure: RavenwoodConfig and RavenwoodRule cannot be used in the same class. Suggest migrating to RavenwoodConfig.
-    testFinished: initializationError(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleInBaseClassTest)
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class ConfigWithRuleInBaseClassTest extends RuleInBaseClass {
-        @RavenwoodConfig.Config
-        public static RavenwoodConfig sConfig = new RavenwoodConfig.Builder().build();
-
-        @Test
-        public void test() {
-        }
-    }
-
-    /**
-     * Same as {@link RuleInBaseClass}, but the type of the rule field is not {@link RavenwoodRule}.
-     */
-    public abstract static class RuleWithDifferentTypeInBaseClass {
-        static String PACKAGE_NAME = "com.RuleWithDifferentTypeInBaseClass";
-        @Rule
-        public final TestRule mRavenwood1 = new RavenwoodRule.Builder()
-                .setPackageName(PACKAGE_NAME).build();
-    }
-
-    /**
-     * Make sure that RavenwoodRule in a base class takes effect, even if the field type is not
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest
-    testStarted: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest)
-    testFailure: If you have a RavenwoodRule in your test, make sure the field type is RavenwoodRule so Ravenwood can detect it.
-    testFinished: testRuleInBaseClass(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest)
-    testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$RuleWithDifferentTypeInBaseClassSuccessTest
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    @Ignore // Package name is no longer set via config.
-    public static class RuleWithDifferentTypeInBaseClassSuccessTest extends RuleWithDifferentTypeInBaseClass {
-
-        @Test
-        public void testRuleInBaseClass() {
-            assertThat(InstrumentationRegistry.getInstrumentation().getContext().getPackageName())
-                    .isEqualTo(PACKAGE_NAME);
-        }
-    }
-
-    /**
-     * Make sure that having a config and a rule in a base class should fail, even if the field type is not
-     * RavenwoodRule.
-     */
-    @RunWith(AndroidJUnit4.class)
-    // CHECKSTYLE:OFF
-    @Expected("""
-    testRunStarted: classes
-    testSuiteStarted: classes
-    testSuiteStarted: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleWithDifferentTypeInBaseClassTest
-    testStarted: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleWithDifferentTypeInBaseClassTest)
-    testFailure: If you have a RavenwoodRule in your test, make sure the field type is RavenwoodRule so Ravenwood can detect it.
-    testFinished: test(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleWithDifferentTypeInBaseClassTest)
-    testSuiteFinished: com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerConfigValidationTest$ConfigWithRuleWithDifferentTypeInBaseClassTest
-    testSuiteFinished: classes
-    testRunFinished: 1,1,0,0
-    """)
-    // CHECKSTYLE:ON
-    public static class ConfigWithRuleWithDifferentTypeInBaseClassTest extends RuleWithDifferentTypeInBaseClass {
-        @RavenwoodConfig.Config
-        public static RavenwoodConfig sConfig = new RavenwoodConfig.Builder().build();
-
-        @Test
-        public void test() {
-        }
-    }
-}
diff --git a/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/IdentityTest.java b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/IdentityTest.java
index 8e04b69..271c27f 100644
--- a/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/IdentityTest.java
+++ b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/IdentityTest.java
@@ -15,7 +15,6 @@
  */
 package com.android.ravenwoodtest.runtimetest;
 
-import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
 import static android.os.Process.FIRST_APPLICATION_UID;
 
 import static org.junit.Assert.assertEquals;
@@ -23,7 +22,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Process;
-import android.platform.test.ravenwood.RavenwoodConfig;
 import android.system.Os;
 
 import com.android.ravenwood.RavenwoodRuntimeState;
@@ -34,13 +32,6 @@
 
 public class IdentityTest {
 
-    @RavenwoodConfig.Config
-    public static final RavenwoodConfig sConfig =
-            new RavenwoodConfig.Builder()
-                    .setTargetSdkLevel(UPSIDE_DOWN_CAKE)
-                    .setProcessApp()
-                    .build();
-
     @Test
     public void testUid() {
         assertEquals(FIRST_APPLICATION_UID, RavenwoodRuntimeState.sUid);
@@ -60,7 +51,7 @@
     @Test
     public void testTargetSdkLevel() {
         assertEquals(Build.VERSION_CODES.CUR_DEVELOPMENT, RavenwoodRuntimeState.CUR_DEVELOPMENT);
-        assertEquals(UPSIDE_DOWN_CAKE, RavenwoodRuntimeState.sTargetSdkLevel);
-        assertEquals(UPSIDE_DOWN_CAKE, VMRuntime.getRuntime().getTargetSdkVersion());
+        assertEquals(RavenwoodRuntimeState.sTargetSdkLevel,
+                VMRuntime.getRuntime().getTargetSdkVersion());
     }
 }
diff --git a/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/SystemPropertyTest.java b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/SystemPropertyTest.java
new file mode 100644
index 0000000..70bf204
--- /dev/null
+++ b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/SystemPropertyTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.runtimetest;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.os.SystemProperties;
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runners.model.Statement;
+
+public class SystemPropertyTest {
+
+    private static final String PROP_KEY_1 = "debug.ravenwood.prop1";
+    private static final String PROP_VAL_1 = "ravenwood.1";
+    private static final String PROP_KEY_2 = "debug.ravenwood.prop2";
+    private static final String PROP_VAL_2 = "ravenwood.2";
+    private static final String PROP_KEY_3 = "debug.ravenwood.prop3";
+    private static final String PROP_VAL_3 = "ravenwood.3";
+    private static final String PROP_VAL_4 = "ravenwood.4";
+
+    @ClassRule(order = 0)
+    public static TestRule mCheckClassRule = (base, description) -> new Statement() {
+        @Override
+        public void evaluate() throws Throwable {
+            assertTrue(SystemProperties.get(PROP_KEY_1).isEmpty());
+            assertTrue(SystemProperties.get(PROP_KEY_3).isEmpty());
+            try {
+                base.evaluate();
+            } finally {
+                assertTrue(SystemProperties.get(PROP_KEY_1).isEmpty());
+                assertTrue(SystemProperties.get(PROP_KEY_3).isEmpty());
+            }
+        }
+    };
+
+    @ClassRule(order = 1)
+    public static RavenwoodRule mClassRule = new RavenwoodRule.Builder()
+            .setSystemPropertyImmutable(PROP_KEY_1, PROP_VAL_1)
+            .setSystemPropertyImmutable(PROP_KEY_3, PROP_VAL_4)
+            .build();
+
+    @Rule(order = 0)
+    public TestRule mCheckRule = (base, description) -> new Statement() {
+        @Override
+        public void evaluate() throws Throwable {
+            assertTrue(SystemProperties.get(PROP_KEY_2).isEmpty());
+            assertEquals(SystemProperties.get(PROP_KEY_3), PROP_VAL_4);
+            try {
+                base.evaluate();
+            } finally {
+                assertTrue(SystemProperties.get(PROP_KEY_2).isEmpty());
+                assertEquals(SystemProperties.get(PROP_KEY_3), PROP_VAL_4);
+            }
+        }
+    };
+
+    @Rule(order = 1)
+    public RavenwoodRule mRule = new RavenwoodRule.Builder()
+            .setSystemPropertyImmutable(PROP_KEY_2, PROP_VAL_2)
+            .setSystemPropertyImmutable(PROP_KEY_3, PROP_VAL_3)
+            .build();
+
+    @Test
+    public void testRavenwoodRuleSetProperty() {
+        assertEquals(SystemProperties.get(PROP_KEY_1), PROP_VAL_1);
+        assertEquals(SystemProperties.get(PROP_KEY_2), PROP_VAL_2);
+        assertEquals(SystemProperties.get(PROP_KEY_3), PROP_VAL_3);
+    }
+}
diff --git a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java
index 4aae1e1..e83a247 100644
--- a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java
+++ b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java
@@ -24,8 +24,6 @@
 import android.content.Context;
 import android.hardware.SerialManager;
 import android.hardware.SerialManagerInternal;
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodConfig.Config;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
@@ -42,12 +40,6 @@
 public class RavenwoodServicesTest {
     private static final String TEST_VIRTUAL_PORT = "virtual:example";
 
-    @Config
-    public static final RavenwoodConfig sRavenwood = new RavenwoodConfig.Builder()
-            .setProcessSystem()
-            .setServicesRequired(SerialManager.class)
-            .build();
-
     private Context mContext;
 
     @Before
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/Android.bp b/ravenwood/tools/hoststubgen/test-tiny-framework/Android.bp
index 1570549..483c4be 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/Android.bp
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/Android.bp
@@ -156,6 +156,7 @@
     ],
     data: [
         "golden-output/*.txt",
+        "golden-output.RELEASE_TARGET_JAVA_21/*.txt",
     ],
     java_data: [
         "hoststubgen-test-tiny-framework-orig-dump",
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt
new file mode 100644
index 0000000..5e5ca62
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt
@@ -0,0 +1,3697 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+  Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestClassLoadHook
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  public abstract java.lang.String value();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestIgnore.class
+  Compiled from "HostSideTestIgnore.java"
+public interface android.hosttest.annotation.HostSideTestIgnore extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestIgnore
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestIgnore.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+  Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestKeep
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestRedirect.class
+  Compiled from "HostSideTestRedirect.java"
+public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestRedirect
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRedirect.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestRedirectionClass.class
+  Compiled from "HostSideTestRedirectionClass.java"
+public interface android.hosttest.annotation.HostSideTestRedirectionClass extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestRedirectionClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  public abstract java.lang.String value();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestRedirectionClass.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+  Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestRemove
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestStaticInitializerKeep.class
+  Compiled from "HostSideTestStaticInitializerKeep.java"
+public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestStaticInitializerKeep
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestStaticInitializerKeep.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+  Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestSubstitute
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  public abstract java.lang.String suffix();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+  Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestThrow
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+  Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestWholeClassKeep
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/tests/HostSideTestSuppress.class
+  Compiled from "HostSideTestSuppress.java"
+public interface android.hosttest.annotation.tests.HostSideTestSuppress extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/tests/HostSideTestSuppress
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestSuppress.java"
+RuntimeVisibleAnnotations:
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD]
+    )
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
+  Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 3
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy;
+
+  public static int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0     a   I
+}
+SourceFile: "IPretendingAidl.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+InnerClasses:
+  public static #x= #x of #x;          // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub.class
+  Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 3
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub;
+
+  public static int addOne(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0     a   I
+}
+SourceFile: "IPretendingAidl.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+InnerClasses:
+  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl.class
+  Compiled from "IPretendingAidl.java"
+public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 3
+}
+SourceFile: "IPretendingAidl.java"
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+InnerClasses:
+  public static #x= #x of #x;            // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+## Class: com/android/hoststubgen/test/tinyframework/R$Nested.class
+  Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R$Nested
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/R$Nested
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 3
+  public static int[] ARRAY;
+    descriptor: [I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+
+  public com.android.hoststubgen.test.tinyframework.R$Nested();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/R$Nested;
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: iconst_1
+         x: newarray       int
+         x: dup
+         x: iconst_0
+         x: iconst_1
+         x: iastore
+         x: putstatic     #x                  // Field ARRAY:[I
+        x: return
+      LineNumberTable:
+}
+SourceFile: "R.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/R
+InnerClasses:
+  public static #x= #x of #x;           // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+## Class: com/android/hoststubgen/test/tinyframework/R.class
+  Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/R
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 3
+  public com.android.hoststubgen.test.tinyframework.R();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/R;
+}
+SourceFile: "R.java"
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/R$Nested
+InnerClasses:
+  public static #x= #x of #x;           // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class
+  Compiled from "TinyFrameworkAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 9, attributes: 2
+  public int keep;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public int remove;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iconst_1
+         x: putfield      #x                  // Field keep:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public int addOne(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+            0       4     1 value   I
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public void toBeRemoved(java.lang.String);
+    descriptor: (Ljava/lang/String;)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+            0       8     1   foo   Ljava/lang/String;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRemove
+
+  public int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=2, args_size=2
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String not supported on host side
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+            0      10     1 value   I
+    RuntimeInvisibleAnnotations:
+      x: #x(#x=s#x)
+        android.hosttest.annotation.HostSideTestSubstitute(
+          suffix="_host"
+        )
+
+  public int addTwo_host(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+            0       4     1 value   I
+
+  public static native int nativeAddThree(int);
+    descriptor: (I)I
+    flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+    RuntimeInvisibleAnnotations:
+      x: #x(#x=s#x)
+        android.hosttest.annotation.HostSideTestSubstitute(
+          suffix="_host"
+        )
+
+  private static int nativeAddThree_host(int);
+    descriptor: (I)I
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_3
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0 value   I
+
+  public java.lang.String unsupportedMethod();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: ldc           #x                 // String This value shouldn\'t be seen on the host side.
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       3     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestThrow
+
+  public int toBeIgnored();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String not supported on host side
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestIgnore
+}
+SourceFile: "TinyFrameworkAnnotations.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x(#x=s#x)
+    android.hosttest.annotation.HostSideTestClassLoadHook(
+      value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+    )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+  Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 3, attributes: 2
+  public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+    descriptor: Ljava/util/Set;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/Set<Ljava/lang/Class<*>;>;
+
+  private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+    descriptor: ()V
+    flags: (0x0002) ACC_PRIVATE
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook;
+
+  public static void onClassLoaded(java.lang.Class<?>);
+    descriptor: (Ljava/lang/Class;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: getstatic     #x                  // Field sLoadedClasses:Ljava/util/Set;
+         x: aload_0
+         x: invokeinterface #x,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+         x: pop
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0 clazz   Ljava/lang/Class;
+      LocalVariableTypeTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0 clazz   Ljava/lang/Class<*>;
+    Signature: #x                          // (Ljava/lang/Class<*>;)V
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class java/util/HashSet
+         x: dup
+         x: invokespecial #x                 // Method java/util/HashSet."<init>":()V
+         x: putstatic     #x                  // Field sLoadedClasses:Ljava/util/Set;
+        x: return
+      LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class
+  Compiled from "TinyFrameworkClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 6, attributes: 2
+  public int keep;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+
+  public int remove;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRemove
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iconst_1
+         x: putfield      #x                  // Field keep:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+
+  public int addOne(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+            0       4     1 value   I
+
+  public int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=2, args_size=2
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String not supported on host side
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+            0      10     1 value   I
+    RuntimeInvisibleAnnotations:
+      x: #x(#x=s#x)
+        android.hosttest.annotation.HostSideTestSubstitute(
+          suffix="_host"
+        )
+
+  public int addTwo_host(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+            0       4     1 value   I
+
+  public void toBeRemoved(java.lang.String);
+    descriptor: (Ljava/lang/String;)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+            0       8     1   foo   Ljava/lang/String;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRemove
+
+  public java.lang.String unsupportedMethod();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: ldc           #x                 // String This value shouldn\'t be seen on the host side.
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       3     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestThrow
+}
+SourceFile: "TinyFrameworkClassWideAnnotations.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+  Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 2, attributes: 2
+  public static boolean sInitialized;
+    descriptor: Z
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.lang.Object sObject;
+    descriptor: Ljava/lang/Object;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault;
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: iconst_1
+         x: putstatic     #x                  // Field sInitialized:Z
+         x: new           #x                  // class java/lang/Object
+         x: dup
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+        x: putstatic     #x                 // Field sObject:Ljava/lang/Object;
+        x: return
+      LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+  Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 2, attributes: 2
+  public static boolean sInitialized;
+    descriptor: Z
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.lang.Object sObject;
+    descriptor: Ljava/lang/Object;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub;
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: iconst_1
+         x: putstatic     #x                  // Field sInitialized:Z
+         x: new           #x                  // class java/lang/Object
+         x: dup
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+        x: putstatic     #x                 // Field sObject:Ljava/lang/Object;
+        x: return
+      LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeInvisibleAnnotations:
+  x: #x(#x=s#x)
+    android.hosttest.annotation.HostSideTestClassLoadHook(
+      value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+    )
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x()
+    android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+  Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+  minor version: 0
+  major version: 65
+  flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+  super_class: #x                        // java/lang/Enum
+  interfaces: 0, fields: 6, methods: 7, attributes: 3
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private final java.lang.String mLongName;
+    descriptor: Ljava/lang/String;
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private final java.lang.String mShortName;
+    descriptor: Ljava/lang/String;
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+    descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: getstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+         x: invokevirtual #x                 // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;".clone:()Ljava/lang/Object;
+         x: checkcast     #x                 // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;"
+         x: areturn
+      LineNumberTable:
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+    descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: aload_0
+         x: invokestatic  #x                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+         x: checkcast     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  name   Ljava/lang/String;
+    MethodParameters:
+      Name                           Flags
+      <no name>                      mandated
+
+  private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+    descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+    flags: (0x0002) ACC_PRIVATE
+    Code:
+      stack=3, locals=5, args_size=5
+         x: aload_0
+         x: aload_1
+         x: iload_2
+         x: invokespecial #x                 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+         x: aload_0
+         x: aload_3
+         x: putfield      #x                 // Field mLongName:Ljava/lang/String;
+        x: aload_0
+        x: aload         4
+        x: putfield      #x                 // Field mShortName:Ljava/lang/String;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      18     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+            0      18     3 longName   Ljava/lang/String;
+            0      18     4 shortName   Ljava/lang/String;
+    MethodParameters:
+      Name                           Flags
+      <no name>                      synthetic
+      <no name>                      synthetic
+      <no name>
+      <no name>
+    Signature: #x                          // (Ljava/lang/String;Ljava/lang/String;)V
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.lang.String getLongName();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: getfield      #x                 // Field mLongName:Ljava/lang/String;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.lang.String getShortName();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: getfield      #x                 // Field mShortName:Ljava/lang/String;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: iconst_3
+         x: anewarray     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: dup
+         x: iconst_0
+         x: getstatic     #x                  // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+         x: aastore
+        x: dup
+        x: iconst_1
+        x: getstatic     #x                  // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: aastore
+        x: dup
+        x: iconst_2
+        x: getstatic     #x                 // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: aastore
+        x: areturn
+      LineNumberTable:
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=6, locals=0, args_size=0
+         x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: dup
+         x: ldc           #x                 // String RED
+         x: iconst_0
+         x: ldc           #x                 // String Red
+         x: ldc           #x                 // String R
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+        x: putstatic     #x                  // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: dup
+        x: ldc           #x                 // String GREEN
+        x: iconst_1
+        x: ldc           #x                 // String Green
+        x: ldc           #x                 // String G
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+        x: putstatic     #x                  // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: dup
+        x: ldc           #x                 // String BLUE
+        x: iconst_2
+        x: ldc           #x                 // String Blue
+        x: ldc           #x                 // String B
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+        x: putstatic     #x                 // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: invokestatic  #x                 // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: putstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: return
+      LineNumberTable:
+}
+Signature: #x                          // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+  Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+  minor version: 0
+  major version: 65
+  flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+  super_class: #x                        // java/lang/Enum
+  interfaces: 0, fields: 3, methods: 5, attributes: 3
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+    descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: getstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+         x: invokevirtual #x                 // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;".clone:()Ljava/lang/Object;
+         x: checkcast     #x                 // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;"
+         x: areturn
+      LineNumberTable:
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+    descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: aload_0
+         x: invokestatic  #x                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+         x: checkcast     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  name   Ljava/lang/String;
+    MethodParameters:
+      Name                           Flags
+      <no name>                      mandated
+
+  private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+    descriptor: (Ljava/lang/String;I)V
+    flags: (0x0002) ACC_PRIVATE
+    Code:
+      stack=3, locals=3, args_size=3
+         x: aload_0
+         x: aload_1
+         x: iload_2
+         x: invokespecial #x                 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       7     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    MethodParameters:
+      Name                           Flags
+      <no name>                      synthetic
+      <no name>                      synthetic
+    Signature: #x                          // ()V
+
+  private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: iconst_2
+         x: anewarray     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: dup
+         x: iconst_0
+         x: getstatic     #x                  // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+         x: aastore
+        x: dup
+        x: iconst_1
+        x: getstatic     #x                  // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: aastore
+        x: areturn
+      LineNumberTable:
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: dup
+         x: ldc           #x                 // String CAT
+         x: iconst_0
+         x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;I)V
+        x: putstatic     #x                  // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+        x: dup
+        x: ldc           #x                 // String DOG
+        x: iconst_1
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;I)V
+        x: putstatic     #x                  // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: invokestatic  #x                 // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: putstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: return
+      LineNumberTable:
+}
+Signature: #x                          // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+  Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 2
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester;
+
+  public static int testException();
+    descriptor: ()I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=0
+         x: new           #x                  // class java/lang/IllegalStateException
+         x: dup
+         x: ldc           #x                  // String Inner exception
+         x: invokespecial #x                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+         x: athrow
+        x: astore_0
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: ldc           #x                 // String Outer exception
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+        x: athrow
+      Exception table:
+         from    to  target type
+             0    10    10   Class java/lang/Exception
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      11     0     e   Ljava/lang/Exception;
+      StackMapTable: number_of_entries = 1
+        frame_type = 74 /* same_locals_1_stack_item */
+          stack = [ class java/lang/Exception ]
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+  Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 17, attributes: 1
+  public int stub;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+
+  public int remove;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iconst_1
+         x: putfield      #x                  // Field stub:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public int addOne(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+            0       4     1 value   I
+
+  public void toBeRemoved(java.lang.String);
+    descriptor: (Ljava/lang/String;)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+            0       8     1   foo   Ljava/lang/String;
+
+  public java.lang.String toBeIgnoredObj();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public void toBeIgnoredV();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public boolean toBeIgnoredZ();
+    descriptor: ()Z
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public byte toBeIgnoredB();
+    descriptor: ()B
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public char toBeIgnoredC();
+    descriptor: ()C
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public short toBeIgnoredS();
+    descriptor: ()S
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public int toBeIgnoredI();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public float toBeIgnoredF();
+    descriptor: ()F
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public double toBeIgnoredD();
+    descriptor: ()D
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+  public int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=2, args_size=2
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String not supported on host side
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+            0      10     1 value   I
+
+  public int addTwo_host(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+            0       4     1 value   I
+
+  public static native int nativeAddThree(int);
+    descriptor: (I)I
+    flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+  public static int addThree_host(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_3
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0 value   I
+
+  public java.lang.String unsupportedMethod();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: ldc           #x                 // String This value shouldn\'t be seen on the host side.
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       3     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+  Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 8, attributes: 5
+  public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: invokedynamic #x,  0              // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: putfield      #x                 // Field mSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      14     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.util.function.Supplier<java.lang.Integer> getSupplier();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static java.lang.Integer lambda$getSupplier_static$3();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: bipush        8
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+
+  private static java.lang.Integer lambda$getSupplier$2();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: bipush        7
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+
+  private static java.lang.Integer lambda$static$1();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: bipush        6
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+
+  private static java.lang.Integer lambda$new$0();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_5
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: putstatic     #x                 // Field sSupplier:Ljava/util/function/Supplier;
+         x: return
+      LineNumberTable:
+}
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x()
+    android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+BootstrapMethods:
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$new$0:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier$2:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$static$1:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+InnerClasses:
+  public static #x= #x of #x;          // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+  public static final #x= #x of #x;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+  Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 8, attributes: 5
+  public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: invokedynamic #x,  0              // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: putfield      #x                 // Field mSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      14     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.util.function.Supplier<java.lang.Integer> getSupplier();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static java.lang.Integer lambda$getSupplier_static$3();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_4
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+
+  private static java.lang.Integer lambda$getSupplier$2();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_3
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+
+  private static java.lang.Integer lambda$static$1();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_2
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+
+  private static java.lang.Integer lambda$new$0();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_1
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: putstatic     #x                 // Field sSupplier:Ljava/util/function/Supplier;
+         x: return
+      LineNumberTable:
+}
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x()
+    android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+BootstrapMethods:
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$new$0:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier$2:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$static$1:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+InnerClasses:
+  public static #x= #x of #x;          // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+  public static final #x= #x of #x;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
+  Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 3, attributes: 3
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo;
+
+  public static void startThread(java.lang.Thread);
+    descriptor: (Ljava/lang/Thread;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: iconst_1
+         x: invokevirtual #x                  // Method java/lang/Thread.setDaemon:(Z)V
+         x: aload_0
+         x: invokevirtual #x                 // Method java/lang/Thread.start:()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0 thread   Ljava/lang/Thread;
+
+  public static int add(int, int);
+    descriptor: (II)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_0
+         x: iload_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0     a   I
+            0       4     1     b   I
+}
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+InnerClasses:
+  public static #x= #x of #x;          // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
+  Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 5, attributes: 5
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace;
+
+  public static boolean nonStaticMethodCallReplaceTester() throws java.lang.Exception;
+    descriptor: ()Z
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=3, locals=2, args_size=0
+         x: new           #x                  // class java/util/concurrent/atomic/AtomicBoolean
+         x: dup
+         x: iconst_0
+         x: invokespecial #x                  // Method java/util/concurrent/atomic/AtomicBoolean."<init>":(Z)V
+         x: astore_0
+         x: new           #x                 // class java/lang/Thread
+        x: dup
+        x: aload_0
+        x: invokedynamic #x,  0             // InvokeDynamic #x:run:(Ljava/util/concurrent/atomic/AtomicBoolean;)Ljava/lang/Runnable;
+        x: invokespecial #x                 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
+        x: astore_1
+        x: aload_1
+        x: invokevirtual #x                 // Method java/lang/Thread.start:()V
+        x: aload_1
+        x: invokevirtual #x                 // Method java/lang/Thread.join:()V
+        x: aload_0
+        x: invokevirtual #x                 // Method java/util/concurrent/atomic/AtomicBoolean.get:()Z
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            9      27     0    ab   Ljava/util/concurrent/atomic/AtomicBoolean;
+           23      13     1    th   Ljava/lang/Thread;
+    Exceptions:
+      throws java.lang.Exception
+
+  public static int staticMethodCallReplaceTester();
+    descriptor: ()I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: iconst_1
+         x: iconst_2
+         x: invokestatic  #x                 // Method originalAdd:(II)I
+         x: ireturn
+      LineNumberTable:
+
+  private static int originalAdd(int, int);
+    descriptor: (II)I
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_0
+         x: iload_1
+         x: iadd
+         x: iconst_1
+         x: isub
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0     a   I
+            0       6     1     b   I
+
+  private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
+    descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokestatic  #x                 // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
+         x: invokevirtual #x                 // Method java/lang/Thread.isDaemon:()Z
+         x: invokevirtual #x                 // Method java/util/concurrent/atomic/AtomicBoolean.set:(Z)V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0    ab   Ljava/util/concurrent/atomic/AtomicBoolean;
+}
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+BootstrapMethods:
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()V
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.lambda$nonStaticMethodCallReplaceTester$0:(Ljava/util/concurrent/atomic/AtomicBoolean;)V
+      #x ()V
+InnerClasses:
+  public static #x= #x of #x;          // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+  public static final #x= #x of #x;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+  Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 14, attributes: 2
+  int value;
+    descriptor: I
+    flags: (0x0000)
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+
+  public static native int nativeAddTwo(int);
+    descriptor: (I)I
+    flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public static int nativeAddTwo_should_be_like_this(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iload_0
+         x: invokestatic  #x                  // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0   arg   I
+
+  public static native long nativeLongPlus(long, long);
+    descriptor: (JJ)J
+    flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public static long nativeLongPlus_should_be_like_this(long, long);
+    descriptor: (JJ)J
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=4, args_size=2
+         x: lload_0
+         x: lload_2
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+         x: lreturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  arg1   J
+            0       6     2  arg2   J
+
+  public void setValue(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: iload_1
+         x: putfield      #x                 // Field value:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+            0       6     1     v   I
+
+  public native int nativeNonStaticAddToValue(int);
+    descriptor: (I)I
+    flags: (0x0101) ACC_PUBLIC, ACC_NATIVE
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public int nativeNonStaticAddToValue_should_be_like_this(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: iload_1
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+            0       6     1   arg   I
+
+  public static native void nativeStillNotSupported();
+    descriptor: ()V
+    flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestThrow
+
+  public static native void nativeStillKeep();
+    descriptor: ()V
+    flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+  public static void nativeStillNotSupported_should_be_like_this();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+
+  public static native byte nativeBytePlus(byte, byte);
+    descriptor: (BB)B
+    flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public void notNativeRedirected();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public static void notNativeStaticRedirected();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+  x: #x(#x=s#x)
+    android.hosttest.annotation.HostSideTestRedirectionClass(
+      value="TinyFrameworkNative_host"
+    )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+  Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 7, attributes: 2
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host;
+
+  public static int nativeAddTwo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0   arg   I
+
+  public static long nativeLongPlus(long, long);
+    descriptor: (JJ)J
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=4, args_size=2
+         x: lload_0
+         x: lload_2
+         x: ladd
+         x: lreturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  arg1   J
+            0       4     2  arg2   J
+
+  public static int nativeNonStaticAddToValue(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative, int);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: getfield      #x                  // Field com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.value:I
+         x: iload_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       7     0 source   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+            0       7     1   arg   I
+
+  public static byte nativeBytePlus(byte, byte);
+    descriptor: (BB)B
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_0
+         x: iload_1
+         x: iadd
+         x: i2b
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  arg1   B
+            0       5     1  arg2   B
+
+  public static void notNativeRedirected(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=0, locals=1, args_size=1
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       1     0 source   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+
+  public static void notNativeStaticRedirected();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=0, locals=0, args_size=0
+         x: return
+      LineNumberTable:
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 5
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+            0       5     1 this$0   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    MethodParameters:
+      Name                           Flags
+      <no name>                      final mandated
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_1
+         x: invokestatic  #x                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+}
+Signature: #x                          // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x                 // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 5
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+    descriptor: ()V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_2
+         x: invokestatic  #x                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+}
+Signature: #x                          // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x                 // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 5
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+            0       5     1 this$0   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    MethodParameters:
+      Name                           Flags
+      <no name>                      final mandated
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_3
+         x: invokestatic  #x                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+}
+Signature: #x                          // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x                // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 5
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+    descriptor: ()V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_4
+         x: invokestatic  #x                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+}
+Signature: #x                          // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x                // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 1, attributes: 3
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iload_1
+         x: putfield      #x                  // Field value:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+            0      10     1     x   I
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  public static #x= #x of #x;           // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 1, attributes: 3
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iconst_5
+         x: putfield      #x                  // Field value:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+            0      10     1 this$0   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    MethodParameters:
+      Name                           Flags
+      <no name>                      final mandated
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  public #x= #x of #x;                  // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 5
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+    descriptor: ()V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: bipush        7
+         x: invokestatic  #x                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+}
+Signature: #x                          // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x                // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  public static #x= #x of #x;          // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 1, attributes: 3
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: bipush        8
+         x: putfield      #x                  // Field value:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass;
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  public static #x= #x of #x;          // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;           // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 3
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: bipush        6
+         x: putfield      #x                  // Field value:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+         x: dup
+         x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+         x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  public static #x= #x of #x;           // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+  public static #x= #x of #x;           // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+  interfaces: 0, fields: 0, methods: 1, attributes: 3
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: iload_1
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+            0       6     1     x   I
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+  public static #x= #x of #x;           // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;           // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 4, attributes: 4
+  public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+  public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+         x: dup
+         x: aload_0
+        x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+        x: putfield      #x                 // Field mSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      17     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+  public java.util.function.Supplier<java.lang.Integer> getSupplier();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+         x: dup
+         x: aload_0
+         x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       9     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+         x: dup
+         x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+         x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+         x: dup
+         x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+         x: putstatic     #x                 // Field sSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+InnerClasses:
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+  public static #x= #x of #x;          // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;          // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;          // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public #x= #x of #x;                 // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;          // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+  Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 2
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect;
+
+  public static int foo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: new           #x                  // class com/unsupported/UnsupportedClass
+         x: dup
+         x: iload_0
+         x: invokespecial #x                  // Method com/unsupported/UnsupportedClass."<init>":(I)V
+         x: invokevirtual #x                 // Method com/unsupported/UnsupportedClass.getValue:()I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      12     0 value   I
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
+  Compiled from "TinyFrameworkRenamedClassCaller.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 2
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller;
+
+  public static int foo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+         x: dup
+         x: iload_0
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed."<init>":(I)V
+         x: invokevirtual #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      12     0 value   I
+}
+SourceFile: "TinyFrameworkRenamedClassCaller.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.class
+  Compiled from "TinyFrameworkToBeRenamed.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 2
+  private final int mValue;
+    descriptor: I
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iload_1
+         x: putfield      #x                  // Field mValue:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+            0      10     1 value   I
+
+  public int getValue();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: getfield      #x                  // Field mValue:I
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+}
+SourceFile: "TinyFrameworkToBeRenamed.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/A.class
+  Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.A
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/packagetest/A
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.packagetest.A();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/packagetest/A;
+}
+SourceFile: "A.java"
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/B.class
+  Compiled from "B.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.B
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/packagetest/B
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.packagetest.B();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/packagetest/B;
+}
+SourceFile: "B.java"
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/sub/A.class
+  Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.packagetest.sub.A();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/packagetest/sub/A;
+}
+SourceFile: "A.java"
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/sub/B.class
+  Compiled from "B.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.sub.B
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/packagetest/sub/B
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.packagetest.sub.B();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/packagetest/sub/B;
+}
+SourceFile: "B.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class
+  Compiled from "C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.C1();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/C1;
+}
+SourceFile: "C1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class
+  Compiled from "C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.C2();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/subclasstest/C1."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/C2;
+}
+SourceFile: "C2.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class
+  Compiled from "C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.C3();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/subclasstest/C2."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/C3;
+}
+SourceFile: "C3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class
+  Compiled from "CA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/CA
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.CA();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/CA;
+}
+SourceFile: "CA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class
+  Compiled from "CB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.CB();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/CB;
+}
+SourceFile: "CB.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.class
+  Compiled from "Class_C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/subclasstest/C1."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_C1;
+}
+SourceFile: "Class_C1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.class
+  Compiled from "Class_C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/subclasstest/C2."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_C2;
+}
+SourceFile: "Class_C2.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.class
+  Compiled from "Class_C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C3
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/subclasstest/C3."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_C3;
+}
+SourceFile: "Class_C3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA.class
+  Compiled from "Class_CA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA extends com.android.hoststubgen.test.tinyframework.subclasstest.CA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/CA
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/subclasstest/CA."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_CA;
+}
+SourceFile: "Class_CA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB.class
+  Compiled from "Class_CB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB extends com.android.hoststubgen.test.tinyframework.subclasstest.CB
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/subclasstest/CB."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_CB;
+}
+SourceFile: "Class_CB.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA.class
+  Compiled from "Class_CB_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA extends com.android.hoststubgen.test.tinyframework.subclasstest.CB implements com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+  interfaces: 1, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method com/android/hoststubgen/test/tinyframework/subclasstest/CB."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA;
+}
+SourceFile: "Class_CB_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.class
+  Compiled from "Class_I1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I1;
+}
+SourceFile: "Class_I1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.class
+  Compiled from "Class_I1_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I1,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
+  super_class: #x                         // java/lang/Object
+  interfaces: 2, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA;
+}
+SourceFile: "Class_I1_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.class
+  Compiled from "Class_I2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 implements com.android.hoststubgen.test.tinyframework.subclasstest.I2
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I2;
+}
+SourceFile: "Class_I2.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.class
+  Compiled from "Class_I3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.I3
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I3;
+}
+SourceFile: "Class_I3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA.class
+  Compiled from "Class_I3_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I3,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA
+  super_class: #x                         // java/lang/Object
+  interfaces: 2, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA;
+}
+SourceFile: "Class_I3_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA.class
+  Compiled from "Class_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IA;
+}
+SourceFile: "Class_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1.class
+  Compiled from "Class_IA_I1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.IA,com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1
+  super_class: #x                         // java/lang/Object
+  interfaces: 2, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1;
+}
+SourceFile: "Class_IA_I1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3.class
+  Compiled from "Class_IA_I3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.IA,com.android.hoststubgen.test.tinyframework.subclasstest.I3
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3
+  super_class: #x                         // java/lang/Object
+  interfaces: 2, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3;
+}
+SourceFile: "Class_IA_I3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB.class
+  Compiled from "Class_IB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB implements com.android.hoststubgen.test.tinyframework.subclasstest.IB
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IB;
+}
+SourceFile: "Class_IB.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA.class
+  Compiled from "Class_IB_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.IB,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA
+  super_class: #x                         // java/lang/Object
+  interfaces: 2, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA;
+}
+SourceFile: "Class_IB_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_None.class
+  Compiled from "Class_None.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_None
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_None
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 1
+  public com.android.hoststubgen.test.tinyframework.subclasstest.Class_None();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_None;
+}
+SourceFile: "Class_None.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class
+  Compiled from "I1.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/I1
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "I1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class
+  Compiled from "I2.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/I2
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "I2.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class
+  Compiled from "I3.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/I3
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "I3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class
+  Compiled from "IA.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/IA
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class
+  Compiled from "IB.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/IB
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "IB.java"
+## Class: com/supported/UnsupportedClass.class
+  Compiled from "UnsupportedClass.java"
+public class com.supported.UnsupportedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/supported/UnsupportedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 2
+  private final int mValue;
+    descriptor: I
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+
+  public com.supported.UnsupportedClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iload_1
+         x: putfield      #x                  // Field mValue:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/supported/UnsupportedClass;
+            0      10     1 value   I
+
+  public int getValue();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: getfield      #x                  // Field mValue:I
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/supported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/unsupported/UnsupportedClass.class
+  Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                         // com/unsupported/UnsupportedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 2
+  public com.unsupported.UnsupportedClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                  // Method java/lang/Object."<init>":()V
+         x: new           #x                  // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                  // String This class is not supported
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      14     0  this   Lcom/unsupported/UnsupportedClass;
+            0      14     1 value   I
+
+  public int getValue();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: new           #x                  // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                  // String This class is not supported
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/unsupported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt
new file mode 100644
index 0000000..84a8373
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt
@@ -0,0 +1,3727 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+  Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestClassLoadHook
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  public abstract java.lang.String value();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+  Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestKeep
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestRedirect.class
+  Compiled from "HostSideTestRedirect.java"
+public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestRedirect
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRedirect.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestRedirectionClass.class
+  Compiled from "HostSideTestRedirectionClass.java"
+public interface android.hosttest.annotation.HostSideTestRedirectionClass extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestRedirectionClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  public abstract java.lang.String value();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestRedirectionClass.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+  Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestRemove
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestStaticInitializerKeep.class
+  Compiled from "HostSideTestStaticInitializerKeep.java"
+public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestStaticInitializerKeep
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestStaticInitializerKeep.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+  Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestSubstitute
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  public abstract java.lang.String suffix();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+  Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestThrow
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+  Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestWholeClassKeep
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
+  Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 4
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0     a   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub.class
+  Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 4
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int addOne(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0     a   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;             // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl.class
+  Compiled from "IPretendingAidl.java"
+public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 4
+}
+InnerClasses:
+  public static #x= #x of #x;            // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+## Class: com/android/hoststubgen/test/tinyframework/R$Nested.class
+  Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R$Nested
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/R$Nested
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 4
+  public static int[] ARRAY;
+    descriptor: [I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.R$Nested();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/R$Nested;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: iconst_1
+         x: newarray       int
+         x: dup
+         x: iconst_0
+         x: iconst_1
+         x: iastore
+         x: putstatic     #x                 // Field ARRAY:[I
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;             // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+SourceFile: "R.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/R
+## Class: com/android/hoststubgen/test/tinyframework/R.class
+  Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/R
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 4
+  public com.android.hoststubgen.test.tinyframework.R();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/R;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;             // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+SourceFile: "R.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/R$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class
+  Compiled from "TinyFrameworkAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 7, attributes: 3
+  public int keep;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+         x: ldc           #x                  // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iconst_1
+         x: putfield      #x                 // Field keep:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public int addOne(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+            0       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+            0       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeAddThree(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_3
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.String unsupportedMethod();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String Unreachable
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestThrow
+
+  public int toBeIgnored();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_0
+         x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestIgnore
+}
+SourceFile: "TinyFrameworkAnnotations.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x(#x=s#x)
+    android.hosttest.annotation.HostSideTestClassLoadHook(
+      value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+    )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+  Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 3, attributes: 3
+  public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+    descriptor: Ljava/util/Set;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/Set<Ljava/lang/Class<*>;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+    descriptor: ()V
+    flags: (0x0002) ACC_PRIVATE
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void onClassLoaded(java.lang.Class<?>);
+    descriptor: (Ljava/lang/Class;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: getstatic     #x                 // Field sLoadedClasses:Ljava/util/Set;
+         x: aload_0
+         x: invokeinterface #x,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+         x: pop
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0 clazz   Ljava/lang/Class;
+      LocalVariableTypeTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0 clazz   Ljava/lang/Class<*>;
+    Signature: #x                          // (Ljava/lang/Class<*>;)V
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class java/util/HashSet
+         x: dup
+         x: invokespecial #x                 // Method java/util/HashSet."<init>":()V
+         x: putstatic     #x                 // Field sLoadedClasses:Ljava/util/Set;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class
+  Compiled from "TinyFrameworkClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 4, attributes: 3
+  public int keep;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iconst_1
+         x: putfield      #x                 // Field keep:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int addOne(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+            0       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+            0       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.String unsupportedMethod();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String Unreachable
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestThrow
+}
+SourceFile: "TinyFrameworkClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+  Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 0, attributes: 3
+  public static boolean sInitialized;
+    descriptor: Z
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.lang.Object sObject;
+    descriptor: Ljava/lang/Object;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+  Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 1, attributes: 3
+  public static boolean sInitialized;
+    descriptor: Z
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.lang.Object sObject;
+    descriptor: Ljava/lang/Object;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+         x: ldc           #x                 // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: iconst_1
+         x: putstatic     #x                 // Field sInitialized:Z
+        x: new           #x                  // class java/lang/Object
+        x: dup
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: putstatic     #x                 // Field sObject:Ljava/lang/Object;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x(#x=s#x)
+    android.hosttest.annotation.HostSideTestClassLoadHook(
+      value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+    )
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x()
+    android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+  Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+  minor version: 0
+  major version: 65
+  flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+  super_class: #x                         // java/lang/Enum
+  interfaces: 0, fields: 6, methods: 7, attributes: 4
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private final java.lang.String mLongName;
+    descriptor: Ljava/lang/String;
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private final java.lang.String mShortName;
+    descriptor: Ljava/lang/String;
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+    descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: getstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+         x: invokevirtual #x                 // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;".clone:()Ljava/lang/Object;
+         x: checkcast     #x                 // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;"
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+    descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: aload_0
+         x: invokestatic  #x                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+         x: checkcast     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  name   Ljava/lang/String;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      mandated
+
+  private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+    descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+    flags: (0x0002) ACC_PRIVATE
+    Code:
+      stack=3, locals=5, args_size=5
+         x: aload_0
+         x: aload_1
+         x: iload_2
+         x: invokespecial #x                 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+         x: aload_0
+         x: aload_3
+         x: putfield      #x                 // Field mLongName:Ljava/lang/String;
+        x: aload_0
+        x: aload         4
+        x: putfield      #x                 // Field mShortName:Ljava/lang/String;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      18     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+            0      18     3 longName   Ljava/lang/String;
+            0      18     4 shortName   Ljava/lang/String;
+    Signature: #x                          // (Ljava/lang/String;Ljava/lang/String;)V
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      synthetic
+      <no name>                      synthetic
+      <no name>
+      <no name>
+
+  public java.lang.String getLongName();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: getfield      #x                 // Field mLongName:Ljava/lang/String;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.lang.String getShortName();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: getfield      #x                 // Field mShortName:Ljava/lang/String;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: iconst_3
+         x: anewarray     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: dup
+         x: iconst_0
+         x: getstatic     #x                 // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+         x: aastore
+        x: dup
+        x: iconst_1
+        x: getstatic     #x                 // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: aastore
+        x: dup
+        x: iconst_2
+        x: getstatic     #x                 // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: aastore
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=6, locals=0, args_size=0
+         x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: dup
+         x: ldc           #x                 // String RED
+         x: iconst_0
+         x: ldc           #x                 // String Red
+         x: ldc           #x                 // String R
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+        x: putstatic     #x                 // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: dup
+        x: ldc           #x                 // String GREEN
+        x: iconst_1
+        x: ldc           #x                 // String Green
+        x: ldc           #x                 // String G
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+        x: putstatic     #x                 // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: dup
+        x: ldc           #x                 // String BLUE
+        x: iconst_2
+        x: ldc           #x                 // String Blue
+        x: ldc           #x                 // String B
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+        x: putstatic     #x                 // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: invokestatic  #x                 // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: putstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+Signature: #x                           // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+  Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+  minor version: 0
+  major version: 65
+  flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+  super_class: #x                         // java/lang/Enum
+  interfaces: 0, fields: 3, methods: 5, attributes: 4
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+    descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: getstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+         x: invokevirtual #x                 // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;".clone:()Ljava/lang/Object;
+         x: checkcast     #x                 // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;"
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+    descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: aload_0
+         x: invokestatic  #x                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+         x: checkcast     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  name   Ljava/lang/String;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      mandated
+
+  private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+    descriptor: (Ljava/lang/String;I)V
+    flags: (0x0002) ACC_PRIVATE
+    Code:
+      stack=3, locals=3, args_size=3
+         x: aload_0
+         x: aload_1
+         x: iload_2
+         x: invokespecial #x                 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       7     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    Signature: #x                          // ()V
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      synthetic
+      <no name>                      synthetic
+
+  private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: iconst_2
+         x: anewarray     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: dup
+         x: iconst_0
+         x: getstatic     #x                 // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+         x: aastore
+        x: dup
+        x: iconst_1
+        x: getstatic     #x                 // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: aastore
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: dup
+         x: ldc           #x                 // String CAT
+         x: iconst_0
+         x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;I)V
+        x: putstatic     #x                 // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+        x: dup
+        x: ldc           #x                 // String DOG
+        x: iconst_1
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;I)V
+        x: putstatic     #x                 // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: invokestatic  #x                 // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: putstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+Signature: #x                           // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+  Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 3
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int testException();
+    descriptor: ()I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=0
+         x: new           #x                 // class java/lang/IllegalStateException
+         x: dup
+         x: ldc           #x                 // String Inner exception
+         x: invokespecial #x                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+         x: athrow
+        x: astore_0
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: ldc           #x                 // String Outer exception
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+        x: athrow
+      Exception table:
+         from    to  target type
+             0    10    10   Class java/lang/Exception
+      StackMapTable: number_of_entries = 1
+        frame_type = 74 /* same_locals_1_stack_item */
+          stack = [ class java/lang/Exception ]
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      11     0     e   Ljava/lang/Exception;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+  Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 15, attributes: 2
+  public int stub;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                  // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iconst_1
+         x: putfield      #x                 // Field stub:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int addOne(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+            0       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.String toBeIgnoredObj();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aconst_null
+         x: areturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public void toBeIgnoredV();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=0, locals=1, args_size=1
+         x: return
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public boolean toBeIgnoredZ();
+    descriptor: ()Z
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_0
+         x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public byte toBeIgnoredB();
+    descriptor: ()B
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_0
+         x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public char toBeIgnoredC();
+    descriptor: ()C
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_0
+         x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public short toBeIgnoredS();
+    descriptor: ()S
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_0
+         x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int toBeIgnoredI();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_0
+         x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public float toBeIgnoredF();
+    descriptor: ()F
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: fconst_0
+         x: freturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public double toBeIgnoredD();
+    descriptor: ()D
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: dconst_0
+         x: dreturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_1
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+            0       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeAddThree(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_3
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.String unsupportedMethod();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String Unreachable
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+  Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 8, attributes: 6
+  public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: putfield      #x                 // Field mSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      14     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.util.function.Supplier<java.lang.Integer> getSupplier();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static java.lang.Integer lambda$getSupplier_static$3();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: bipush        8
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$getSupplier$2();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: bipush        7
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$static$1();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: bipush        6
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$new$0();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_5
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: putstatic     #x                 // Field sSupplier:Ljava/util/function/Supplier;
+         x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;            // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+  public static final #x= #x of #x;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x()
+    android.hosttest.annotation.HostSideTestStaticInitializerKeep
+BootstrapMethods:
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$new$0:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier$2:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$static$1:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+  Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 8, attributes: 6
+  public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: putfield      #x                 // Field mSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      14     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.util.function.Supplier<java.lang.Integer> getSupplier();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static java.lang.Integer lambda$getSupplier_static$3();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_4
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$getSupplier$2();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_3
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$static$1();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_2
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$new$0();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: iconst_1
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+         x: putstatic     #x                 // Field sSupplier:Ljava/util/function/Supplier;
+         x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+  public static final #x= #x of #x;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x()
+    android.hosttest.annotation.HostSideTestStaticInitializerKeep
+BootstrapMethods:
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$new$0:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier$2:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$static$1:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
+  Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 3, attributes: 4
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void startThread(java.lang.Thread);
+    descriptor: (Ljava/lang/Thread;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: iconst_1
+         x: invokevirtual #x                 // Method java/lang/Thread.setDaemon:(Z)V
+         x: aload_0
+         x: invokevirtual #x                 // Method java/lang/Thread.start:()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0 thread   Ljava/lang/Thread;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int add(int, int);
+    descriptor: (II)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_0
+         x: iload_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0     a   I
+            0       4     1     b   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;             // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
+  Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 4, attributes: 6
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static boolean nonStaticMethodCallReplaceTester() throws java.lang.Exception;
+    descriptor: ()Z
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=3, locals=2, args_size=0
+         x: new           #x                 // class java/util/concurrent/atomic/AtomicBoolean
+         x: dup
+         x: iconst_0
+         x: invokespecial #x                 // Method java/util/concurrent/atomic/AtomicBoolean."<init>":(Z)V
+         x: astore_0
+         x: new           #x                 // class java/lang/Thread
+        x: dup
+        x: aload_0
+        x: invokedynamic #x,  0             // InvokeDynamic #x:run:(Ljava/util/concurrent/atomic/AtomicBoolean;)Ljava/lang/Runnable;
+        x: invokespecial #x                 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
+        x: astore_1
+        x: aload_1
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.startThread:(Ljava/lang/Thread;)V
+        x: aload_1
+        x: invokevirtual #x                 // Method java/lang/Thread.join:()V
+        x: aload_0
+        x: invokevirtual #x                 // Method java/util/concurrent/atomic/AtomicBoolean.get:()Z
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            9      27     0    ab   Ljava/util/concurrent/atomic/AtomicBoolean;
+           23      13     1    th   Ljava/lang/Thread;
+    Exceptions:
+      throws java.lang.Exception
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int staticMethodCallReplaceTester();
+    descriptor: ()I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: iconst_1
+         x: iconst_2
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.add:(II)I
+         x: ireturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
+    descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokestatic  #x                 // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
+         x: invokevirtual #x                 // Method java/lang/Thread.isDaemon:()Z
+         x: invokevirtual #x                 // Method java/util/concurrent/atomic/AtomicBoolean.set:(Z)V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0    ab   Ljava/util/concurrent/atomic/AtomicBoolean;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;            // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+  public static final #x= #x of #x;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+BootstrapMethods:
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()V
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.lambda$nonStaticMethodCallReplaceTester$0:(Ljava/util/concurrent/atomic/AtomicBoolean;)V
+      #x ()V
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+  Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 14, attributes: 3
+  int value;
+    descriptor: I
+    flags: (0x0000)
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeAddTwo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iload_0
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+         x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public static int nativeAddTwo_should_be_like_this(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iload_0
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0   arg   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static long nativeLongPlus(long, long);
+    descriptor: (JJ)J
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=4, args_size=2
+         x: lload_0
+         x: lload_2
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+         x: lreturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public static long nativeLongPlus_should_be_like_this(long, long);
+    descriptor: (JJ)J
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=4, args_size=2
+         x: lload_0
+         x: lload_2
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+         x: lreturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  arg1   J
+            0       6     2  arg2   J
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public void setValue(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: iload_1
+         x: putfield      #x                 // Field value:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+            0       6     1     v   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int nativeNonStaticAddToValue(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: iload_1
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+         x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public int nativeNonStaticAddToValue_should_be_like_this(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: iload_1
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+            0       6     1   arg   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void nativeStillNotSupported();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=3, locals=0, args_size=0
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String Unreachable
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestThrow
+
+  public static native void nativeStillKeep();
+    descriptor: ()V
+    flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void nativeStillNotSupported_should_be_like_this();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+         x: athrow
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static byte nativeBytePlus(byte, byte);
+    descriptor: (BB)B
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_0
+         x: iload_1
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeBytePlus:(BB)B
+         x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public void notNativeRedirected();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.notNativeRedirected:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+         x: return
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public static void notNativeStaticRedirected();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=0, locals=0, args_size=0
+         x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.notNativeStaticRedirected:()V
+         x: return
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+  x: #x(#x=s#x)
+    android.hosttest.annotation.HostSideTestRedirectionClass(
+      value="TinyFrameworkNative_host"
+    )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+  Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 7, attributes: 3
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeAddTwo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: iload_0
+         x: iconst_2
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0   arg   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static long nativeLongPlus(long, long);
+    descriptor: (JJ)J
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=4, args_size=2
+         x: lload_0
+         x: lload_2
+         x: ladd
+         x: lreturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       4     0  arg1   J
+            0       4     2  arg2   J
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeNonStaticAddToValue(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative, int);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: getfield      #x                 // Field com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.value:I
+         x: iload_1
+         x: iadd
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       7     0 source   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+            0       7     1   arg   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static byte nativeBytePlus(byte, byte);
+    descriptor: (BB)B
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: iload_0
+         x: iload_1
+         x: iadd
+         x: i2b
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  arg1   B
+            0       5     1  arg2   B
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void notNativeRedirected(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=0, locals=1, args_size=1
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       1     0 source   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void notNativeStaticRedirected();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=0, locals=0, args_size=0
+         x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 6
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+            0       5     1 this$0   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      final mandated
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_1
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+EnclosingMethod: #x.#x                 // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 6
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+    descriptor: ()V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_2
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+EnclosingMethod: #x.#x                 // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 6
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+            0       5     1 this$0   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      final mandated
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_3
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+EnclosingMethod: #x.#x                // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 6
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+    descriptor: ()V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: iconst_4
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+EnclosingMethod: #x.#x                // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 1, attributes: 4
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iload_1
+         x: putfield      #x                 // Field value:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+            0      10     1     x   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;             // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 1, attributes: 4
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iconst_5
+         x: putfield      #x                 // Field value:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+            0      10     1 this$0   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      final mandated
+}
+InnerClasses:
+  public #x= #x of #x;                    // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 3, attributes: 6
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+    descriptor: ()V
+    flags: (0x0000)
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: bipush        7
+         x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;          // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+EnclosingMethod: #x.#x                // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 1, attributes: 4
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: bipush        8
+         x: putfield      #x                 // Field value:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;           // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 4
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: bipush        6
+         x: putfield      #x                 // Field value:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      11     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+         x: dup
+         x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+         x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;             // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+  public static #x= #x of #x;           // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+  interfaces: 0, fields: 0, methods: 1, attributes: 4
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: iload_1
+         x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+            0       6     1     x   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;             // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;            // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 4, attributes: 5
+  public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+         x: dup
+         x: aload_0
+        x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+        x: putfield      #x                 // Field mSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      17     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.util.function.Supplier<java.lang.Integer> getSupplier();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+         x: dup
+         x: aload_0
+         x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+         x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       9     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+         x: dup
+         x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+         x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+         x: dup
+         x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+         x: putstatic     #x                 // Field sSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+  public static #x= #x of #x;            // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;           // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;           // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public #x= #x of #x;                  // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;          // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+  Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 3
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int foo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: new           #x                 // class com/supported/UnsupportedClass
+         x: dup
+         x: iload_0
+         x: invokespecial #x                 // Method com/supported/UnsupportedClass."<init>":(I)V
+         x: invokevirtual #x                 // Method com/supported/UnsupportedClass.getValue:()I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      12     0 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
+  Compiled from "TinyFrameworkRenamedClassCaller.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 3
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int foo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: new           #x                 // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+         x: dup
+         x: iload_0
+         x: invokespecial #x                 // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed."<init>":(I)V
+         x: invokevirtual #x                 // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      12     0 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkRenamedClassCaller.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/A.class
+  Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.A
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/packagetest/A
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "A.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/sub/A.class
+  Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "A.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class
+  Compiled from "C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "C1.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class
+  Compiled from "C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "C2.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class
+  Compiled from "C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "C3.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class
+  Compiled from "CA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/CA
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "CA.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class
+  Compiled from "CB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "CB.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.class
+  Compiled from "Class_C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_C1.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.class
+  Compiled from "Class_C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_C2.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.class
+  Compiled from "Class_C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C3
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_C3.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.class
+  Compiled from "Class_I1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_I1.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.class
+  Compiled from "Class_I1_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I1,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
+  super_class: #x                         // java/lang/Object
+  interfaces: 2, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_I1_IA.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.class
+  Compiled from "Class_I2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 implements com.android.hoststubgen.test.tinyframework.subclasstest.I2
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_I2.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.class
+  Compiled from "Class_I3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.I3
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_I3.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class
+  Compiled from "I1.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/I1
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "I1.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class
+  Compiled from "I2.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/I2
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "I2.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class
+  Compiled from "I3.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/I3
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "I3.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class
+  Compiled from "IA.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/IA
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "IA.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class
+  Compiled from "IB.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/IB
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "IB.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/supported/UnsupportedClass.class
+  Compiled from "UnsupportedClass.java"
+public class com.supported.UnsupportedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/supported/UnsupportedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 3
+  private final int mValue;
+    descriptor: I
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.supported.UnsupportedClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iload_1
+         x: putfield      #x                 // Field mValue:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/supported/UnsupportedClass;
+            0      10     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int getValue();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: getfield      #x                 // Field mValue:I
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/supported/UnsupportedClass;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/unsupported/UnsupportedClass.class
+  Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/unsupported/UnsupportedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 3
+  public com.unsupported.UnsupportedClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String This class is not supported
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      14     0  this   Lcom/unsupported/UnsupportedClass;
+            0      14     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int getValue();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=3, locals=1, args_size=1
+         x: new           #x                 // class java/lang/RuntimeException
+         x: dup
+         x: ldc           #x                 // String This class is not supported
+         x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+         x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/unsupported/UnsupportedClass;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.class
+  Compiled from "TinyFrameworkToBeRenamed.java"
+public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 3
+  private final int mValue;
+    descriptor: I
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=2, locals=2, args_size=2
+         x: aload_0
+         x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+         x: aload_0
+         x: iload_1
+         x: putfield      #x                 // Field mValue:I
+         x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+            0      10     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int getValue();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         x: aload_0
+         x: getfield      #x                 // Field mValue:I
+         x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkToBeRenamed.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
new file mode 100644
index 0000000..49769e6
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
@@ -0,0 +1,4896 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+  Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestClassLoadHook
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 2, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class android/hosttest/annotation/HostSideTestClassLoadHook
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public abstract java.lang.String value();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+  Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestKeep
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class android/hosttest/annotation/HostSideTestKeep
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestRedirect.class
+  Compiled from "HostSideTestRedirect.java"
+public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestRedirect
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class android/hosttest/annotation/HostSideTestRedirect
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "HostSideTestRedirect.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestRedirectionClass.class
+  Compiled from "HostSideTestRedirectionClass.java"
+public interface android.hosttest.annotation.HostSideTestRedirectionClass extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestRedirectionClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 2, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class android/hosttest/annotation/HostSideTestRedirectionClass
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public abstract java.lang.String value();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestRedirectionClass.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+  Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestRemove
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class android/hosttest/annotation/HostSideTestRemove
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestStaticInitializerKeep.class
+  Compiled from "HostSideTestStaticInitializerKeep.java"
+public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestStaticInitializerKeep
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class android/hosttest/annotation/HostSideTestStaticInitializerKeep
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "HostSideTestStaticInitializerKeep.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+  Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestSubstitute
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 2, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class android/hosttest/annotation/HostSideTestSubstitute
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public abstract java.lang.String suffix();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+  Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestThrow
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class android/hosttest/annotation/HostSideTestThrow
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x,e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+  Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+  minor version: 0
+  major version: 65
+  flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+  this_class: #x                          // android/hosttest/annotation/HostSideTestWholeClassKeep
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class android/hosttest/annotation/HostSideTestWholeClassKeep
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+  x: #x(#x=[e#x.#x])
+    java.lang.annotation.Target(
+      value=[Ljava/lang/annotation/ElementType;.TYPE]
+    )
+  x: #x(#x=e#x.#x)
+    java.lang.annotation.Retention(
+      value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+    )
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
+  Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 3, attributes: 4
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+         x: ldc           #x                 // String addTwo
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: iconst_2
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0     a   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;          // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub.class
+  Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 3, attributes: 4
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int addOne(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+         x: ldc           #x                 // String addOne
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: iconst_1
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0     a   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl.class
+  Compiled from "IPretendingAidl.java"
+public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 4
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+InnerClasses:
+  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;          // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+## Class: com/android/hoststubgen/test/tinyframework/R$Nested.class
+  Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R$Nested
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/R$Nested
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 4
+  public static int[] ARRAY;
+    descriptor: [I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.R$Nested();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/R$Nested
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/R$Nested;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/R$Nested
+         x: ldc           #x                 // String <clinit>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/R$Nested
+        x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: iconst_1
+        x: newarray       int
+        x: dup
+        x: iconst_0
+        x: iconst_1
+        x: iastore
+        x: putstatic     #x                 // Field ARRAY:[I
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;             // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+SourceFile: "R.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/R
+## Class: com/android/hoststubgen/test/tinyframework/R.class
+  Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/R
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 2, attributes: 4
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/R
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.R();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/R
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/R;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+SourceFile: "R.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/R$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class
+  Compiled from "TinyFrameworkAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 7, attributes: 3
+  public int keep;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+         x: ldc           #x                 // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: iconst_1
+        x: putfield      #x                 // Field keep:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public int addOne(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+         x: ldc           #x                 // String addOne
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_1
+        x: iconst_1
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+           11       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+         x: ldc           #x                 // String addTwo
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_1
+        x: iconst_2
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+           11       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeAddThree(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+         x: ldc           #x                 // String nativeAddThree
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: iconst_3
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.String unsupportedMethod();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+         x: ldc           #x                 // String unsupportedMethod
+         x: ldc           #x                 // String ()Ljava/lang/String;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: ldc           #x                 // String Unreachable
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestThrow
+
+  public int toBeIgnored();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+         x: ldc           #x                 // String toBeIgnored
+         x: ldc           #x                 // String ()I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_0
+        x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestIgnore
+}
+SourceFile: "TinyFrameworkAnnotations.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x(#x=s#x)
+    android.hosttest.annotation.HostSideTestClassLoadHook(
+      value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+    )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+  Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 3, attributes: 3
+  public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+    descriptor: Ljava/util/Set;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/Set<Ljava/lang/Class<*>;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+    descriptor: ()V
+    flags: (0x0002) ACC_PRIVATE
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void onClassLoaded(java.lang.Class<?>);
+    descriptor: (Ljava/lang/Class;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+         x: ldc           #x                 // String onClassLoaded
+         x: ldc           #x                 // String (Ljava/lang/Class;)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: getstatic     #x                 // Field sLoadedClasses:Ljava/util/Set;
+        x: aload_0
+        x: invokeinterface #x,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+        x: pop
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      11     0 clazz   Ljava/lang/Class;
+      LocalVariableTypeTable:
+        Start  Length  Slot  Name   Signature
+           11      11     0 clazz   Ljava/lang/Class<*>;
+    Signature: #x                          // (Ljava/lang/Class<*>;)V
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+         x: ldc           #x                 // String <clinit>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+        x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: new           #x                 // class java/util/HashSet
+        x: dup
+        x: invokespecial #x                 // Method java/util/HashSet."<init>":()V
+        x: putstatic     #x                 // Field sLoadedClasses:Ljava/util/Set;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class
+  Compiled from "TinyFrameworkClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 5, attributes: 3
+  public int keep;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: iconst_1
+        x: putfield      #x                 // Field keep:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int addOne(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+         x: ldc           #x                 // String addOne
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_1
+        x: iconst_1
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+           11       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+         x: ldc           #x                 // String addTwo
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_1
+        x: iconst_2
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+           11       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.String unsupportedMethod();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+         x: ldc           #x                 // String unsupportedMethod
+         x: ldc           #x                 // String ()Ljava/lang/String;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: ldc           #x                 // String Unreachable
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestThrow
+}
+SourceFile: "TinyFrameworkClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+  Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 0, attributes: 3
+  public static boolean sInitialized;
+    descriptor: Z
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.lang.Object sObject;
+    descriptor: Ljava/lang/Object;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+  Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 1, attributes: 3
+  public static boolean sInitialized;
+    descriptor: Z
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.lang.Object sObject;
+    descriptor: Ljava/lang/Object;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+         x: ldc           #x                 // String <clinit>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+        x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+        x: ldc           #x                 // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: iconst_1
+        x: putstatic     #x                 // Field sInitialized:Z
+        x: new           #x                  // class java/lang/Object
+        x: dup
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: putstatic     #x                 // Field sObject:Ljava/lang/Object;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x(#x=s#x)
+    android.hosttest.annotation.HostSideTestClassLoadHook(
+      value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+    )
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x()
+    android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+  Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+  minor version: 0
+  major version: 65
+  flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+  super_class: #x                         // java/lang/Enum
+  interfaces: 0, fields: 6, methods: 7, attributes: 4
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private final java.lang.String mLongName;
+    descriptor: Ljava/lang/String;
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private final java.lang.String mShortName;
+    descriptor: Ljava/lang/String;
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+    descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: ldc           #x                 // String values
+         x: ldc           #x                 // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: getstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: invokevirtual #x                 // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;".clone:()Ljava/lang/Object;
+        x: checkcast     #x                 // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;"
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+    descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: ldc           #x                 // String valueOf
+         x: ldc           #x                 // String (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: aload_0
+        x: invokestatic  #x                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+        x: checkcast     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  name   Ljava/lang/String;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      mandated
+
+  private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+    descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+    flags: (0x0002) ACC_PRIVATE
+    Code:
+      stack=4, locals=5, args_size=5
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: aload_1
+        x: iload_2
+        x: invokespecial #x                 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+        x: aload_0
+        x: aload_3
+        x: putfield      #x                 // Field mLongName:Ljava/lang/String;
+        x: aload_0
+        x: aload         4
+        x: putfield      #x                 // Field mShortName:Ljava/lang/String;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      18     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+           11      18     3 longName   Ljava/lang/String;
+           11      18     4 shortName   Ljava/lang/String;
+    Signature: #x                          // (Ljava/lang/String;Ljava/lang/String;)V
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      synthetic
+      <no name>                      synthetic
+      <no name>
+      <no name>
+
+  public java.lang.String getLongName();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: ldc           #x                 // String getLongName
+         x: ldc           #x                 // String ()Ljava/lang/String;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: getfield      #x                 // Field mLongName:Ljava/lang/String;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.lang.String getShortName();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: ldc           #x                 // String getShortName
+         x: ldc           #x                 // String ()Ljava/lang/String;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: getfield      #x                 // Field mShortName:Ljava/lang/String;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: ldc           #x                 // String $values
+         x: ldc           #x                 // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_3
+        x: anewarray     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: dup
+        x: iconst_0
+        x: getstatic     #x                 // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: aastore
+        x: dup
+        x: iconst_1
+        x: getstatic     #x                 // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: aastore
+        x: dup
+        x: iconst_2
+        x: getstatic     #x                 // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: aastore
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=6, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+         x: ldc           #x                 // String <clinit>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: dup
+        x: ldc           #x                 // String RED
+        x: iconst_0
+        x: ldc           #x                 // String Red
+        x: ldc           #x                 // String R
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+        x: putstatic     #x                 // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: dup
+        x: ldc           #x                 // String GREEN
+        x: iconst_1
+        x: ldc           #x                 // String Green
+        x: ldc           #x                 // String G
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+        x: putstatic     #x                 // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+        x: dup
+        x: ldc           #x                 // String BLUE
+        x: iconst_2
+        x: ldc           #x                 // String Blue
+        x: ldc           #x                // String B
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+        x: putstatic     #x                 // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: invokestatic  #x                // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: putstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+Signature: #x                           // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+  Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+  minor version: 0
+  major version: 65
+  flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+  super_class: #x                         // java/lang/Enum
+  interfaces: 0, fields: 3, methods: 5, attributes: 4
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+    descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+    descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: ldc           #x                 // String values
+         x: ldc           #x                 // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: getstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: invokevirtual #x                 // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;".clone:()Ljava/lang/Object;
+        x: checkcast     #x                 // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;"
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+    descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: ldc           #x                 // String valueOf
+         x: ldc           #x                 // String (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+        x: aload_0
+        x: invokestatic  #x                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+        x: checkcast     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  name   Ljava/lang/String;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      mandated
+
+  private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+    descriptor: (Ljava/lang/String;I)V
+    flags: (0x0002) ACC_PRIVATE
+    Code:
+      stack=4, locals=3, args_size=3
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (Ljava/lang/String;I)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: aload_1
+        x: iload_2
+        x: invokespecial #x                 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       7     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    Signature: #x                          // ()V
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      synthetic
+      <no name>                      synthetic
+
+  private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+    descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: ldc           #x                 // String $values
+         x: ldc           #x                 // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_2
+        x: anewarray     #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+        x: dup
+        x: iconst_0
+        x: getstatic     #x                 // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: aastore
+        x: dup
+        x: iconst_1
+        x: getstatic     #x                 // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: aastore
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+         x: ldc           #x                 // String <clinit>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+        x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+        x: dup
+        x: ldc           #x                 // String CAT
+        x: iconst_0
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;I)V
+        x: putstatic     #x                 // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: new           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+        x: dup
+        x: ldc           #x                 // String DOG
+        x: iconst_1
+        x: invokespecial #x                 // Method "<init>":(Ljava/lang/String;I)V
+        x: putstatic     #x                 // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: invokestatic  #x                 // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: putstatic     #x                 // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+Signature: #x                           // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+  Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 3, attributes: 3
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int testException();
+    descriptor: ()I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+         x: ldc           #x                 // String testException
+         x: ldc           #x                 // String ()I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: new           #x                 // class java/lang/IllegalStateException
+        x: dup
+        x: ldc           #x                 // String Inner exception
+        x: invokespecial #x                 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+        x: athrow
+        x: astore_0
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: ldc           #x                 // String Outer exception
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+        x: athrow
+      Exception table:
+         from    to  target type
+            11    21    21   Class java/lang/Exception
+      StackMapTable: number_of_entries = 1
+        frame_type = 85 /* same_locals_1_stack_item */
+          stack = [ class java/lang/Exception ]
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           22      11     0     e   Ljava/lang/Exception;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+  Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 15, attributes: 2
+  public int stub;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: iconst_1
+        x: putfield      #x                 // Field stub:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int addOne(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String addOne
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_1
+        x: iconst_1
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+           11       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.String toBeIgnoredObj();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String toBeIgnoredObj
+         x: ldc           #x                 // String ()Ljava/lang/String;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aconst_null
+        x: areturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public void toBeIgnoredV();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String toBeIgnoredV
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: return
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public boolean toBeIgnoredZ();
+    descriptor: ()Z
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String toBeIgnoredZ
+         x: ldc           #x                 // String ()Z
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_0
+        x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public byte toBeIgnoredB();
+    descriptor: ()B
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String toBeIgnoredB
+         x: ldc           #x                 // String ()B
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_0
+        x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public char toBeIgnoredC();
+    descriptor: ()C
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String toBeIgnoredC
+         x: ldc           #x                 // String ()C
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_0
+        x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public short toBeIgnoredS();
+    descriptor: ()S
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String toBeIgnoredS
+         x: ldc           #x                 // String ()S
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_0
+        x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int toBeIgnoredI();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String toBeIgnoredI
+         x: ldc           #x                 // String ()I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_0
+        x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public float toBeIgnoredF();
+    descriptor: ()F
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String toBeIgnoredF
+         x: ldc           #x                 // String ()F
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: fconst_0
+        x: freturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public double toBeIgnoredD();
+    descriptor: ()D
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String toBeIgnoredD
+         x: ldc           #x                 // String ()D
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: dconst_0
+        x: dreturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int addTwo(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String addTwo
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_1
+        x: iconst_2
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+           11       4     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeAddThree(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String nativeAddThree
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: iconst_3
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.String unsupportedMethod();
+    descriptor: ()Ljava/lang/String;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+         x: ldc           #x                 // String unsupportedMethod
+         x: ldc           #x                 // String ()Ljava/lang/String;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: ldc           #x                 // String Unreachable
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+  Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 8, attributes: 6
+  public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: putfield      #x                 // Field mSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      14     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.util.function.Supplier<java.lang.Integer> getSupplier();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+         x: ldc           #x                 // String getSupplier
+         x: ldc           #x                 // String ()Ljava/util/function/Supplier;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+         x: ldc           #x                 // String getSupplier_static
+         x: ldc           #x                 // String ()Ljava/util/function/Supplier;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static java.lang.Integer lambda$getSupplier_static$3();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+         x: ldc           #x                 // String lambda$getSupplier_static$3
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: bipush        8
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$getSupplier$2();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+         x: ldc           #x                 // String lambda$getSupplier$2
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: bipush        7
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$static$1();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+         x: ldc           #x                 // String lambda$static$1
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: bipush        6
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$new$0();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+         x: ldc           #x                 // String lambda$new$0
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_5
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+         x: ldc           #x                 // String <clinit>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+        x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: putstatic     #x                 // Field sSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;            // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+  public static final #x= #x of #x;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x()
+    android.hosttest.annotation.HostSideTestStaticInitializerKeep
+BootstrapMethods:
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$new$0:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier$2:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$static$1:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+  Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 8, attributes: 6
+  public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: putfield      #x                 // Field mSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      14     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public java.util.function.Supplier<java.lang.Integer> getSupplier();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+         x: ldc           #x                 // String getSupplier
+         x: ldc           #x                 // String ()Ljava/util/function/Supplier;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+         x: ldc           #x                 // String getSupplier_static
+         x: ldc           #x                 // String ()Ljava/util/function/Supplier;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestKeep
+
+  private static java.lang.Integer lambda$getSupplier_static$3();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+         x: ldc           #x                 // String lambda$getSupplier_static$3
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_4
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$getSupplier$2();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+         x: ldc           #x                 // String lambda$getSupplier$2
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_3
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$static$1();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+         x: ldc           #x                 // String lambda$static$1
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_2
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static java.lang.Integer lambda$new$0();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+         x: ldc           #x                 // String lambda$new$0
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_1
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+         x: ldc           #x                 // String <clinit>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+        x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: invokedynamic #x,  0             // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+        x: putstatic     #x                 // Field sSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+  public static final #x= #x of #x;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestKeep
+  x: #x()
+    android.hosttest.annotation.HostSideTestStaticInitializerKeep
+BootstrapMethods:
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$new$0:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier$2:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()Ljava/lang/Object;
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$static$1:()Ljava/lang/Integer;
+      #x ()Ljava/lang/Integer;
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
+  Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 4, attributes: 4
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void startThread(java.lang.Thread);
+    descriptor: (Ljava/lang/Thread;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+         x: ldc           #x                 // String startThread
+         x: ldc           #x                 // String (Ljava/lang/Thread;)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: iconst_1
+        x: invokevirtual #x                 // Method java/lang/Thread.setDaemon:(Z)V
+        x: aload_0
+        x: invokevirtual #x                 // Method java/lang/Thread.start:()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0 thread   Ljava/lang/Thread;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int add(int, int);
+    descriptor: (II)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+         x: ldc           #x                 // String add
+         x: ldc           #x                 // String (II)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: iload_1
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0     a   I
+           11       4     1     b   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
+  Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 5, attributes: 6
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static boolean nonStaticMethodCallReplaceTester() throws java.lang.Exception;
+    descriptor: ()Z
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=2, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+         x: ldc           #x                 // String nonStaticMethodCallReplaceTester
+         x: ldc           #x                 // String ()Z
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: new           #x                 // class java/util/concurrent/atomic/AtomicBoolean
+        x: dup
+        x: iconst_0
+        x: invokespecial #x                 // Method java/util/concurrent/atomic/AtomicBoolean."<init>":(Z)V
+        x: astore_0
+        x: new           #x                 // class java/lang/Thread
+        x: dup
+        x: aload_0
+        x: invokedynamic #x,  0             // InvokeDynamic #x:run:(Ljava/util/concurrent/atomic/AtomicBoolean;)Ljava/lang/Runnable;
+        x: invokespecial #x                 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
+        x: astore_1
+        x: aload_1
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.startThread:(Ljava/lang/Thread;)V
+        x: aload_1
+        x: invokevirtual #x                 // Method java/lang/Thread.join:()V
+        x: aload_0
+        x: invokevirtual #x                 // Method java/util/concurrent/atomic/AtomicBoolean.get:()Z
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           20      27     0    ab   Ljava/util/concurrent/atomic/AtomicBoolean;
+           34      13     1    th   Ljava/lang/Thread;
+    Exceptions:
+      throws java.lang.Exception
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int staticMethodCallReplaceTester();
+    descriptor: ()I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+         x: ldc           #x                 // String staticMethodCallReplaceTester
+         x: ldc           #x                 // String ()I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_1
+        x: iconst_2
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.add:(II)I
+        x: ireturn
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
+    descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+    flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+         x: ldc           #x                 // String lambda$nonStaticMethodCallReplaceTester$0
+         x: ldc           #x                 // String (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokestatic  #x                 // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
+        x: invokevirtual #x                // Method java/lang/Thread.isDaemon:()Z
+        x: invokevirtual #x                // Method java/util/concurrent/atomic/AtomicBoolean.set:(Z)V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      11     0    ab   Ljava/util/concurrent/atomic/AtomicBoolean;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+  public static final #x= #x of #x;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+BootstrapMethods:
+  x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+    Method arguments:
+      #x ()V
+      #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.lambda$nonStaticMethodCallReplaceTester$0:(Ljava/util/concurrent/atomic/AtomicBoolean;)V
+      #x ()V
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+  Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 15, attributes: 3
+  int value;
+    descriptor: I
+    flags: (0x0000)
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeAddTwo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String nativeAddTwo
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+        x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public static int nativeAddTwo_should_be_like_this(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String nativeAddTwo_should_be_like_this
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0   arg   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static long nativeLongPlus(long, long);
+    descriptor: (JJ)J
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=4, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String nativeLongPlus
+         x: ldc           #x                 // String (JJ)J
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: lload_0
+        x: lload_2
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+        x: lreturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public static long nativeLongPlus_should_be_like_this(long, long);
+    descriptor: (JJ)J
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=4, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String nativeLongPlus_should_be_like_this
+         x: ldc           #x                 // String (JJ)J
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: lload_0
+        x: lload_2
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+        x: lreturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       6     0  arg1   J
+           11       6     2  arg2   J
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public void setValue(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String setValue
+         x: ldc           #x                 // String (I)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: iload_1
+        x: putfield      #x                 // Field value:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+           11       6     1     v   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int nativeNonStaticAddToValue(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String nativeNonStaticAddToValue
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: iload_1
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+        x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public int nativeNonStaticAddToValue_should_be_like_this(int);
+    descriptor: (I)I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String nativeNonStaticAddToValue_should_be_like_this
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: iload_1
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+           11       6     1   arg   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void nativeStillNotSupported();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String nativeStillNotSupported
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: ldc           #x                 // String Unreachable
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestThrow
+
+  public static native void nativeStillKeep();
+    descriptor: ()V
+    flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void nativeStillNotSupported_should_be_like_this();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String nativeStillNotSupported_should_be_like_this
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":()V
+        x: athrow
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static byte nativeBytePlus(byte, byte);
+    descriptor: (BB)B
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String nativeBytePlus
+         x: ldc           #x                 // String (BB)B
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: iload_1
+        x: invokestatic  #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeBytePlus:(BB)B
+        x: ireturn
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public void notNativeRedirected();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                 // String notNativeRedirected
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokestatic  #x                // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.notNativeRedirected:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+        x: return
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+
+  public static void notNativeStaticRedirected();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+         x: ldc           #x                // String notNativeStaticRedirected
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: invokestatic  #x                // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.notNativeStaticRedirected:()V
+        x: return
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    RuntimeInvisibleAnnotations:
+      x: #x()
+        android.hosttest.annotation.HostSideTestRedirect
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+  x: #x(#x=s#x)
+    android.hosttest.annotation.HostSideTestRedirectionClass(
+      value="TinyFrameworkNative_host"
+    )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+  Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 8, attributes: 3
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeAddTwo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+         x: ldc           #x                 // String nativeAddTwo
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: iconst_2
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0   arg   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static long nativeLongPlus(long, long);
+    descriptor: (JJ)J
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=4, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+         x: ldc           #x                 // String nativeLongPlus
+         x: ldc           #x                 // String (JJ)J
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: lload_0
+        x: lload_2
+        x: ladd
+        x: lreturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       4     0  arg1   J
+           11       4     2  arg2   J
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int nativeNonStaticAddToValue(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative, int);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+         x: ldc           #x                 // String nativeNonStaticAddToValue
+         x: ldc           #x                 // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: getfield      #x                 // Field com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.value:I
+        x: iload_1
+        x: iadd
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       7     0 source   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+           11       7     1   arg   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static byte nativeBytePlus(byte, byte);
+    descriptor: (BB)B
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+         x: ldc           #x                 // String nativeBytePlus
+         x: ldc           #x                 // String (BB)B
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iload_0
+        x: iload_1
+        x: iadd
+        x: i2b
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  arg1   B
+           11       5     1  arg2   B
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void notNativeRedirected(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+         x: ldc           #x                 // String notNativeRedirected
+         x: ldc           #x                 // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       1     0 source   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static void notNativeStaticRedirected();
+    descriptor: ()V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+         x: ldc           #x                 // String notNativeStaticRedirected
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 4, attributes: 6
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+    flags: (0x0000)
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+           11       5     1 this$0   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      final mandated
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_1
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Object;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+EnclosingMethod: #x.#x                 // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 4, attributes: 6
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+    descriptor: ()V
+    flags: (0x0000)
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_2
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Object;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+EnclosingMethod: #x.#x                 // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 4, attributes: 6
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+    flags: (0x0000)
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+           11       5     1 this$0   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      final mandated
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_3
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Object;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+EnclosingMethod: #x.#x                // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 4, attributes: 6
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+    descriptor: ()V
+    flags: (0x0000)
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: iconst_4
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Object;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+EnclosingMethod: #x.#x                // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 4
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (I)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: iload_1
+        x: putfield      #x                 // Field value:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+           11      10     1     x   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 4
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+    descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: iconst_5
+        x: putfield      #x                 // Field value:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+           11      10     1 this$0   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+    MethodParameters:
+      Name                           Flags
+      <no name>                      final mandated
+}
+InnerClasses:
+  public #x= #x of #x;                  // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+  minor version: 0
+  major version: 65
+  flags: (0x0020) ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 4, attributes: 6
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+    descriptor: ()V
+    flags: (0x0000)
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Integer get();
+    descriptor: ()Ljava/lang/Integer;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Integer;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: bipush        7
+        x: invokestatic  #x                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.lang.Object get();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+         x: ldc           #x                 // String get
+         x: ldc           #x                 // String ()Ljava/lang/Object;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokevirtual #x                 // Method get:()Ljava/lang/Integer;
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;          // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  #x;                                     // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+EnclosingMethod: #x.#x                // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+Signature: #x                           // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 2, attributes: 4
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: bipush        8
+        x: putfield      #x                 // Field value:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      11     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;          // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;           // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 3, attributes: 4
+  public int value;
+    descriptor: I
+    flags: (0x0001) ACC_PUBLIC
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: bipush        6
+        x: putfield      #x                 // Field value:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      11     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+         x: ldc           #x                 // String getSupplier_static
+         x: ldc           #x                 // String ()Ljava/util/function/Supplier;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+        x: dup
+        x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+        x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+  public static #x= #x of #x;           // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+  interfaces: 0, fields: 0, methods: 2, attributes: 4
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (I)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: iload_1
+        x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       6     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+           11       6     1     x   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  public static #x= #x of #x;           // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;           // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+  Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 2, methods: 4, attributes: 5
+  public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+    descriptor: Ljava/util/function/Supplier;
+    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+    Signature: #x                          // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+        x: dup
+        x: aload_0
+        x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+        x: putfield      #x                 // Field mSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      17     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public java.util.function.Supplier<java.lang.Integer> getSupplier();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+         x: ldc           #x                 // String getSupplier
+         x: ldc           #x                 // String ()Ljava/util/function/Supplier;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+        x: dup
+        x: aload_0
+        x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+        x: areturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       9     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+    descriptor: ()Ljava/util/function/Supplier;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+         x: ldc           #x                 // String getSupplier_static
+         x: ldc           #x                 // String ()Ljava/util/function/Supplier;
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+        x: dup
+        x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+        x: areturn
+      LineNumberTable:
+    Signature: #x                          // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  static {};
+    descriptor: ()V
+    flags: (0x0008) ACC_STATIC
+    Code:
+      stack=4, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+         x: ldc           #x                 // String <clinit>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+        x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+        x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+        x: new           #x                 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+        x: dup
+        x: invokespecial #x                 // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+        x: putstatic     #x                 // Field sSupplier:Ljava/util/function/Supplier;
+        x: return
+      LineNumberTable:
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+  public static #x= #x of #x;            // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;           // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;           // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public #x= #x of #x;                  // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+  public static #x= #x of #x;          // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+  #x;                                    // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+NestMembers:
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+  com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+  Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 3, attributes: 3
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int foo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+         x: ldc           #x                 // String foo
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: new           #x                 // class com/supported/UnsupportedClass
+        x: dup
+        x: iload_0
+        x: invokespecial #x                 // Method com/supported/UnsupportedClass."<init>":(I)V
+        x: invokevirtual #x                 // Method com/supported/UnsupportedClass.getValue:()I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      12     0 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
+  Compiled from "TinyFrameworkRenamedClassCaller.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 3, attributes: 3
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String ()V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public static int foo(int);
+    descriptor: (I)I
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+         x: ldc           #x                 // String foo
+         x: ldc           #x                 // String (I)I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: new           #x                 // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+        x: dup
+        x: iload_0
+        x: invokespecial #x                 // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed."<init>":(I)V
+        x: invokevirtual #x                 // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      12     0 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkRenamedClassCaller.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/A.class
+  Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.A
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/packagetest/A
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/packagetest/A
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "A.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/sub/A.class
+  Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/packagetest/sub/A
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "A.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class
+  Compiled from "C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/C1
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "C1.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class
+  Compiled from "C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/C2
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "C2.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class
+  Compiled from "C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/C3
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "C3.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class
+  Compiled from "CA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/CA
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/CA
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "CA.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class
+  Compiled from "CB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/CB
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "CB.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.class
+  Compiled from "Class_C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "Class_C1.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.class
+  Compiled from "Class_C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "Class_C2.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.class
+  Compiled from "Class_C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C3
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
+  super_class: #x                         // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "Class_C3.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.class
+  Compiled from "Class_I1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "Class_I1.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.class
+  Compiled from "Class_I1_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I1,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
+  super_class: #x                         // java/lang/Object
+  interfaces: 2, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "Class_I1_IA.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.class
+  Compiled from "Class_I2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 implements com.android.hoststubgen.test.tinyframework.subclasstest.I2
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "Class_I2.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.class
+  Compiled from "Class_I3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.I3
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "Class_I3.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class
+  Compiled from "I1.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/I1
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/I1
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "I1.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class
+  Compiled from "I2.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/I2
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/I2
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "I2.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class
+  Compiled from "I3.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/I3
+  super_class: #x                         // java/lang/Object
+  interfaces: 1, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/I3
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "I3.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class
+  Compiled from "IA.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/IA
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/IA
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "IA.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class
+  Compiled from "IB.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
+  minor version: 0
+  major version: 65
+  flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/subclasstest/IB
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 1, attributes: 2
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/subclasstest/IB
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+}
+SourceFile: "IB.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/supported/UnsupportedClass.class
+  Compiled from "UnsupportedClass.java"
+public class com.supported.UnsupportedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/supported/UnsupportedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 3, attributes: 3
+  private final int mValue;
+    descriptor: I
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/supported/UnsupportedClass
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.supported.UnsupportedClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/supported/UnsupportedClass
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (I)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: iload_1
+        x: putfield      #x                 // Field mValue:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  this   Lcom/supported/UnsupportedClass;
+           11      10     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int getValue();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/supported/UnsupportedClass
+         x: ldc           #x                 // String getValue
+         x: ldc           #x                 // String ()I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: getfield      #x                 // Field mValue:I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/supported/UnsupportedClass;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/unsupported/UnsupportedClass.class
+  Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // com/unsupported/UnsupportedClass
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 3, attributes: 3
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/unsupported/UnsupportedClass
+         x: ldc           #x                  // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public com.unsupported.UnsupportedClass(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/unsupported/UnsupportedClass
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (I)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: ldc           #x                 // String This class is not supported
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      14     0  this   Lcom/unsupported/UnsupportedClass;
+           11      14     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int getValue();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/unsupported/UnsupportedClass
+         x: ldc           #x                 // String getValue
+         x: ldc           #x                 // String ()I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: new           #x                 // class java/lang/RuntimeException
+        x: dup
+        x: ldc           #x                 // String This class is not supported
+        x: invokespecial #x                 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+        x: athrow
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  this   Lcom/unsupported/UnsupportedClass;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.class
+  Compiled from "TinyFrameworkToBeRenamed.java"
+public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
+  minor version: 0
+  major version: 65
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #x                          // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+  super_class: #x                         // java/lang/Object
+  interfaces: 0, fields: 1, methods: 3, attributes: 3
+  private final int mValue;
+    descriptor: I
+    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  private static {};
+    descriptor: ()V
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=0, args_size=0
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+         x: return
+
+  public rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed(int);
+    descriptor: (I)V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=2, args_size=2
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+         x: ldc           #x                 // String <init>
+         x: ldc           #x                 // String (I)V
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: invokespecial #x                 // Method java/lang/Object."<init>":()V
+        x: aload_0
+        x: iload_1
+        x: putfield      #x                 // Field mValue:I
+        x: return
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11      10     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+           11      10     1 value   I
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+  public int getValue();
+    descriptor: ()I
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=4, locals=1, args_size=1
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+         x: ldc           #x                 // String getValue
+         x: ldc           #x                 // String ()I
+         x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+         x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+        x: aload_0
+        x: getfield      #x                 // Field mValue:I
+        x: ireturn
+      LineNumberTable:
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+    RuntimeVisibleAnnotations:
+      x: #x()
+        com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkToBeRenamed.java"
+RuntimeVisibleAnnotations:
+  x: #x()
+    com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+  x: #x()
+    android.hosttest.annotation.HostSideTestWholeClassKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
index 7a7de35..88fa492 100755
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
@@ -20,18 +20,23 @@
 import unittest
 import subprocess
 
-GOLDEN_DIR = 'golden-output'
+GOLDEN_DIRS = [
+    'golden-output',
+    'golden-output.RELEASE_TARGET_JAVA_21',
+]
+
 
 # Run diff.
 def run_diff(file1, file2):
-    command = ['diff', '-u', '--ignore-blank-lines', '--ignore-space-change', file1, file2]
+    command = ['diff', '-u', '--ignore-blank-lines',
+               '--ignore-space-change', file1, file2]
     print(' '.join(command))
-    result = subprocess.run(command, stderr = sys.stdout)
+    result = subprocess.run(command, stderr=sys.stdout)
 
     success = result.returncode == 0
 
     if success:
-        print(f'No diff found.')
+        print('No diff found.')
     else:
         print(f'Fail: {file1} and {file2} are different.')
 
@@ -39,27 +44,42 @@
 
 
 # Check one golden file.
-def check_one_file(filename):
+def check_one_file(golden_dir, filename):
     print(f'= Checking file: {filename}')
-    return run_diff(os.path.join(GOLDEN_DIR, filename), filename)
+    return run_diff(os.path.join(golden_dir, filename), filename)
+
 
 class TestWithGoldenOutput(unittest.TestCase):
 
     # Test to check the generated jar files to the golden output.
+    # Depending on build flags, the golden output may differ in expected ways.
+    # So only expect the files to match one of the possible golden outputs.
     def test_compare_to_golden(self):
-        self.skipTest("test cannot handle multiple images (see b/378470825)")
-        files = os.listdir(GOLDEN_DIR)
-        files.sort()
+        success = False
 
-        print(f"Golden files: {files}")
-        success = True
-
-        for file in files:
-            if not check_one_file(file):
-                success = False
+        for golden_dir in GOLDEN_DIRS:
+            if self.matches_golden(golden_dir):
+                success = True
+                print(f"Test passes for dir: {golden_dir}")
+                break
 
         if not success:
-            self.fail('Some files are different. See stdout log for more details.')
+            self.fail('Some files are different. ' +
+                      'See stdout log for more details.')
+
+    def matches_golden(self, golden_dir):
+        files = os.listdir(golden_dir)
+        files.sort()
+
+        print(f"Golden files for {golden_dir}: {files}")
+        match_success = True
+
+        for file in files:
+            if not check_one_file(golden_dir, file):
+                match_success = False
+
+        return match_success
+
 
 if __name__ == "__main__":
     unittest.main(verbosity=2)
diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt
index 8ec0932..61e254b 100644
--- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt
+++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt
@@ -43,7 +43,7 @@
     }
     var allOk = true
 
-    log.i("Checking ${cn.name.toHumanReadableClassName()}")
+    log.v("Checking ${cn.name.toHumanReadableClassName()}")
 
     // See if there's any class that extends a legacy base class.
     // But ignore the base classes in android.test.
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index 2808056..a0b989b 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -55,16 +55,6 @@
 }
 
 flag {
-    name: "compute_window_changes_on_a11y_v2"
-    namespace: "accessibility"
-    description: "Computes accessibility window changes in accessibility instead of wm package."
-    bug: "322444245"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
     name: "deprecate_package_list_observer"
     namespace: "accessibility"
     description: "Stops using the deprecated PackageListObserver."
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index d6fc6e4..7ef6aac 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -1180,18 +1180,8 @@
     }
 
     private boolean anyServiceWantsGenericMotionEvent(MotionEvent event) {
-        if (Flags.alwaysAllowObservingTouchEvents()) {
-            final boolean isTouchEvent = event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN);
-            if (isTouchEvent && !canShareGenericTouchEvent()) {
-                return false;
-            }
-            final int eventSourceWithoutClass = event.getSource() & ~InputDevice.SOURCE_CLASS_MASK;
-            return (mCombinedGenericMotionEventSources & eventSourceWithoutClass) != 0;
-        }
-        // Disable SOURCE_TOUCHSCREEN generic event interception if any service is performing
-        // touch exploration.
-        if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)
-                && (mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) {
+        final boolean isTouchEvent = event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN);
+        if (isTouchEvent && !canShareGenericTouchEvent()) {
             return false;
         }
         final int eventSourceWithoutClass = event.getSource() & ~InputDevice.SOURCE_CLASS_MASK;
@@ -1199,21 +1189,8 @@
     }
 
     private boolean anyServiceWantsToObserveMotionEvent(MotionEvent event) {
-        if (Flags.alwaysAllowObservingTouchEvents()) {
-            final int eventSourceWithoutClass = event.getSource() & ~InputDevice.SOURCE_CLASS_MASK;
-            return (mCombinedMotionEventObservedSources & eventSourceWithoutClass) != 0;
-        }
-        // Disable SOURCE_TOUCHSCREEN generic event interception if any service is performing
-        // touch exploration.
-        if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)
-                && (mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) {
-            return false;
-        }
         final int eventSourceWithoutClass = event.getSource() & ~InputDevice.SOURCE_CLASS_MASK;
-        return (mCombinedGenericMotionEventSources
-                & mCombinedMotionEventObservedSources
-                & eventSourceWithoutClass)
-                != 0;
+        return (mCombinedMotionEventObservedSources & eventSourceWithoutClass) != 0;
     }
 
     private boolean canShareGenericTouchEvent() {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index d4af7b7..71a0fc4 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3797,13 +3797,7 @@
                 || (Flags.enableMagnificationMultipleFingerMultipleTapGesture()
                     && userState.isMagnificationTwoFingerTripleTapEnabledLocked()));
 
-        final boolean createConnectionForCurrentCapability =
-                com.android.window.flags.Flags.alwaysDrawMagnificationFullscreenBorder()
-                        || (userState.getMagnificationCapabilitiesLocked()
-                                != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-
-        final boolean connect = (shortcutEnabled && createConnectionForCurrentCapability)
-                || userHasMagnificationServicesLocked(userState);
+        final boolean connect = shortcutEnabled || userHasMagnificationServicesLocked(userState);
 
         getMagnificationConnectionManager().requestConnection(connect);
     }
@@ -4503,13 +4497,11 @@
         }
         if (shortcutType == HARDWARE) {
             skipVolumeShortcutDialogTimeoutRestriction(userId);
-            if (com.android.server.accessibility.Flags.enableHardwareShortcutDisablesWarning()) {
-                persistIntToSetting(
-                        userId,
-                        Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
-                        AccessibilityShortcutController.DialogStatus.SHOWN
-                );
-            }
+            persistIntToSetting(
+                    userId,
+                    Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+                    AccessibilityShortcutController.DialogStatus.SHOWN
+            );
         } else if (shortcutType == SOFTWARE) {
             // Update the A11y FAB size to large when the Magnification shortcut is
             // enabled and the user hasn't changed the floating button size
@@ -4854,8 +4846,7 @@
 
         getMagnificationConnectionManager().setConnection(connection);
 
-        if (com.android.window.flags.Flags.alwaysDrawMagnificationFullscreenBorder()
-                && connection == null
+        if (connection == null
                 && mMagnificationController.isFullScreenMagnificationControllerInitialized()) {
             // Since the connection does not exist, the system ui cannot provide the border
             // implementation for fullscreen magnification. So we call reset to deactivate the
@@ -6550,8 +6541,7 @@
 
                 // Only continue setting up the packages if the service has been initialized.
                 // See: b/340927041
-                if (Flags.skipPackageChangeBeforeUserSwitch()
-                        && !mManagerService.isServiceInitializedLocked()) {
+                if (!mManagerService.isServiceInitializedLocked()) {
                     Slog.w(LOG_TAG,
                             "onSomePackagesChanged: service not initialized, skip the callback.");
                     return;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 9a81aa6..8b870db 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -434,21 +434,23 @@
         }
 
         /**
-         * Callbacks from window manager when there's an accessibility change in windows.
+         * Called when the windows for accessibility changed.
          *
-         * @param forceSend Send the windows for accessibility even if they haven't changed.
-         * @param topFocusedDisplayId The display Id which has the top focused window.
+         * @param forceSend             Send the windows for accessibility even if they haven't
+         *                              changed.
+         * @param topFocusedDisplayId   The display Id which has the top focused window.
          * @param topFocusedWindowToken The window token of top focused window.
-         * @param windows The windows for accessibility.
+         * @param screenSize            The size of the display that the change happened.
+         * @param accessibilityWindows  The windows for accessibility.
          */
         @Override
-        public void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
-                IBinder topFocusedWindowToken, @NonNull List<WindowInfo> windows) {
+        public void onAccessibilityWindowsChanged(boolean forceSend, int topFocusedDisplayId,
+                @NonNull IBinder topFocusedWindowToken, @NonNull Point screenSize,
+                @NonNull List<AccessibilityWindow> accessibilityWindows) {
             synchronized (mLock) {
-                if (!Flags.computeWindowChangesOnA11yV2()) {
-                    // If the flag is enabled, it's already done in #createWindowInfoListLocked.
-                    updateWindowsByWindowAttributesLocked(windows);
-                }
+                final List<WindowInfo> windows =
+                        createWindowInfoListLocked(screenSize, accessibilityWindows);
+
                 if (DEBUG) {
                     Slogf.i(LOG_TAG, "mDisplayId=%d, topFocusedDisplayId=%d, currentUserId=%d, "
                                     + "visibleBgUsers=%s", mDisplayId, topFocusedDisplayId,
@@ -463,14 +465,15 @@
                         Slogf.i(LOG_TAG, "%d windows changed: %s", windows.size(), windowsInfo);
                     }
                 }
-                if (shouldUpdateWindowsLocked(forceSend, windows)) {
+
+                if (forceSend || shouldUpdateWindowsLocked(windows)) {
                     mTopFocusedDisplayId = topFocusedDisplayId;
                     if (!isProxyed(topFocusedDisplayId)) {
                         mLastNonProxyTopFocusedDisplayId = topFocusedDisplayId;
                     }
                     mTopFocusedWindowToken = topFocusedWindowToken;
                     if (DEBUG) {
-                        Slogf.d(LOG_TAG, "onWindowsForAccessibilityChanged(): updating windows for "
+                        Slogf.d(LOG_TAG, "onAccessibilityWindowsChanged(): updating windows for "
                                         + "display %d and token %s",
                                 topFocusedDisplayId, topFocusedWindowToken);
                     }
@@ -480,39 +483,14 @@
                             windows);
                     // Someone may be waiting for the windows - advertise it.
                     mLock.notifyAll();
-                }
-                else if (DEBUG) {
-                    Slogf.d(LOG_TAG, "onWindowsForAccessibilityChanged(): NOT updating windows for "
+                } else if (DEBUG) {
+                    Slogf.d(LOG_TAG, "onAccessibilityWindowsChanged(): NOT updating windows for "
                                     + "display %d and token %s",
                             topFocusedDisplayId, topFocusedWindowToken);
                 }
             }
         }
 
-        /**
-         * Called when the windows for accessibility changed. This is called if
-         * {@link com.android.server.accessibility.Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2} is
-         * true.
-         *
-         * @param forceSend             Send the windows for accessibility even if they haven't
-         *                              changed.
-         * @param topFocusedDisplayId   The display Id which has the top focused window.
-         * @param topFocusedWindowToken The window token of top focused window.
-         * @param screenSize            The size of the display that the change happened.
-         * @param windows               The windows for accessibility.
-         */
-        @Override
-        public void onAccessibilityWindowsChanged(boolean forceSend, int topFocusedDisplayId,
-                @NonNull IBinder topFocusedWindowToken, @NonNull Point screenSize,
-                @NonNull List<AccessibilityWindow> windows) {
-            synchronized (mLock) {
-                final List<WindowInfo> windowInfoList =
-                        createWindowInfoListLocked(screenSize, windows);
-                onWindowsForAccessibilityChanged(forceSend, topFocusedDisplayId,
-                        topFocusedWindowToken, windowInfoList);
-            }
-        }
-
         private List<WindowInfo> createWindowInfoListLocked(@NonNull Point screenSize,
                 @NonNull List<AccessibilityWindow> visibleWindows) {
             final Set<IBinder> addedWindows = new ArraySet<>();
@@ -655,16 +633,6 @@
             return true;
         }
 
-        private void updateWindowsByWindowAttributesLocked(List<WindowInfo> windows) {
-            for (int i = windows.size() - 1; i >= 0; i--) {
-                final WindowInfo windowInfo = windows.get(i);
-                final IBinder token = windowInfo.token;
-                final int windowId = findWindowIdLocked(
-                        mAccessibilityUserManager.getCurrentUserIdLocked(), token);
-                updateWindowWithWindowAttributes(windowInfo, mWindowAttributes.get(windowId));
-            }
-        }
-
         private void updateWindowWithWindowAttributes(@NonNull WindowInfo windowInfo,
                 @Nullable AccessibilityWindowAttributes attributes) {
             if (attributes == null) {
@@ -674,12 +642,7 @@
             windowInfo.locales = attributes.getLocales();
         }
 
-        private boolean shouldUpdateWindowsLocked(boolean forceSend,
-                @NonNull List<WindowInfo> windows) {
-            if (forceSend) {
-                return true;
-            }
-
+        private boolean shouldUpdateWindowsLocked(@NonNull List<WindowInfo> windows) {
             final int windowCount = windows.size();
             if (VERBOSE) {
                 Slogf.v(LOG_TAG,
@@ -990,19 +953,6 @@
         private AccessibilityWindowInfo populateReportedWindowLocked(int userId,
                 WindowInfo window, SparseArray<AccessibilityWindowInfo> oldWindowsById) {
             final int windowId = findWindowIdLocked(userId, window.token);
-
-            // With the flag enabled, createWindowInfoListLocked() already removes invalid windows.
-            if (!Flags.computeWindowChangesOnA11yV2()) {
-                if (windowId < 0) {
-                    return null;
-                }
-
-                // Don't need to add the embedded hierarchy windows into the a11y windows list.
-                if (isEmbeddedHierarchyWindowsLocked(windowId)) {
-                    return null;
-                }
-            }
-
             final AccessibilityWindowInfo reportedWindow = AccessibilityWindowInfo.obtain();
 
             reportedWindow.setId(windowId);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index d3d80e1..11b8ccb 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -699,10 +699,9 @@
             if (!mRegistered) {
                 return false;
             }
-            // If the border implementation is on system ui side but the connection is not
+            // The border implementation is on system ui side but the connection is not
             // established, the fullscreen magnification should not work.
-            if (com.android.window.flags.Flags.alwaysDrawMagnificationFullscreenBorder()
-                    && !mMagnificationConnectionStateSupplier.get()) {
+            if (!mMagnificationConnectionStateSupplier.get()) {
                 return false;
             }
             if (DEBUG) {
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index c6a966f..d11ae0a 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -58,8 +58,6 @@
 import android.view.GestureDetector;
 import android.view.GestureDetector.SimpleOnGestureListener;
 import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
-import android.view.MotionEvent.PointerProperties;
 import android.view.ScaleGestureDetector;
 import android.view.ScaleGestureDetector.OnScaleGestureListener;
 import android.view.VelocityTracker;
@@ -155,9 +153,6 @@
     @VisibleForTesting State mCurrentState;
     @VisibleForTesting State mPreviousState;
 
-    private PointerCoords[] mTempPointerCoords;
-    private PointerProperties[] mTempPointerProperties;
-
     @VisibleForTesting static final int OVERSCROLL_NONE = 0;
     @VisibleForTesting static final int OVERSCROLL_LEFT_EDGE = 1;
     @VisibleForTesting static final int OVERSCROLL_RIGHT_EDGE = 2;
@@ -430,38 +425,6 @@
         mPanningScalingState.clear();
     }
 
-    private PointerCoords[] getTempPointerCoordsWithMinSize(int size) {
-        final int oldSize = (mTempPointerCoords != null) ? mTempPointerCoords.length : 0;
-        if (oldSize < size) {
-            PointerCoords[] oldTempPointerCoords = mTempPointerCoords;
-            mTempPointerCoords = new PointerCoords[size];
-            if (oldTempPointerCoords != null) {
-                System.arraycopy(oldTempPointerCoords, 0, mTempPointerCoords, 0, oldSize);
-            }
-        }
-        for (int i = oldSize; i < size; i++) {
-            mTempPointerCoords[i] = new PointerCoords();
-        }
-        return mTempPointerCoords;
-    }
-
-    private PointerProperties[] getTempPointerPropertiesWithMinSize(int size) {
-        final int oldSize = (mTempPointerProperties != null) ? mTempPointerProperties.length
-                : 0;
-        if (oldSize < size) {
-            PointerProperties[] oldTempPointerProperties = mTempPointerProperties;
-            mTempPointerProperties = new PointerProperties[size];
-            if (oldTempPointerProperties != null) {
-                System.arraycopy(oldTempPointerProperties, 0, mTempPointerProperties, 0,
-                        oldSize);
-            }
-        }
-        for (int i = oldSize; i < size; i++) {
-            mTempPointerProperties[i] = new PointerProperties();
-        }
-        return mTempPointerProperties;
-    }
-
     @VisibleForTesting
     void transitionTo(State state) {
         if (DEBUG_STATE_TRANSITIONS) {
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index 51c4305..058b2be 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -51,7 +51,6 @@
 import com.android.server.LocalServices;
 import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.wm.WindowManagerInternal;
-import com.android.window.flags.Flags;
 
 import java.util.concurrent.Executor;
 
@@ -634,10 +633,8 @@
 
     @Override
     public void onFullScreenMagnificationActivationState(int displayId, boolean activated) {
-        if (Flags.alwaysDrawMagnificationFullscreenBorder()) {
-            getMagnificationConnectionManager()
-                    .onFullscreenMagnificationActivationChanged(displayId, activated);
-        }
+        getMagnificationConnectionManager()
+                .onFullscreenMagnificationActivationChanged(displayId, activated);
 
         if (activated) {
             synchronized (mLock) {
diff --git a/services/autofill/bugfixes.aconfig b/services/autofill/bugfixes.aconfig
index 1803424..5d2ef77 100644
--- a/services/autofill/bugfixes.aconfig
+++ b/services/autofill/bugfixes.aconfig
@@ -44,6 +44,16 @@
 }
 
 flag {
+  name: "test_flag"
+  namespace: "autofill"
+  description: "Test flag "
+  bug: "377868687"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "add_session_id_to_client_state"
   namespace: "autofill"
   description: "Include the session id into the FillEventHistory events as part of ClientState"
diff --git a/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java b/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java
index 5e4bab15..02f1865 100644
--- a/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java
+++ b/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java
@@ -41,6 +41,7 @@
 import android.util.ArraySet;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.LocalServices;
 import com.android.server.backup.internal.LifecycleOperationStorage;
@@ -71,8 +72,10 @@
     // Activity Manager; use this lock object to signal when a requested binding has
     // completed.
     private final Object mAgentConnectLock = new Object();
-    private IBackupAgent mConnectedAgent;
-    private volatile boolean mConnecting;
+    @GuardedBy("mAgentConnectLock")
+    @Nullable
+    private BackupAgentConnection mCurrentConnection;
+
     private final ArraySet<String> mRestoreNoRestrictedModePackages = new ArraySet<>();
     private final ArraySet<String> mBackupNoRestrictedModePackages = new ArraySet<>();
 
@@ -96,8 +99,18 @@
         mUserIdMsg = "[UserID:" + userId + "] ";
     }
 
+    private static final class BackupAgentConnection {
+        public final ApplicationInfo appInfo;
+        public IBackupAgent backupAgent;
+        public boolean connecting = true; // Assume we are trying to connect on creation.
+
+        private BackupAgentConnection(ApplicationInfo appInfo) {
+            this.appInfo = appInfo;
+        }
+    }
+
     /**
-     * Fires off a backup agent, blocking until it attaches (and ActivityManager will call
+     * Fires off a backup agent, blocking until it attaches (i.e. ActivityManager calls
      * {@link #agentConnected(String, IBinder)}) or until this operation times out.
      *
      * @param mode a {@code BACKUP_MODE} from {@link android.app.ApplicationThreadConstants}.
@@ -105,48 +118,56 @@
     @Nullable
     public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode,
             @BackupAnnotations.BackupDestination int backupDestination) {
-        IBackupAgent agent = null;
         synchronized (mAgentConnectLock) {
-            mConnecting = true;
-            mConnectedAgent = null;
             boolean useRestrictedMode = shouldUseRestrictedBackupModeForPackage(mode,
                     app.packageName);
+            if (mCurrentConnection != null) {
+                Slog.e(TAG, mUserIdMsg + "binding to new agent before unbinding from old one: "
+                        + mCurrentConnection.appInfo.packageName);
+            }
+            mCurrentConnection = new BackupAgentConnection(app);
+
+            // bindBackupAgent() is an async API. It will kick off the app's process and call
+            // agentConnected() when it receives the agent from the app.
+            boolean startedBindSuccessfully = false;
             try {
-                if (mActivityManager.bindBackupAgent(app.packageName, mode, mUserId,
-                        backupDestination, useRestrictedMode)) {
-                    Slog.d(TAG, mUserIdMsg + "awaiting agent for " + app);
-
-                    // success; wait for the agent to arrive
-                    // only wait 10 seconds for the bind to happen
-                    long timeoutMark = System.currentTimeMillis() + 10 * 1000;
-                    while (mConnecting && mConnectedAgent == null && (System.currentTimeMillis()
-                            < timeoutMark)) {
-                        try {
-                            mAgentConnectLock.wait(5000);
-                        } catch (InterruptedException e) {
-                            // just bail
-                            Slog.w(TAG, mUserIdMsg + "Interrupted: " + e);
-                            mConnecting = false;
-                            mConnectedAgent = null;
-                        }
-                    }
-
-                    // if we timed out with no connect, abort and move on
-                    if (mConnecting) {
-                        Slog.w(TAG, mUserIdMsg + "Timeout waiting for agent " + app);
-                        mConnectedAgent = null;
-                    }
-                    Slog.i(TAG, mUserIdMsg + "got agent " + mConnectedAgent);
-                    agent = mConnectedAgent;
-                }
+                startedBindSuccessfully = mActivityManager.bindBackupAgent(app.packageName, mode,
+                        mUserId, backupDestination, useRestrictedMode);
             } catch (RemoteException e) {
                 // can't happen - ActivityManager is local
             }
-        }
-        if (agent == null) {
+
+            if (!startedBindSuccessfully) {
+                Slog.w(TAG, mUserIdMsg + "bind request failed for " + app.packageName);
+                mCurrentConnection = null;
+            } else {
+                Slog.d(TAG, mUserIdMsg + "awaiting agent for " + app.packageName);
+
+                // Wait 10 seconds for the agent and then time out if we still haven't bound to it.
+                long timeoutMark = System.currentTimeMillis() + 10 * 1000;
+                while (mCurrentConnection != null && mCurrentConnection.connecting && (
+                        System.currentTimeMillis() < timeoutMark)) {
+                    try {
+                        mAgentConnectLock.wait(5000);
+                    } catch (InterruptedException e) {
+                        Slog.w(TAG, mUserIdMsg + "Interrupted: " + e);
+                        mCurrentConnection = null;
+                    }
+                }
+            }
+
+            if (mCurrentConnection != null) {
+                if (!mCurrentConnection.connecting) {
+                    return mCurrentConnection.backupAgent;
+                }
+                // If we are still connecting, we've timed out.
+                Slog.w(TAG, mUserIdMsg + "Timeout waiting for agent " + app);
+                mCurrentConnection = null;
+            }
+
             mActivityManagerInternal.clearPendingBackup(mUserId);
+            return null;
         }
-        return agent;
     }
 
     /**
@@ -154,30 +175,49 @@
      * It will tell the app to destroy the agent.
      */
     public void unbindAgent(ApplicationInfo app) {
-        try {
-            mActivityManager.unbindBackupAgent(app);
-        } catch (RemoteException e) {
-            // Can't happen - activity manager is local
+        synchronized (mAgentConnectLock) {
+            if (mCurrentConnection == null) {
+                Slog.w(TAG, mUserIdMsg + "unbindAgent but no current connection");
+            } else if (!mCurrentConnection.appInfo.packageName.equals(app.packageName)) {
+                Slog.w(TAG, mUserIdMsg + "unbindAgent for unexpected package: " + app.packageName
+                        + " expected: " + mCurrentConnection.appInfo.packageName);
+            } else {
+                mCurrentConnection = null;
+            }
+
+            // Even if we weren't expecting to be bound to this agent, we should still call
+            // ActivityManager just in case. It will ignore the call if it also wasn't expecting it.
+            try {
+                mActivityManager.unbindBackupAgent(app);
+            } catch (RemoteException e) {
+                // Can't happen - activity manager is local
+            }
         }
     }
 
     /**
      * Callback: a requested backup agent has been instantiated. This should only be called from
-     * the
-     * {@link ActivityManager} when it's telling us that an agent is ready after a call to
+     * the {@link ActivityManager} when it's telling us that an agent is ready after a call to
      * {@link #bindToAgentSynchronous(ApplicationInfo, int, int)}.
      */
     public void agentConnected(String packageName, IBinder agentBinder) {
         synchronized (mAgentConnectLock) {
-            if (getCallingUid() == android.os.Process.SYSTEM_UID) {
-                Slog.d(TAG,
-                        mUserIdMsg + "agentConnected pkg=" + packageName + " agent=" + agentBinder);
-                mConnectedAgent = IBackupAgent.Stub.asInterface(agentBinder);
-                mConnecting = false;
-            } else {
+            if (getCallingUid() != Process.SYSTEM_UID) {
                 Slog.w(TAG, mUserIdMsg + "Non-system process uid=" + getCallingUid()
                         + " claiming agent connected");
+                return;
             }
+
+            Slog.d(TAG, mUserIdMsg + "agentConnected pkg=" + packageName + " agent=" + agentBinder);
+            if (mCurrentConnection == null) {
+                Slog.w(TAG, mUserIdMsg + "was not expecting connection");
+            } else if (!mCurrentConnection.appInfo.packageName.equals(packageName)) {
+                Slog.w(TAG, mUserIdMsg + "got agent for unexpected package=" + packageName);
+            } else {
+                mCurrentConnection.backupAgent = IBackupAgent.Stub.asInterface(agentBinder);
+                mCurrentConnection.connecting = false;
+            }
+
             mAgentConnectLock.notifyAll();
         }
     }
@@ -189,16 +229,22 @@
      */
     public void agentDisconnected(String packageName) {
         synchronized (mAgentConnectLock) {
-            if (getCallingUid() == Process.SYSTEM_UID) {
-                mConnectedAgent = null;
-                mConnecting = false;
-            } else {
+            if (getCallingUid() != Process.SYSTEM_UID) {
                 Slog.w(TAG, mUserIdMsg + "Non-system process uid=" + getCallingUid()
                         + " claiming agent disconnected");
+                return;
             }
+
             Slog.w(TAG, mUserIdMsg + "agentDisconnected: the backup agent for " + packageName
                     + " died: cancel current operations");
 
+            // Only abort the current connection if the agent we were expecting or already
+            // connected to has disconnected.
+            if (mCurrentConnection != null && mCurrentConnection.appInfo.packageName.equals(
+                    packageName)) {
+                mCurrentConnection = null;
+            }
+
             // Offload operation cancellation off the main thread as the cancellation callbacks
             // might call out to BackupTransport. Other operations started on the same package
             // before the cancellation callback has executed will also be cancelled by the callback.
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 8b5b93e..d4beb019 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -44,7 +44,6 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.compat.CompatChanges;
 import android.companion.AssociationInfo;
-import android.companion.AssociationRequest;
 import android.companion.virtual.ActivityPolicyExemption;
 import android.companion.virtual.IVirtualDevice;
 import android.companion.virtual.IVirtualDeviceActivityListener;
@@ -156,9 +155,6 @@
 
     private static final String PERSISTENT_ID_PREFIX_CDM_ASSOCIATION = "companion:";
 
-    private static final List<String> DEVICE_PROFILES_ALLOWING_MIRROR_DISPLAYS = List.of(
-            AssociationRequest.DEVICE_PROFILE_APP_STREAMING);
-
     /**
      * Timeout until {@link #launchPendingIntent} stops waiting for an activity to be launched.
      */
@@ -1352,11 +1348,6 @@
         return hasCustomAudioInputSupportInternal();
     }
 
-    @Override
-    public boolean canCreateMirrorDisplays() {
-        return DEVICE_PROFILES_ALLOWING_MIRROR_DISPLAYS.contains(getDeviceProfile());
-    }
-
     private boolean hasCustomAudioInputSupportInternal() {
         if (!Flags.vdmPublicApis()) {
             return false;
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 3dcca14..4cf17ae 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -69,6 +69,7 @@
 import android.sysprop.PowerProperties;
 import android.util.EventLog;
 import android.util.Slog;
+import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -303,6 +304,17 @@
      */
     @VisibleForTesting
     public long mLastBroadcastVoltageUpdateTime;
+    /**
+     * Time when the max charging current was updated last by HAL and we sent the
+     * {@link Intent#ACTION_BATTERY_CHANGED} broadcast.
+     * Note: This value is used to rate limit the {@link Intent#ACTION_BATTERY_CHANGED} broadcast
+     * so it is possible that max current was updated but we did not send the broadcast so in that
+     * case we do not update the time.
+     */
+    @VisibleForTesting
+    public long mLastBroadcastMaxChargingCurrentUpdateTime;
+
+    private boolean mIsFirstBatteryChangedUpdate = true;
 
     private Led mLed;
 
@@ -350,16 +362,21 @@
     private static final int ABSOLUTE_DECI_CELSIUS_DIFF_FOR_TEMP_UPDATE = 10;
     /**
      * This value is used to rate limit the {@link Intent#ACTION_BATTERY_CHANGED} broadcast. We
-     * only send the broadcast if the last voltage was updated at least 20s seconds back and has a
+     * only send the broadcast if the last voltage was updated at least 20 seconds back and has a
      * fluctuation of at least 1%.
      */
     private static final int TIME_DIFF_FOR_VOLTAGE_UPDATE_MS = 20000;
     /**
      * The value is used to rate limit the {@link Intent#ACTION_BATTERY_CHANGED} broadcast. We
-     * only send the broadcast if the last voltage was updated at least 20s seconds back and has a
+     * only send the broadcast if the last voltage was updated at least 20 seconds back and has a
      * fluctuation of at least 1%.
      */
     private static final float BASE_POINT_DIFF_FOR_VOLTAGE_UPDATE = 0.01f;
+    /**
+     * This value is used to rate limit the {@link Intent#ACTION_BATTERY_CHANGED} broadcast. We
+     * only send the broadcast if the last max charging current was updated at least 5 seconds back.
+     */
+    private static final int TIME_DIFF_FOR_MAX_CHARGING_CURRENT_UPDATE_MS = 5000;
 
     private final Handler.Callback mLocalCallback = msg -> {
         switch (msg.what) {
@@ -1252,8 +1269,10 @@
         if (!com.android.server.flags.Flags.rateLimitBatteryChangedBroadcast()) {
             return false;
         }
-        if (mLastBroadcastBatteryVoltage == 0 || mLastBroadcastBatteryTemperature == 0) {
+        if (mIsFirstBatteryChangedUpdate) {
             mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime();
+            mLastBroadcastMaxChargingCurrentUpdateTime = SystemClock.elapsedRealtime();
+            mIsFirstBatteryChangedUpdate = false;
             return false;
         }
 
@@ -1261,13 +1280,14 @@
                 mLastBroadcastBatteryVoltage != mHealthInfo.batteryVoltageMillivolts;
         final boolean temperatureUpdated =
                 mLastBroadcastBatteryTemperature != mHealthInfo.batteryTemperatureTenthsCelsius;
+        final boolean maxChargingCurrentUpdated =
+                mLastBroadcastMaxChargingCurrent != mHealthInfo.maxChargingCurrentMicroamps;
         final boolean otherStatesUpdated = forceUpdate
                 || mHealthInfo.batteryStatus != mLastBroadcastBatteryStatus
                 || mHealthInfo.batteryHealth != mLastBroadcastBatteryHealth
                 || mHealthInfo.batteryPresent != mLastBroadcastBatteryPresent
                 || mHealthInfo.batteryLevel != mLastBroadcastBatteryLevel
                 || mPlugType != mLastBroadcastPlugType
-                || mHealthInfo.maxChargingCurrentMicroamps != mLastBroadcastMaxChargingCurrent
                 || mHealthInfo.maxChargingVoltageMicrovolts != mLastBroadcastMaxChargingVoltage
                 || mInvalidCharger != mLastBroadcastInvalidCharger
                 || mHealthInfo.batteryCycleCount != mLastBroadcastBatteryCycleCount
@@ -1280,6 +1300,9 @@
             if (voltageUpdated) {
                 mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime();
             }
+            if (maxChargingCurrentUpdated) {
+                mLastBroadcastMaxChargingCurrentUpdateTime = SystemClock.elapsedRealtime();
+            }
             return false;
         }
 
@@ -1295,6 +1318,9 @@
                         >= TIME_DIFF_FOR_VOLTAGE_UPDATE_MS) {
             mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime();
 
+            if (maxChargingCurrentUpdated) {
+                mLastBroadcastMaxChargingCurrentUpdateTime = SystemClock.elapsedRealtime();
+            }
             return false;
         }
 
@@ -1307,6 +1333,20 @@
             if (voltageUpdated) {
                 mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime();
             }
+            if (maxChargingCurrentUpdated) {
+                mLastBroadcastMaxChargingCurrentUpdateTime = SystemClock.elapsedRealtime();
+            }
+            return false;
+        }
+
+        if (maxChargingCurrentUpdated
+                && SystemClock.elapsedRealtime() - mLastBroadcastMaxChargingCurrentUpdateTime
+                >= TIME_DIFF_FOR_MAX_CHARGING_CURRENT_UPDATE_MS) {
+            mLastBroadcastMaxChargingCurrentUpdateTime = SystemClock.elapsedRealtime();
+
+            if (voltageUpdated) {
+                mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime();
+            }
             return false;
         }
 
@@ -1615,6 +1655,9 @@
                 pw.println("  Wireless powered: " + mHealthInfo.chargerWirelessOnline);
                 pw.println("  Dock powered: " + mHealthInfo.chargerDockOnline);
                 pw.println("  Max charging current: " + mHealthInfo.maxChargingCurrentMicroamps);
+                pw.println(" Time when the latest updated value of the Max charging current was"
+                        + " sent via battery changed broadcast: "
+                        + TimeUtils.formatDuration(mLastBroadcastMaxChargingCurrentUpdateTime));
                 pw.println("  Max charging voltage: " + mHealthInfo.maxChargingVoltageMicrovolts);
                 pw.println("  Charge counter: " + mHealthInfo.batteryChargeCounterUah);
                 pw.println("  status: " + mHealthInfo.batteryStatus);
@@ -1624,7 +1667,8 @@
                 pw.println("  scale: " + BATTERY_SCALE);
                 pw.println("  voltage: " + mHealthInfo.batteryVoltageMillivolts);
                 pw.println(" Time when the latest updated value of the voltage was sent via "
-                        + "battery changed broadcast: " + mLastBroadcastVoltageUpdateTime);
+                        + "battery changed broadcast: "
+                        + TimeUtils.formatDuration(mLastBroadcastVoltageUpdateTime));
                 pw.println(" The last voltage value sent via the battery changed broadcast: "
                         + mLastBroadcastBatteryVoltage);
                 pw.println("  temperature: " + mHealthInfo.batteryTemperatureTenthsCelsius);
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 485bf31..0286f7b 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -65,6 +65,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.IRemoteCallback;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
@@ -347,7 +348,8 @@
                         + " packages after considering preloads");
             }
 
-            if (CompatChanges.isChangeEnabled(LOG_MBA_INFO)) {
+            if (!android.app.Flags.backgroundInstallControlCallbackApi()
+                    && CompatChanges.isChangeEnabled(LOG_MBA_INFO)) {
                 // lastly measure all newly installed MBAs
                 List<IBinaryTransparencyService.AppInfo> allMbaInfo =
                         collectAllSilentInstalledMbaInfo(packagesMeasured);
@@ -1158,6 +1160,49 @@
     }
 
     /**
+     * Receive callbacks from BIC to write silently installed apps to log
+     *
+     * TODO: Add a host test for testing registration and callback of BicCallbackHandler
+     *  b/380002484
+     */
+    static class BicCallbackHandler extends IRemoteCallback.Stub {
+        private static final String BIC_CALLBACK_HANDLER_TAG =
+                "BTS.BicCallbackHandler";
+        private final BinaryTransparencyServiceImpl mServiceImpl;
+        static final String FLAGGED_PACKAGE_NAME_KEY = "packageName";
+
+        BicCallbackHandler(BinaryTransparencyServiceImpl impl) {
+            mServiceImpl = impl;
+        }
+
+        @Override
+        public void sendResult(Bundle data) {
+            String packageName = data.getString(FLAGGED_PACKAGE_NAME_KEY);
+            if (packageName == null) return;
+            if (DEBUG) {
+                Slog.d(BIC_CALLBACK_HANDLER_TAG, "background install event detected for "
+                        + packageName);
+            }
+
+            PackageState packageState = LocalServices.getService(PackageManagerInternal.class)
+                    .getPackageStateInternal(packageName);
+            if (packageState == null) {
+                Slog.w(TAG, "Package state is unavailable, ignoring the package "
+                        + packageName);
+                return;
+            }
+            if (packageState.isUpdatedSystemApp()) {
+                return;
+            }
+            List<IBinaryTransparencyService.AppInfo> mbaInfo = mServiceImpl.collectAppInfo(
+                    packageState, MBA_STATUS_NEW_INSTALL);
+            for (IBinaryTransparencyService.AppInfo appInfo : mbaInfo) {
+                mServiceImpl.writeAppInfoToLog(appInfo);
+            }
+        }
+    };
+
+    /**
      * Called when the system service should publish a binder service using
      * {@link #publishBinderService(String, IBinder).}
      */
@@ -1534,6 +1579,29 @@
         }
     }
 
+    private void registerBicCallback() {
+        if(!com.android.server.flags.Flags.optionalBackgroundInstallControl()) {
+            Slog.d(TAG, "BICS is disabled for this device, skipping registration.");
+            return;
+        }
+        IBackgroundInstallControlService iBics =
+                IBackgroundInstallControlService.Stub.asInterface(
+                        ServiceManager.getService(
+                                Context.BACKGROUND_INSTALL_CONTROL_SERVICE));
+        if(iBics == null) {
+            Slog.e(TAG, "Failed to register BackgroundInstallControl callback, either "
+                + "background install control service does not exist or disabled on this "
+                + "build.");
+            return;
+        }
+        try {
+            iBics.registerBackgroundInstallCallback(
+                    new BicCallbackHandler(mServiceImpl));
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to register BackgroundInstallControl callback.");
+        }
+    }
+
     private boolean isPackagePreloaded(String packageName) {
         PackageManager pm = mContext.getPackageManager();
         try {
@@ -1596,6 +1664,10 @@
     private void registerAllPackageUpdateObservers() {
         registerApkAndNonStagedApexUpdateListener();
         registerStagedApexUpdateObserver();
+        if (android.app.Flags.backgroundInstallControlCallbackApi()
+                && CompatChanges.isChangeEnabled(LOG_MBA_INFO)) {
+            registerBicCallback();
+        }
     }
 
     private String translateContentDigestAlgorithmIdToString(int algorithmId) {
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 99772c3..03d6c8b 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -1318,6 +1318,7 @@
                         }
                         XmlUtils.skipCurrentTag(parser);
                     } break;
+                    case "disabled-in-sku":
                     case "disabled-until-used-preinstalled-carrier-app": {
                         if (allowAppConfigs) {
                             String pkgname = parser.getAttributeValue(null, "package");
@@ -1334,6 +1335,24 @@
                         }
                         XmlUtils.skipCurrentTag(parser);
                     } break;
+                    case "enabled-in-sku-override": {
+                        if (allowAppConfigs) {
+                            String pkgname = parser.getAttributeValue(null, "package");
+                            if (pkgname == null) {
+                                Slog.w(TAG,
+                                        "<" + name + "> without "
+                                                + "package in " + permFile + " at "
+                                                + parser.getPositionDescription());
+                            } else if (!mDisabledUntilUsedPreinstalledCarrierApps.remove(pkgname)) {
+                                Slog.w(TAG,
+                                        "<" + name + "> packagename:" + pkgname + " not included"
+                                                + "in disabled-in-sku");
+                            }
+                        } else {
+                            logNotAllowedInPartition(name, permFile, parser);
+                        }
+                        XmlUtils.skipCurrentTag(parser);
+                    } break;
                     case "privapp-permissions": {
                         if (allowPrivappPermissions) {
                             // privapp permissions from system, apex, vendor, product and
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index ce66dc3..8da8358 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -176,6 +176,10 @@
                     "include-filter": "com.android.server.wm.BackgroundActivityStart*"
                 }
             ]
+        },
+        {
+            "name": "FrameworksMockingServicesTests_service_batteryServiceTest",
+            "file_patterns": ["BatteryService\\.java"]
         }
    ]
 }
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 06e6c8b..2012f56 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -48,7 +48,6 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
-import android.net.vcn.Flags;
 import android.net.vcn.IVcnManagementService;
 import android.net.vcn.IVcnStatusCallback;
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -890,20 +889,11 @@
         while (configsIterator.hasNext()) {
             final ParcelUuid subGrp = configsIterator.next();
 
-            if (Flags.fixConfigGarbageCollection()) {
-                if (!subGroups.contains(subGrp)) {
-                    // Trim subGrps with no more subscriptions; must have moved to another subGrp
-                    logDbg("Garbage collect VcnConfig for group=" + subGrp);
-                    configsIterator.remove();
-                    shouldWrite = true;
-                }
-            } else {
-                final List<SubscriptionInfo> subscriptions = subMgr.getSubscriptionsInGroup(subGrp);
-                if (subscriptions == null || subscriptions.isEmpty()) {
-                    // Trim subGrps with no more subscriptions; must have moved to another subGrp
-                    configsIterator.remove();
-                    shouldWrite = true;
-                }
+            if (!subGroups.contains(subGrp)) {
+                // Trim subGrps with no more subscriptions; must have moved to another subGrp
+                logDbg("Garbage collect VcnConfig for group=" + subGrp);
+                configsIterator.remove();
+                shouldWrite = true;
             }
         }
 
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index ab3ab15..71cbc10 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -9319,6 +9319,46 @@
             Slog.e(TAG, "stopForegroundServiceDelegateLocked delegate does not exist");
         }
     }
+    /**
+     * Handles notifications from MediaSessionService about active media service.
+     * This method evaluates the provided information and transitions corresponding service to
+     * foreground state.
+     *
+     * @param packageName The package name of the app running the service.
+     * @param userId The user ID associated with the service.
+     * @param notificationId The ID of the media notification associated with the service.
+     */
+    void notifyActiveMediaForegroundServiceLocked(@NonNull String packageName,
+            @UserIdInt int userId, int notificationId) {
+        if (!enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
+            return;
+        }
+
+        final ServiceMap smap = mServiceMap.get(userId);
+        if (smap == null) {
+            return;
+        }
+        final int serviceSize = smap.mServicesByInstanceName.size();
+        for (int i = 0; i < serviceSize; i++) {
+            final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i);
+            if (sr.appInfo.packageName.equals(packageName) && !sr.isForeground) {
+                // foregroundServiceType is cleared when media session is user-disengaged
+                // and calls notifyInactiveMediaForegroundService->setServiceForegroundInnerLocked.
+                if (sr.foregroundServiceType
+                        == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE
+                        && sr.foregroundId == notificationId) {
+                    if (DEBUG_FOREGROUND_SERVICE) {
+                        Slog.d(TAG, "Moving media service to foreground for package "
+                                + packageName);
+                    }
+                    setServiceForegroundInnerLocked(sr, sr.foregroundId,
+                             sr.foregroundNoti, /* flags */ 0,
+                             ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK,
+                             /* callingUidStart */ 0);
+                }
+            }
+        }
+    }
 
     /**
      * Handles notifications from MediaSessionService about inactive media foreground services.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5c5361b..053ec82 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -131,6 +131,9 @@
 import static android.provider.Settings.Global.DEBUG_APP;
 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
 import static android.security.Flags.preventIntentRedirect;
+import static android.security.Flags.preventIntentRedirectCollectNestedKeysOnServerIfNotCollected;
+import static android.security.Flags.preventIntentRedirectShowToast;
+import static android.security.Flags.preventIntentRedirectThrowExceptionIfNestedKeysNotCollected;
 import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
 import static android.view.Display.INVALID_DISPLAY;
 
@@ -387,6 +390,7 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.view.autofill.AutofillManagerInternal;
+import android.widget.Toast;
 
 import com.android.internal.annotations.CompositeRWLock;
 import com.android.internal.annotations.GuardedBy;
@@ -437,6 +441,7 @@
 import com.android.server.SystemService;
 import com.android.server.SystemServiceManager;
 import com.android.server.ThreadPriorityBooster;
+import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.am.LowMemDetector.MemFactor;
 import com.android.server.appop.AppOpsService;
@@ -478,6 +483,7 @@
 
 import dalvik.annotation.optimization.NeverCompile;
 import dalvik.system.VMRuntime;
+
 import libcore.util.EmptyArray;
 
 import java.io.File;
@@ -17923,6 +17929,15 @@
         }
 
         @Override
+        public void notifyActiveMediaForegroundService(@NonNull String packageName,
+                @UserIdInt int userId, int notificationId) {
+            synchronized (ActivityManagerService.this) {
+                mServices.notifyActiveMediaForegroundServiceLocked(packageName, userId,
+                        notificationId);
+            }
+        }
+
+        @Override
         public void notifyInactiveMediaForegroundService(@NonNull String packageName,
                 @UserIdInt int userId, int notificationId) {
             synchronized (ActivityManagerService.this) {
@@ -19304,9 +19319,32 @@
      */
     public void addCreatorToken(@Nullable Intent intent, String creatorPackage) {
         if (!preventIntentRedirect()) return;
-
         if (intent == null) return;
 
+        if ((intent.getExtendedFlags() & Intent.EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED) == 0) {
+            Slog.wtf(TAG,
+                    "[IntentRedirect] The intent does not have its nested keys collected as a "
+                            + "preparation for creating intent creator tokens. Intent: "
+                            + intent + "; creatorPackage: " + creatorPackage);
+            if (preventIntentRedirectShowToast()) {
+                UiThread.getHandler().post(
+                        () -> Toast.makeText(mContext,
+                                "Nested keys not collected. go/report-bug-intentRedir to report a"
+                                        + " bug", Toast.LENGTH_LONG).show());
+            }
+            if (preventIntentRedirectThrowExceptionIfNestedKeysNotCollected()) {
+                // this flag will be internal only, not ramped to public.
+                throw new SecurityException(
+                        "The intent does not have its nested keys collected as a preparation for "
+                                + "creating intent creator tokens. Intent: "
+                                + intent + "; creatorPackage: " + creatorPackage);
+            }
+            if (preventIntentRedirectCollectNestedKeysOnServerIfNotCollected()) {
+                // this flag will be ramped to public.
+                intent.collectExtraIntentKeys();
+            }
+        }
+
         String targetPackage = intent.getComponent() != null
                 ? intent.getComponent().getPackageName()
                 : intent.getPackage();
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index d3d3fc9..37d058b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -471,14 +471,14 @@
         }
         int userId = UserHandle.USER_CURRENT;
         final String cmd = getNextArgRequired();
-        if ("inactive".equals(cmd)) {
+        if ("inactive".equals(cmd) || "active".equals(cmd)) {
             String opt;
             while ((opt = getNextOption()) != null) {
                 if (opt.equals("--user")) {
                     userId = UserHandle.parseUserArg(getNextArgRequired());
                     if (userId == UserHandle.USER_ALL) {
                         err.println(
-                                "Error: Can't set media fgs inactive with user 'all'");
+                                "Error: Can't set media fgs with user 'all'");
                         return -1;
                     }
                 } else {
@@ -492,8 +492,13 @@
                 err.println("Error: notification id cannot be zero");
                 return -1;
             }
-            mInternal.mInternal.notifyInactiveMediaForegroundService(pkgName,
-                    userId, notificationId);
+            if ("inactive".equals(cmd)) {
+                mInternal.mInternal.notifyInactiveMediaForegroundService(pkgName,
+                        userId, notificationId);
+            } else {
+                mInternal.mInternal.notifyActiveMediaForegroundService(pkgName,
+                        userId, notificationId);
+            }
             return 0;
         }
         err.println("Error: Unknown set-media-foreground-service command: " + cmd);
@@ -852,6 +857,7 @@
                 }
                 options.setDismissKeyguardIfInsecure();
             }
+            intent.collectExtraIntentKeys();
             if (mWaitOption) {
                 result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, null, intent,
                         mimeType, null, null, 0, mStartFlags, profilerInfo,
@@ -970,6 +976,7 @@
         }
         pw.println("Starting service: " + intent);
         pw.flush();
+        intent.collectExtraIntentKeys();
         ComponentName cn = mInterface.startService(null, intent, intent.getType(),
                 asForeground, SHELL_PACKAGE_NAME, null, mUserId);
         if (cn == null) {
@@ -1002,6 +1009,7 @@
         }
         pw.println("Stopping service: " + intent);
         pw.flush();
+        intent.collectExtraIntentKeys();
         int result = mInterface.stopService(null, intent, intent.getType(), mUserId);
         if (result == 0) {
             err.println("Service not stopped: was not running.");
@@ -1399,6 +1407,12 @@
             heapFile = "/data/local/tmp/heapdump-" + logNameTimeString + ".prof";
         }
 
+        String argAfterHeapFile = getNextArg();
+        if (argAfterHeapFile != null) {
+            err.println("Error: Arguments cannot be placed after the heap file");
+            return -1;
+        }
+
         // Writes an error message to stderr on failure
         ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
         if (fd == null) {
@@ -4683,9 +4697,9 @@
             pw.println("         --protobuf: format output using protobuffer");
             pw.println("  set-app-zygote-preload-timeout <TIMEOUT_IN_MS>");
             pw.println("         Set the timeout for preloading code in the app-zygote");
-            pw.println("  set-media-foreground-service inactive [--user USER_ID]"
-                    + " <PACKAGE> <NOTIFICATION_ID>");
-            pw.println("         Set an app's media foreground service inactive.");
+            pw.println("  set-media-foreground-service inactive|active [--user USER_ID] <PACKAGE>"
+                            + " <NOTIFICATION_ID>");
+            pw.println("         Set an app's media service inactive or active.");
             Intent.printIntentArgsHelp(pw, "");
         }
     }
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 415f78a..b7a5f3e 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -598,7 +598,7 @@
         }
 
         if (r != null) {
-            mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode(),
+            mPackageWatchdog.notifyPackageFailure(r.getPackageListWithVersionCode(),
                     PackageWatchdog.FAILURE_REASON_APP_CRASH);
 
             synchronized (mService) {
@@ -1142,7 +1142,7 @@
         }
         // Notify PackageWatchdog without the lock held
         if (packageList != null) {
-            mPackageWatchdog.onPackageFailure(packageList,
+            mPackageWatchdog.notifyPackageFailure(packageList,
                     PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
         }
     }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 2eb9f3c..400ebfd 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1126,20 +1126,8 @@
                     break;
                 }
                 case FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL:
-                    if (Flags.disableCompositeBatteryUsageStatsAtoms()) {
-                        return StatsManager.PULL_SKIP;
-                    }
+                    return StatsManager.PULL_SKIP;
 
-                    final BatteryUsageStatsQuery queryPowerProfile =
-                            new BatteryUsageStatsQuery.Builder()
-                                    .setMaxStatsAgeMs(0)
-                                    .includeProcessStateData()
-                                    .includeVirtualUids()
-                                    .powerProfileModeledOnly()
-                                    .includePowerModels()
-                                    .build();
-                    bus = getBatteryUsageStats(List.of(queryPowerProfile)).get(0);
-                    break;
                 case FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET: {
                     if (Flags.disableCompositeBatteryUsageStatsAtoms()) {
                         return StatsManager.PULL_SKIP;
@@ -1262,6 +1250,17 @@
             mFrameworkStatsLogger = frameworkStatsLogger;
         }
 
+        private static float clampPowerMah(double powerMah, String consumer) {
+            float resultPowerMah = 0;
+            if (powerMah <= Float.MAX_VALUE && powerMah >= Float.MIN_VALUE) {
+                resultPowerMah = (float) powerMah;
+            } else {
+                // Handle overflow appropriately
+                Slog.wtfStack(TAG, consumer + " reported powerMah float overflow: " + powerMah);
+            }
+            return resultPowerMah;
+        }
+
         /**
          * Generates StatsEvents for the supplied battery usage stats and adds them to
          * the supplied list.
@@ -1282,7 +1281,8 @@
                     bus.getAggregateBatteryConsumer(
                             BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
 
-            final float totalDeviceConsumedPowerMah = (float) deviceConsumer.getConsumedPower();
+            final float totalDeviceConsumedPowerMah =
+                    clampPowerMah(deviceConsumer.getConsumedPower(), "AggregateBatteryConsumer");
 
             for (@BatteryConsumer.PowerComponentId int powerComponentId :
                     deviceConsumer.getPowerComponentIds()) {
@@ -1314,7 +1314,9 @@
             // Log single atom for BatteryUsageStats per uid/process_state/component/etc.
             for (UidBatteryConsumer uidConsumer : uidConsumers) {
                 final int uid = uidConsumer.getUid();
-                final float totalConsumedPowerMah = (float) uidConsumer.getConsumedPower();
+
+                final float totalConsumedPowerMah =
+                        clampPowerMah(uidConsumer.getConsumedPower(), "uidConsumer-" + uid);
 
                 for (@BatteryConsumer.PowerComponentId int powerComponentId :
                         uidConsumer.getPowerComponentIds()) {
@@ -1358,7 +1360,10 @@
             }
 
             final String powerComponentName = batteryConsumer.getPowerComponentName(componentId);
-            final float powerMah = (float) batteryConsumer.getConsumedPower(key);
+            final double consumedPowerMah = batteryConsumer.getConsumedPower(key);
+            float powerMah =
+                    clampPowerMah(
+                            consumedPowerMah, "uidConsumer-" + uid + "-" + powerComponentName);
             final long powerComponentDurationMillis = batteryConsumer.getUsageDurationMillis(key);
 
             if (powerMah == 0 && powerComponentDurationMillis == 0) {
@@ -3167,7 +3172,7 @@
         }
     }
 
-    private void dumpUsageStats(FileDescriptor fd, PrintWriter pw, int model,
+    private void dumpUsageStats(FileDescriptor fd, PrintWriter pw,
             boolean proto, boolean accumulated) {
         awaitCompletion();
         syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
@@ -3179,9 +3184,6 @@
         if (Flags.batteryUsageStatsByPowerAndScreenState()) {
             builder.includeScreenStateData().includePowerStateData();
         }
-        if (model == BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
-            builder.powerProfileModeledOnly();
-        }
         if (accumulated) {
             builder.accumulated();
         }
@@ -3376,7 +3378,6 @@
                     dumpPowerProfile(pw);
                     return;
                 } else if ("--usage".equals(arg)) {
-                    int model = BatteryConsumer.POWER_MODEL_UNDEFINED;
                     boolean proto = false;
                     boolean accumulated = false;
                     for (int j = i + 1; j < args.length; j++) {
@@ -3384,29 +3385,12 @@
                             case "--proto":
                                 proto = true;
                                 break;
-                            case "--model": {
-                                if (j + 1 < args.length) {
-                                    j++;
-                                    if ("power-profile".equals(args[j])) {
-                                        model = BatteryConsumer.POWER_MODEL_POWER_PROFILE;
-                                    } else {
-                                        pw.println("Unknown power model: " + args[j]);
-                                        dumpHelp(pw);
-                                        return;
-                                    }
-                                } else {
-                                    pw.println("--model without a value");
-                                    dumpHelp(pw);
-                                    return;
-                                }
-                                break;
-                            }
                             case "--accumulated":
                                 accumulated = true;
                                 break;
                         }
                     }
-                    dumpUsageStats(fd, pw, model, proto, accumulated);
+                    dumpUsageStats(fd, pw, proto, accumulated);
                     return;
                 } else if ("--wakeups".equals(arg)) {
                     mCpuWakeupStats.dump(new IndentingPrintWriter(pw, "  "),
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index da5b1fd..2f5362f 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -2122,7 +2122,7 @@
                     Slog.d(TAG_AM,
                             "Performing native compaction for pid=" + pid
                                     + " type=" + compactProfile.name());
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactSystem");
+                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactNative");
                     try {
                         mProcessDependencies.performCompaction(compactProfile, pid);
                     } catch (Exception e) {
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index ab7cd5f..1a6051b 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -66,6 +66,9 @@
 # Activity Security
 per-file ActivityManager* = file:/ACTIVITY_SECURITY_OWNERS
 
+# Aconfig Flags
+per-file flags.aconfig = yamasani@google.com, bills@google.com, nalini@google.com
+
 # Londoners
 michaelwr@google.com #{LAST_RESORT_SUGGESTION}
 narayan@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index b84bf6b9..f42641e 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1376,9 +1376,11 @@
             ProcessRecord app = lruList.get(i);
             final ProcessStateRecord state = app.mState;
             if (!app.isKilledByAm() && app.getThread() != null) {
-                // We don't need to apply the update for the process which didn't get computed
-                if (state.getCompletedAdjSeq() == mAdjSeq) {
-                    applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true);
+                if (!Flags.fixApplyOomadjOrder()) {
+                    // We don't need to apply the update for the process which didn't get computed
+                    if (state.getCompletedAdjSeq() == mAdjSeq) {
+                        applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true);
+                    }
                 }
 
                 if (app.isPendingFinishAttach()) {
@@ -1480,6 +1482,19 @@
             }
         }
 
+        if (Flags.fixApplyOomadjOrder()) {
+            // We need to apply the update starting from the least recently used.
+            // Otherwise, they won't be in the correct LRU order in LMKD.
+            for (int i = 0; i < numLru; i++) {
+                ProcessRecord app = lruList.get(i);
+                // We don't need to apply the update for the process which didn't get computed
+                if (!app.isKilledByAm() && app.getThread() != null
+                        && app.mState.getCompletedAdjSeq() == mAdjSeq) {
+                    applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true);
+                }
+            }
+        }
+
         if (!mProcsToOomAdj.isEmpty()) {
             mInjector.batchSetOomAdj(mProcsToOomAdj);
             mProcsToOomAdj.clear();
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 78c4f74..7660c15 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -140,6 +140,8 @@
     // The list is sorted.
     @VisibleForTesting
     static final String[] sDeviceConfigAconfigScopes = new String[] {
+        "aaos_audio_triage",
+        "aaos_power_triage",
         "aaos_sdv",
         "accessibility",
         "android_core_networking",
@@ -533,9 +535,8 @@
      * @param packageName the package of the flag
      * @param flagName the name of the flag
      * @param immediate if true, clear immediately; otherwise, clear on next reboot
-     *
-     * @hide
      */
+    @VisibleForTesting
     public static void writeFlagOverrideRemovalRequest(
         ProtoOutputStream proto, String packageName, String flagName, boolean immediate) {
       long msgsToken = proto.start(StorageRequestMessages.MSGS);
@@ -591,7 +592,8 @@
      * apply flag local override in aconfig new storage
      * @param props
      */
-    static void setLocalOverridesInNewStorage(DeviceConfig.Properties props) {
+    @VisibleForTesting
+    public static void setLocalOverridesInNewStorage(DeviceConfig.Properties props) {
         int num_requests = 0;
         ProtoOutputStream requests = new ProtoOutputStream();
         for (String flagName : props.getKeyset()) {
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index 6d247d2..89e4a8d 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -245,6 +245,14 @@
 }
 
 flag {
+    name: "fix_apply_oomadj_order"
+    namespace: "backstage_power"
+    is_fixed_read_only: true
+    description: "Fix the iteration direction of process LRU list when applying oom adj"
+    bug: "378580264"
+}
+
+flag {
     name: "phantom_processes_fix"
     namespace: "backstage_power"
     description: "Make sure setProcessGroupForPhantomProcessOfApp deals with phantom processes properly"
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 8c5152f..6f8dc10 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -100,6 +100,7 @@
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
 import com.android.server.SystemService.TargetUser;
+import com.android.server.utils.LazyJniRegistrar;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.CompatScaleProvider;
 
@@ -158,6 +159,10 @@
     private static final String GAME_MODE_INTERVENTION_LIST_FILE_NAME =
             "game_mode_intervention.list";
 
+    static {
+        LazyJniRegistrar.registerGameManagerService();
+    }
+
     private final Context mContext;
     private final Object mLock = new Object();
     private final Object mDeviceConfigLock = new Object();
diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
index ed41f2e..fa2e674 100644
--- a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
@@ -31,7 +31,6 @@
 import static android.app.AppOpsManager.OP_NONE;
 import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO;
-import static android.app.AppOpsManager.OP_TAKE_AUDIO_FOCUS;
 import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
 import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
 import static android.app.AppOpsManager.UID_STATE_NONEXISTENT;
@@ -177,8 +176,6 @@
             case OP_RECORD_AUDIO:
             case OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO:
                 return PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
-            case OP_TAKE_AUDIO_FOCUS:
-                return PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL;
             default:
                 return PROCESS_CAPABILITY_NONE;
         }
diff --git a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
index 5283edd..4736918 100644
--- a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
+++ b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
@@ -24,6 +24,7 @@
 import static android.Manifest.permission.CAPTURE_MEDIA_OUTPUT;
 import static android.Manifest.permission.CAPTURE_TUNER_AUDIO_INPUT;
 import static android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT;
+import static android.Manifest.permission.BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION;
 import static android.Manifest.permission.MODIFY_AUDIO_ROUTING;
 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS;
 import static android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS;
@@ -37,7 +38,6 @@
 import android.os.UserHandle;
 import android.util.ArraySet;
 import android.util.IntArray;
-import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.media.permission.INativePermissionController;
@@ -82,6 +82,8 @@
         MONITORED_PERMS[PermissionEnum.CAPTURE_VOICE_COMMUNICATION_OUTPUT] =
                 CAPTURE_VOICE_COMMUNICATION_OUTPUT;
         MONITORED_PERMS[PermissionEnum.BLUETOOTH_CONNECT] = BLUETOOTH_CONNECT;
+        MONITORED_PERMS[PermissionEnum.BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION] =
+                BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION;
     }
 
     private final Object mLock = new Object();
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 6e6bf80..c6317bd 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -49,6 +49,7 @@
 import static android.media.AudioManager.STREAM_SYSTEM;
 import static android.media.audio.Flags.autoPublicVolumeApiHardening;
 import static android.media.audio.Flags.automaticBtDeviceType;
+import static android.media.audio.Flags.concurrentAudioRecordBypassPermission;
 import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency;
 import static android.media.audio.Flags.focusFreezeTestApi;
 import static android.media.audio.Flags.roForegroundAudioControl;
@@ -4888,6 +4889,8 @@
                 + equalScoLeaVcIndexRange());
         pw.println("\tcom.android.media.audio.ringMyCar:"
                 + ringMyCar());
+        pw.println("\tandroid.media.audio.Flags.concurrentAudioRecordBypassPermission:"
+                + concurrentAudioRecordBypassPermission());
     }
 
     private void dumpAudioMode(PrintWriter pw) {
@@ -4951,22 +4954,24 @@
         }
 
         final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
-        final Set<Integer> absVolumeMultiModeCaseDevices =
-                AudioSystem.intersectionAudioDeviceTypes(
-                        mAbsVolumeMultiModeCaseDevices, deviceTypes);
-        if (absVolumeMultiModeCaseDevices.isEmpty()) {
+        Set<Integer> absVolumeDeviceTypes = new ArraySet<>(
+                AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
+        absVolumeDeviceTypes.addAll(mAbsVolumeMultiModeCaseDevices);
+
+        final Set<Integer> absVolumeDevices =
+                AudioSystem.intersectionAudioDeviceTypes(absVolumeDeviceTypes, deviceTypes);
+        if (absVolumeDevices.isEmpty()) {
             return;
         }
-        if (absVolumeMultiModeCaseDevices.size() > 1) {
+        if (absVolumeDevices.size() > 1) {
             Log.w(TAG, "onUpdateContextualVolumes too many active devices: "
-                    + absVolumeMultiModeCaseDevices.stream().map(AudioSystem::getOutputDeviceName)
+                    + absVolumeDevices.stream().map(AudioSystem::getOutputDeviceName)
                         .collect(Collectors.joining(","))
                     + ", for stream: " + streamType);
             return;
         }
 
-        final int device = absVolumeMultiModeCaseDevices.toArray(new Integer[0])[0].intValue();
-
+        final int device = absVolumeDevices.toArray(new Integer[0])[0].intValue();
         final int index = getStreamVolume(streamType, device);
 
         if (DEBUG_VOL) {
@@ -4980,6 +4985,8 @@
                     getVssForStreamOrDefault(streamType).getMaxIndex(), streamType);
         } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
             mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
+        } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)) {
+            mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index);
         } else {
             return;
         }
@@ -11422,6 +11429,10 @@
         return mSpatializerHelper.canBeSpatialized(attributes, format);
     }
 
+    public @NonNull List<Integer> getSpatializedChannelMasks() {
+        return mSpatializerHelper.getSpatializedChannelMasks();
+    }
+
     /** @see Spatializer.SpatializerInfoDispatcherStub */
     public void registerSpatializerCallback(
             @NonNull ISpatializerCallback cb) {
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index a62ac82..1c01fb9 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -17,13 +17,14 @@
 package com.android.server.audio;
 
 import static android.media.AudioPlaybackConfiguration.EXTRA_PLAYER_EVENT_MUTE;
-import static android.media.AudioPlaybackConfiguration.MUTED_BY_APP_OPS;
+import static android.media.AudioPlaybackConfiguration.MUTED_BY_OP_PLAY_AUDIO;
 import static android.media.AudioPlaybackConfiguration.MUTED_BY_CLIENT_VOLUME;
 import static android.media.AudioPlaybackConfiguration.MUTED_BY_MASTER;
 import static android.media.AudioPlaybackConfiguration.MUTED_BY_PORT_VOLUME;
 import static android.media.AudioPlaybackConfiguration.MUTED_BY_STREAM_MUTED;
 import static android.media.AudioPlaybackConfiguration.MUTED_BY_STREAM_VOLUME;
 import static android.media.AudioPlaybackConfiguration.MUTED_BY_VOLUME_SHAPER;
+import static android.media.AudioPlaybackConfiguration.MUTED_BY_OP_CONTROL_AUDIO;
 import static android.media.AudioPlaybackConfiguration.PLAYER_PIID_INVALID;
 import static android.media.AudioPlaybackConfiguration.PLAYER_UPDATE_MUTED;
 
@@ -1376,8 +1377,8 @@
                         if ((eventValue & MUTED_BY_STREAM_MUTED) != 0) {
                             builder.append("streamMute ");
                         }
-                        if ((eventValue & MUTED_BY_APP_OPS) != 0) {
-                            builder.append("appOps ");
+                        if ((eventValue & MUTED_BY_OP_PLAY_AUDIO) != 0) {
+                            builder.append("opPlayAudio ");
                         }
                         if ((eventValue & MUTED_BY_CLIENT_VOLUME) != 0) {
                             builder.append("clientVolume ");
@@ -1388,6 +1389,10 @@
                         if ((eventValue & MUTED_BY_PORT_VOLUME) != 0) {
                             builder.append("portVolume ");
                         }
+                        if ((eventValue & MUTED_BY_OP_CONTROL_AUDIO) != 0) {
+                            builder.append("opControlAudio ");
+                        }
+
                     }
                     return builder.toString();
                 default:
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 9265ff2..afa90d5 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -59,6 +59,8 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 import java.util.UUID;
@@ -1100,6 +1102,23 @@
         return able;
     }
 
+    synchronized @NonNull List<Integer> getSpatializedChannelMasks() {
+        if (!checkSpatializer("getSpatializedChannelMasks")) {
+            return Collections.emptyList();
+        }
+        try {
+            final int[] nativeMasks = new int[0]; // FIXME mSpat query goes here
+            for (int i = 0; i < nativeMasks.length; i++) {
+                nativeMasks[i] = AudioFormat.convertNativeChannelMaskToOutMask(nativeMasks[i]);
+            }
+            final List<Integer> masks = Arrays.stream(nativeMasks).boxed().toList();
+            return masks;
+        } catch (Exception e) { // just catch Exception in case nativeMasks is null
+            Log.e(TAG, "Error calling getSpatializedChannelMasks", e);
+            return Collections.emptyList();
+        }
+    }
+
     //------------------------------------------------------
     // head tracking
     final RemoteCallbackList<ISpatializerHeadTrackingModeCallback> mHeadTrackingModeCallbacks =
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 97a8854..b365ef7 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -434,21 +434,12 @@
 
         public boolean getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(int userId) {
             if (!mMandatoryBiometricsEnabled.containsKey(userId)) {
-                Slog.d(TAG, "update mb toggle for user " + userId);
                 updateMandatoryBiometricsForAllProfiles(userId);
             }
             if (!mMandatoryBiometricsRequirementsSatisfied.containsKey(userId)) {
-                Slog.d(TAG, "update mb reqs for user " + userId);
                 updateMandatoryBiometricsRequirementsForAllProfiles(userId);
             }
 
-            Slog.d(TAG, mMandatoryBiometricsEnabled.getOrDefault(userId,
-                    DEFAULT_MANDATORY_BIOMETRICS_STATUS)
-                    + " " + mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId,
-                    DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS)
-                    + " " + getEnabledForApps(userId)
-                    + " " + (mFingerprintEnrolledForUser.getOrDefault(userId, false /* default */)
-                    || mFaceEnrolledForUser.getOrDefault(userId, false /* default */)));
             return mMandatoryBiometricsEnabled.getOrDefault(userId,
                     DEFAULT_MANDATORY_BIOMETRICS_STATUS)
                     && mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId,
diff --git a/services/core/java/com/android/server/biometrics/biometrics.aconfig b/services/core/java/com/android/server/biometrics/biometrics.aconfig
index d3da8dd..95ba695 100644
--- a/services/core/java/com/android/server/biometrics/biometrics.aconfig
+++ b/services/core/java/com/android/server/biometrics/biometrics.aconfig
@@ -34,3 +34,10 @@
       purpose: PURPOSE_BUGFIX
   }
 }
+
+flag {
+  name: "frr_dialog_improvement"
+  namespace: "biometrics_framework"
+  description: "This flag controls FRR dialog improvement"
+  bug: "380800403"
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java b/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java
index eed2bdd..958ab8e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java
+++ b/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java
@@ -18,6 +18,8 @@
 
 import android.util.SparseArray;
 
+import java.util.concurrent.ConcurrentHashMap;
+
 /**
  * Tracks biometric performance across sensors and users.
  */
@@ -25,17 +27,12 @@
 
     private static final String TAG = "PerformanceTracker";
     // Keyed by SensorId
-    private static SparseArray<PerformanceTracker> sTrackers;
+    private static final ConcurrentHashMap<Integer, PerformanceTracker> sTrackers =
+            new ConcurrentHashMap<>();
 
     public static PerformanceTracker getInstanceForSensorId(int sensorId) {
-        if (sTrackers == null) {
-            sTrackers = new SparseArray<>();
-        }
-
-        if (!sTrackers.contains(sensorId)) {
-            sTrackers.put(sensorId, new PerformanceTracker());
-        }
-        return sTrackers.get(sensorId);
+        PerformanceTracker tracker = sTrackers.putIfAbsent(sensorId, new PerformanceTracker());
+        return tracker != null ? tracker : sTrackers.get(sensorId);
     }
 
     private static class Info {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 36e4a7e..944e85c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -851,13 +851,8 @@
             for (int i = 0; i < mFaceSensors.size(); i++) {
                 final Sensor sensor = mFaceSensors.valueAt(i);
                 final int sensorId = mFaceSensors.keyAt(i);
-                final PerformanceTracker performanceTracker = PerformanceTracker.getInstanceForSensorId(
-                        sensorId);
-                if (performanceTracker != null) {
-                    performanceTracker.incrementHALDeathCount();
-                } else {
-                    Slog.w(getTag(), "Performance tracker is null. Not counting HAL death.");
-                }
+                PerformanceTracker.getInstanceForSensorId(sensorId)
+                        .incrementHALDeathCount();
                 sensor.onBinderDied();
             }
         });
diff --git a/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java b/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java
index 8e72546..eef2b15 100644
--- a/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java
+++ b/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java
@@ -93,7 +93,8 @@
                     return;
                 }
                 final List<VersionedPackage> pkgList = Collections.singletonList(pkg);
-                PackageWatchdog.getInstance(mContext).onPackageFailure(pkgList,  PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
+                PackageWatchdog.getInstance(mContext).notifyPackageFailure(pkgList,
+                        PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
             });
     }
 
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 448c42b7..805357e 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -1280,7 +1280,7 @@
 
     private boolean shouldApplyDozeScaleFactor() {
         // We don't apply the doze scale factor if we have a designated brightness curve for doze.
-        return (mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()
+        return (mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
                 ? (!mUseNormalBrightnessForDoze && mDisplayPolicy == POLICY_DOZE)
                         || Display.isDozeState(mDisplayState) : Display.isDozeState(mDisplayState))
                 && getMode() != AUTO_BRIGHTNESS_MODE_DOZE;
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index d2c044f..1c1bdad 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -311,6 +311,11 @@
      */
     public FrameRateCategoryRate frameRateCategoryRate;
     /**
+     * All the refresh rates supported for the default display mode.
+     */
+    public float[] supportedRefreshRates = new float[0];
+
+    /**
      * The default mode of the display.
      */
     public int defaultModeId;
@@ -562,7 +567,8 @@
                 || installOrientation != other.installOrientation
                 || !Objects.equals(displayShape, other.displayShape)
                 || hasArrSupport != other.hasArrSupport
-                || !Objects.equals(frameRateCategoryRate, other.frameRateCategoryRate)) {
+                || !Objects.equals(frameRateCategoryRate, other.frameRateCategoryRate)
+                || !Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)) {
             diff |= DIFF_OTHER;
         }
         return diff;
@@ -582,6 +588,7 @@
         renderFrameRate = other.renderFrameRate;
         hasArrSupport = other.hasArrSupport;
         frameRateCategoryRate = other.frameRateCategoryRate;
+        supportedRefreshRates = other.supportedRefreshRates;
         defaultModeId = other.defaultModeId;
         userPreferredModeId = other.userPreferredModeId;
         supportedModes = other.supportedModes;
@@ -628,6 +635,7 @@
         sb.append(", renderFrameRate ").append(renderFrameRate);
         sb.append(", hasArrSupport ").append(hasArrSupport);
         sb.append(", frameRateCategoryRate ").append(frameRateCategoryRate);
+        sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates));
         sb.append(", defaultModeId ").append(defaultModeId);
         sb.append(", userPreferredModeId ").append(userPreferredModeId);
         sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 62fcccf..3871f2a 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server.display;
 
 import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY;
+import static android.Manifest.permission.ADD_MIRROR_DISPLAY;
 import static android.Manifest.permission.ADD_TRUSTED_DISPLAY;
 import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT;
 import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT;
@@ -177,6 +178,7 @@
 import com.android.server.display.layout.Layout;
 import com.android.server.display.mode.DisplayModeDirector;
 import com.android.server.display.notifications.DisplayNotificationManager;
+import com.android.server.display.plugin.PluginManager;
 import com.android.server.display.utils.DebugUtils;
 import com.android.server.display.utils.SensorUtils;
 import com.android.server.input.InputManagerInternal;
@@ -583,6 +585,7 @@
 
     private final DisplayNotificationManager mDisplayNotificationManager;
     private final ExternalDisplayStatsService mExternalDisplayStatsService;
+    private final PluginManager mPluginManager;
 
     // Manages the relative placement of extended displays
     @Nullable
@@ -669,6 +672,7 @@
         } else {
             mDisplayTopologyCoordinator = null;
         }
+        mPluginManager = new PluginManager(mContext, mFlags);
     }
 
     public void setupSchedulerPolicies() {
@@ -739,6 +743,7 @@
             mLogicalDisplayMapper.onBootCompleted();
             mDisplayNotificationManager.onBootCompleted();
             mExternalDisplayPolicy.onBootCompleted();
+            mPluginManager.onBootCompleted();
         }
     }
 
@@ -1673,15 +1678,10 @@
     }
 
     private boolean canCreateMirrorDisplays(IVirtualDevice virtualDevice) {
-        if (virtualDevice == null) {
-            return false;
+        if (android.companion.virtualdevice.flags.Flags.enableLimitedVdmRole()) {
+            return checkCallingPermission(ADD_MIRROR_DISPLAY, "canCreateMirrorDisplays");
         }
-        try {
-            return virtualDevice.canCreateMirrorDisplays();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to query virtual device for permissions", e);
-            return false;
-        }
+        return virtualDevice != null;
     }
 
     private boolean canProjectVideo(IMediaProjection projection) {
@@ -1814,7 +1814,7 @@
             // display.
             if (!canProjectVideo(projection) && !canCreateMirrorDisplays(virtualDevice)
                     && !hasVideoOutputPermission("createVirtualDisplayInternal")) {
-                throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
+                throw new SecurityException("Requires ADD_MIRROR_DISPLAY, CAPTURE_VIDEO_OUTPUT or "
                         + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
                         + "MediaProjection token in order to create a screen sharing virtual "
                         + "display. In order to create a virtual display that does not perform "
@@ -3552,6 +3552,9 @@
         SparseArray<DisplayPowerController> displayPowerControllersLocal = new SparseArray<>();
         int displayPowerControllerCount;
 
+        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
+        ipw.increaseIndent();
+
         synchronized (mSyncRoot) {
             brightnessTrackerLocal = mBrightnessTracker;
 
@@ -3599,9 +3602,6 @@
                 pw.println("  Display SdrBrightness=" + brightnessPair.sdrBrightness);
             }
 
-            IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
-            ipw.increaseIndent();
-
             pw.println();
             pw.println("Display Adapters: size=" + mDisplayAdapters.size());
             pw.println("------------------------");
@@ -3664,6 +3664,8 @@
             pw.println();
             mDisplayTopologyCoordinator.dump(pw);
         }
+        pw.println();
+        mPluginManager.dump(ipw);
 
         pw.println();
         mFlags.dump(pw);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 2948ae4..945365d 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1399,7 +1399,7 @@
         // Use doze brightness if one of following is true:
         // 1. The target `state` isDozeState.
         // 2. Doze power request(POLICY_DOZE) if there's no exception(useNormalBrightnessForDoze).
-        final boolean useDozeBrightness = mFlags.isNormalBrightnessForDozeParameterEnabled()
+        final boolean useDozeBrightness = mFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
                 ? (!mPowerRequest.useNormalBrightnessForDoze && mPowerRequest.policy == POLICY_DOZE)
                         || Display.isDozeState(state) : Display.isDozeState(state);
         DisplayBrightnessState displayBrightnessState =
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index a4bb8c3..0b8f7d5 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -249,6 +249,7 @@
         private int mActiveColorMode;
         private boolean mHasArrSupport;
         private FrameRateCategoryRate mFrameRateCategoryRate;
+        private float[] mSupportedRefreshRates = new float[0];
         private Display.HdrCapabilities mHdrCapabilities;
         private boolean mAllmSupported;
         private boolean mGameContentTypeSupported;
@@ -316,6 +317,7 @@
             changed |= updateGameContentTypeSupport(dynamicInfo.gameContentTypeSupported);
             changed |= updateHasArrSupportLocked(dynamicInfo.hasArrSupport);
             changed |= updateFrameRateCategoryRatesLocked(dynamicInfo.frameRateCategoryRate);
+            changed |= updateSupportedRefreshatesLocked(dynamicInfo.supportedRefreshRates);
 
             if (changed) {
                 mHavePendingChanges = true;
@@ -624,6 +626,20 @@
             return true;
         }
 
+        private boolean updateSupportedRefreshatesLocked(float[] supportedRefreshRates) {
+            if (!getFeatureFlags().enableGetSupportedRefreshRates()) {
+                return false;
+            }
+            if (supportedRefreshRates == null) {
+                return false;
+            }
+            if (Arrays.equals(mSupportedRefreshRates, supportedRefreshRates)) {
+                return false;
+            }
+            mSupportedRefreshRates = supportedRefreshRates;
+            return true;
+        }
+
         private boolean updateAllmSupport(boolean supported) {
             if (mAllmSupported == supported) {
                 return false;
@@ -708,6 +724,7 @@
                 mInfo.hdrCapabilities = mHdrCapabilities;
                 mInfo.hasArrSupport = mHasArrSupport;
                 mInfo.frameRateCategoryRate = mFrameRateCategoryRate;
+                mInfo.supportedRefreshRates = mSupportedRefreshRates;
                 mInfo.appVsyncOffsetNanos = mActiveSfDisplayMode.appVsyncOffsetNanos;
                 mInfo.presentationDeadlineNanos = mActiveSfDisplayMode.presentationDeadlineNanos;
                 mInfo.state = mState;
@@ -1299,6 +1316,7 @@
             pw.println("mDefaultModeId=" + mDefaultModeId);
             pw.println("mUserPreferredModeId=" + mUserPreferredModeId);
             pw.println("mHasArrSupport=" + mHasArrSupport);
+            pw.println("mSupportedRefreshRates=" + Arrays.toString(mSupportedRefreshRates));
             pw.println("mState=" + Display.stateToString(mState));
             pw.println("mCommittedState=" + Display.stateToString(mCommittedState));
             pw.println("mBrightnessState=" + mBrightnessState);
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 7cfdcaf..8546598 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -508,6 +508,8 @@
             mBaseDisplayInfo.renderFrameRate = deviceInfo.renderFrameRate;
             mBaseDisplayInfo.hasArrSupport = deviceInfo.hasArrSupport;
             mBaseDisplayInfo.frameRateCategoryRate = deviceInfo.frameRateCategoryRate;
+            mBaseDisplayInfo.supportedRefreshRates = Arrays.copyOf(
+                    deviceInfo.supportedRefreshRates, deviceInfo.supportedRefreshRates.length);
             mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
             mBaseDisplayInfo.userPreferredModeId = deviceInfo.userPreferredModeId;
             mBaseDisplayInfo.supportedModes = Arrays.copyOf(
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
index a0ad49d..2c6f374 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
@@ -109,6 +109,8 @@
 
     private final int mDisplayId;
 
+    private final Context mContext;
+
     /**
      * The constructor of DozeBrightnessStrategy.
      */
@@ -117,6 +119,7 @@
         if (injector == null) {
             injector = new Injector();
         }
+        mContext = context;
         mDisplayManagerFlags = flags;
         mDisplayId = displayId;
         mDozeBrightnessStrategy = injector.getDozeBrightnessStrategy();
@@ -348,7 +351,7 @@
         // a user can define a different display state(displayPowerRequest.dozeScreenState) too
         // in the request with the Doze policy and user might request an override to force certain
         // brightness.
-        return (!mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()
+        return (!mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
                 || !displayPowerRequest.useNormalBrightnessForDoze)
                 && displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
                 && !mAllowAutoBrightnessWhileDozing
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
index ff73693..94522d1 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
@@ -525,7 +525,7 @@
         }
 
         final boolean shouldUseDozeMode =
-                mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()
+                mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
                         ? (!useNormalBrightnessForDoze && policy == POLICY_DOZE)
                                 || Display.isDozeState(state)
                         : Display.isDozeState(state);
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 1a7d74a..45106f5 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -16,6 +16,7 @@
 
 package com.android.server.display.feature;
 
+import android.content.Context;
 import android.os.Build;
 import android.os.SystemProperties;
 import android.text.TextUtils;
@@ -242,6 +243,11 @@
             Flags::autoBrightnessModeBedtimeWear
     );
 
+    private final FlagState mGetSupportedRefreshRatesFlagState = new FlagState(
+            Flags.FLAG_ENABLE_GET_SUPPORTED_REFRESH_RATES,
+            Flags::enableGetSupportedRefreshRates
+    );
+
     private final FlagState mEnablePluginManagerFlagState = new FlagState(
             Flags.FLAG_ENABLE_PLUGIN_MANAGER,
             Flags::enablePluginManager
@@ -251,6 +257,11 @@
             Flags::displayListenerPerformanceImprovements
     );
 
+    private final FlagState mSubscribeGranularDisplayEvents = new FlagState(
+            Flags.FLAG_SUBSCRIBE_GRANULAR_DISPLAY_EVENTS,
+            Flags::subscribeGranularDisplayEvents
+    );
+
     /**
      * @return {@code true} if 'port' is allowed in display layout configuration file.
      */
@@ -461,8 +472,9 @@
     /**
      * @return Whether the useDozeBrightness parameter should be used
      */
-    public boolean isNormalBrightnessForDozeParameterEnabled() {
-        return mNormalBrightnessForDozeParameter.isEnabled();
+    public boolean isNormalBrightnessForDozeParameterEnabled(Context context) {
+        return mNormalBrightnessForDozeParameter.isEnabled() && context.getResources().getBoolean(
+                com.android.internal.R.bool.config_allowNormalBrightnessForDozePolicy);
     }
 
      /**
@@ -526,6 +538,13 @@
         return mAutoBrightnessModeBedtimeWearFlagState.isEnabled();
     }
 
+    /**
+     * @return {@code true} if supported refresh rate api is enabled.
+     */
+    public boolean enableGetSupportedRefreshRates() {
+        return mGetSupportedRefreshRatesFlagState.isEnabled();
+    }
+
     public boolean isPluginManagerEnabled() {
         return mEnablePluginManagerFlagState.isEnabled();
     }
@@ -538,6 +557,13 @@
     }
 
     /**
+     * @return {@code true} if the flag for subscribing to granular display events is enabled
+     */
+    public boolean isSubscribeGranularDisplayEventsEnabled() {
+        return mSubscribeGranularDisplayEvents.isEnabled();
+    }
+
+    /**
      * dumps all flagstates
      * @param pw printWriter
      */
@@ -588,8 +614,10 @@
         pw.println(" " + mIsUserRefreshRateForExternalDisplayEnabled);
         pw.println(" " + mHasArrSupport);
         pw.println(" " + mAutoBrightnessModeBedtimeWearFlagState);
+        pw.println(" " + mGetSupportedRefreshRatesFlagState);
         pw.println(" " + mEnablePluginManagerFlagState);
         pw.println(" " + mDisplayListenerPerformanceImprovementsFlagState);
+        pw.println(" " + mSubscribeGranularDisplayEvents);
     }
 
     private static class FlagState {
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index e7ea868..3976d01 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -478,3 +478,14 @@
     bug: "378385869"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "subscribe_granular_display_events"
+    namespace: "display_manager"
+    description: "Enable subscription to granular display change events."
+    bug: "379250634"
+    is_fixed_read_only: true
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/services/core/java/com/android/server/display/plugin/Plugin.java b/services/core/java/com/android/server/display/plugin/Plugin.java
new file mode 100644
index 0000000..1bef464
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/Plugin.java
@@ -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.server.display.plugin;
+
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+import java.io.PrintWriter;
+
+/**
+ * Interface that OEMs should implement in order to inject custom code to system process.
+ * Communication between OEM Plugin and Framework is implemented via {@link PluginStorage}.
+ * OEM Plugin pushes values to PluginStorage, that are picked up by
+ * {@link PluginManager.PluginChangeListener}, implemented on Framework side.
+ * Avoid calling heavy operations in constructor - it will be called during boot and will
+ * negatively impact boot time. Use onBootComplete and separate thread for long running operations.
+ */
+@KeepForApi
+public interface Plugin {
+
+    /**
+     * Called when device boot completed
+     */
+    void onBootCompleted();
+
+    /**
+     * Print the object's state and debug information into the given stream.
+     */
+    void dump(PrintWriter pw);
+}
+
diff --git a/services/core/java/com/android/server/display/plugin/PluginManager.java b/services/core/java/com/android/server/display/plugin/PluginManager.java
new file mode 100644
index 0000000..d409997
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/PluginManager.java
@@ -0,0 +1,141 @@
+/*
+ * 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.display.plugin;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.SystemServerClassLoaderFactory;
+import com.android.server.display.feature.DisplayManagerFlags;
+
+import dalvik.system.PathClassLoader;
+
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Responsible for loading Plugins. Plugins and PluginSupplier are loaded from
+ * standalone system jar.
+ * Plugin manager will look for PROVIDER_IMPL_CLASS in configured jar.
+ * After device booted, PluginManager will delegate this call to each Plugin
+ */
+public class PluginManager {
+    private static final String PROVIDER_IMPL_CLASS =
+            "com.android.server.display.plugin.PluginsProviderImpl";
+    private static final String TAG = "PluginManager";
+
+    private final DisplayManagerFlags mFlags;
+    private final PluginStorage mPluginStorage;
+    private final List<Plugin> mPlugins;
+
+    public PluginManager(Context context, DisplayManagerFlags flags) {
+        this(context, flags, new Injector());
+    }
+
+    @VisibleForTesting
+    PluginManager(Context context, DisplayManagerFlags flags, Injector injector) {
+        mFlags = flags;
+        mPluginStorage = injector.getPluginStorage();
+        if (mFlags.isPluginManagerEnabled()) {
+            mPlugins = Collections.unmodifiableList(injector.loadPlugins(context, mPluginStorage));
+            Slog.d(TAG, "loaded Plugins:" + mPlugins);
+        } else {
+            mPlugins = List.of();
+            Slog.d(TAG, "PluginManager disabled");
+        }
+    }
+
+    /**
+     * Forwards boot completed event to Plugins
+     */
+    public void onBootCompleted() {
+        mPlugins.forEach(Plugin::onBootCompleted);
+    }
+
+    /**
+     * Adds change listener for particular plugin type
+     */
+    public <T> void subscribe(PluginType<T> type, PluginChangeListener<T> listener) {
+        mPluginStorage.addListener(type, listener);
+    }
+
+    /**
+     * Removes change listener
+     */
+    public <T> void unsubscribe(PluginType<T> type, PluginChangeListener<T> listener) {
+        mPluginStorage.removeListener(type, listener);
+    }
+
+    /**
+     * Print the object's state and debug information into the given stream.
+     */
+    public void dump(PrintWriter pw) {
+        pw.println("PluginManager:");
+        mPluginStorage.dump(pw);
+        for (Plugin plugin : mPlugins) {
+            plugin.dump(pw);
+        }
+    }
+
+    /**
+     * Listens for changes in PluginStorage for a particular type
+     * @param <T> plugin value type
+     */
+    public interface PluginChangeListener<T> {
+        /**
+         * Called when Plugin value changed
+         */
+        void onChanged(@Nullable T value);
+    }
+
+    static class Injector {
+        PluginStorage getPluginStorage() {
+            return new PluginStorage();
+        }
+
+        List<Plugin> loadPlugins(Context context, PluginStorage storage) {
+            String providerJarPath = context
+                    .getString(com.android.internal.R.string.config_pluginsProviderJarPath);
+            Slog.d(TAG, "loading plugins from:" + providerJarPath);
+            if (TextUtils.isEmpty(providerJarPath)) {
+                return List.of();
+            }
+            try {
+                PathClassLoader pathClassLoader =
+                        SystemServerClassLoaderFactory.getOrCreateClassLoader(
+                                providerJarPath, getClass().getClassLoader(), false);
+                @SuppressWarnings("PrivateApi")
+                Class<? extends PluginsProvider> cp = pathClassLoader.loadClass(PROVIDER_IMPL_CLASS)
+                        .asSubclass(PluginsProvider.class);
+                PluginsProvider provider = cp.getDeclaredConstructor().newInstance();
+                return provider.getPlugins(context, storage);
+            } catch (ClassNotFoundException e) {
+                Slog.e(TAG, "loading failed: " + PROVIDER_IMPL_CLASS + " is not found in"
+                        + providerJarPath, e);
+            } catch (InvocationTargetException | InstantiationException | IllegalAccessException
+                     | NoSuchMethodException e) {
+                Slog.e(TAG, "Class instantiation failed", e);
+            }
+            return List.of();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/display/plugin/PluginStorage.java b/services/core/java/com/android/server/display/plugin/PluginStorage.java
new file mode 100644
index 0000000..2bcea77
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/PluginStorage.java
@@ -0,0 +1,134 @@
+/*
+ * 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.display.plugin;
+
+import android.annotation.Nullable;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Stores values pushed by Plugins and forwards them to corresponding listener.
+ */
+public class PluginStorage {
+    private static final String TAG = "PluginStorage";
+
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private final Map<PluginType<?>, Object> mValues = new HashMap<>();
+    @GuardedBy("mLock")
+    private final Map<PluginType<?>, ListenersContainer<?>> mListeners = new HashMap<>();
+
+    /**
+     * Updates value in storage and forwards it to corresponding listeners.
+     * Should be called by OEM Plugin implementation in order to provide communicate with Framework
+     */
+    @KeepForApi
+    public <T> void updateValue(PluginType<T> type, @Nullable T value) {
+        Slog.d(TAG, "updateValue, type=" + type.mName + "; value=" + value);
+        Set<PluginManager.PluginChangeListener<T>> localListeners;
+        synchronized (mLock) {
+            mValues.put(type, value);
+            ListenersContainer<T> container = getListenersContainerForTypeLocked(type);
+            localListeners = new LinkedHashSet<>(container.mListeners);
+        }
+        Slog.d(TAG, "updateValue, notifying listeners=" + localListeners);
+        localListeners.forEach(l -> l.onChanged(value));
+    }
+
+    /**
+     * Adds listener for PluginType. If storage already has value for this type, listener will
+     * be notified immediately.
+     */
+    <T> void addListener(PluginType<T> type, PluginManager.PluginChangeListener<T> listener) {
+        T value = null;
+        synchronized (mLock) {
+            ListenersContainer<T> container = getListenersContainerForTypeLocked(type);
+            if (container.mListeners.add(listener)) {
+                value = getValueForTypeLocked(type);
+            }
+        }
+        if (value != null) {
+            listener.onChanged(value);
+        }
+    }
+
+    /**
+     * Removes listener
+     */
+    <T> void removeListener(PluginType<T> type, PluginManager.PluginChangeListener<T> listener) {
+        synchronized (mLock) {
+            ListenersContainer<T> container = getListenersContainerForTypeLocked(type);
+            container.mListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Print the object's state and debug information into the given stream.
+     */
+    void dump(PrintWriter pw) {
+        Map<PluginType<?>, Object> localValues;
+        @SuppressWarnings("rawtypes")
+        Map<PluginType, Set> localListeners = new HashMap<>();
+        synchronized (mLock) {
+            localValues = new HashMap<>(mValues);
+            mListeners.forEach((type, container) -> localListeners.put(type, container.mListeners));
+        }
+        pw.println("PluginStorage:");
+        pw.println("values=" + localValues);
+        pw.println("listeners=" + localListeners);
+    }
+
+    @GuardedBy("mLock")
+    @SuppressWarnings("unchecked")
+    private <T> T getValueForTypeLocked(PluginType<T> type) {
+        Object value = mValues.get(type);
+        if (value == null) {
+            return null;
+        } else if (type.mType == value.getClass()) {
+            return (T) value;
+        } else {
+            Slog.d(TAG, "getValueForType: unexpected value type=" + value.getClass().getName()
+                    + ", expected=" + type.mType.getName());
+            return null;
+        }
+    }
+
+    @GuardedBy("mLock")
+    @SuppressWarnings("unchecked")
+    private <T> ListenersContainer<T> getListenersContainerForTypeLocked(PluginType<T> type) {
+        ListenersContainer<?> container = mListeners.get(type);
+        if (container == null) {
+            ListenersContainer<T> lc = new ListenersContainer<>();
+            mListeners.put(type, lc);
+            return lc;
+        } else {
+            return (ListenersContainer<T>) container;
+        }
+    }
+
+    private static final class ListenersContainer<T> {
+        private final Set<PluginManager.PluginChangeListener<T>> mListeners = new LinkedHashSet<>();
+    }
+}
diff --git a/services/core/java/com/android/server/display/plugin/PluginType.java b/services/core/java/com/android/server/display/plugin/PluginType.java
new file mode 100644
index 0000000..fb60833
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/PluginType.java
@@ -0,0 +1,48 @@
+/*
+ * 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.display.plugin;
+
+import com.android.internal.annotations.Keep;
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Represent customisation entry point to Framework. OEM and Framework team should define
+ * new PluginTypes together, after that, Framework team can integrate listener and OEM team
+ * create Plugin implementation
+ *
+ * @param <T> type of plugin value
+ */
+@Keep
+public class PluginType<T> {
+
+    final Class<T> mType;
+    final String mName;
+
+    @VisibleForTesting
+    PluginType(Class<T> type, String name) {
+        mType = type;
+        mName = name;
+    }
+
+    @Override
+    public String toString() {
+        return "PluginType{"
+                + "mType=" + mType
+                + ", mName=" + mName
+                + '}';
+    }
+}
diff --git a/services/core/java/com/android/server/display/plugin/PluginsProvider.java b/services/core/java/com/android/server/display/plugin/PluginsProvider.java
new file mode 100644
index 0000000..9ad85f6
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/PluginsProvider.java
@@ -0,0 +1,36 @@
+/*
+ * 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.display.plugin;
+
+import android.annotation.NonNull;
+import android.content.Context;
+
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+import java.util.List;
+
+/**
+ * Interface that OEMs should implement in order to supply Plugins to PluginManager
+ */
+@KeepForApi
+public interface PluginsProvider {
+    /**
+     * Provides list of Plugins to PluginManager
+     */
+    @NonNull
+    List<Plugin> getPlugins(Context context, PluginStorage storage);
+}
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 0e7d2b6..a06f9ef 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -524,6 +524,13 @@
     static final String PROPERTY_DISABLE_CEC_ON_STANDBY_IN_LOW_ENERGY_MODE =
             "persist.sys.hdmi.property_disable_cec_on_standby_in_low_energy_mode";
 
+    /**
+     * Property that checks if CEC was manually enabled by the user in offline mode. With the help
+     * of this property we avoid turning off CEC when the device goes to sleep and if the device
+     * is in low energy mode.
+     */
+    static final String PROPERTY_USER_ACTION_KEEP_CEC_ENABLED_IN_OFFLINE_MODE =
+            "persist.sys.hdmi.property_user_action_keep_cec_enabled_in_offline_mode";
     static final int RECORDING_TYPE_DIGITAL_RF = 1;
     static final int RECORDING_TYPE_ANALOGUE_RF = 2;
     static final int RECORDING_TYPE_EXTERNAL_PHYSICAL_ADDRESS = 3;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java b/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java
index 53c0217..2e66fbc 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java
@@ -16,6 +16,8 @@
 
 package com.android.server.hdmi;
 
+import static android.media.tv.flags.Flags.hdmiControlCollectPhysicalAddress;
+
 import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_ARC_PENDING;
 import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_EARC_CONNECTED;
 import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_EARC_PENDING;
@@ -35,6 +37,8 @@
     @VisibleForTesting
     protected static final int FEATURE_ABORT_OPCODE_UNKNOWN = 0x100;
     private static final int ERROR_CODE_UNKNOWN = -1;
+    @VisibleForTesting
+    protected static final int PHYSICAL_ADDRESS_INVALID = 0xFFFF;
 
     /**
      * Writes a HdmiCecMessageReported atom representing an HDMI CEC message.
@@ -95,6 +99,11 @@
                 return createUserControlPressedSpecialArgs(message);
             case Constants.MESSAGE_FEATURE_ABORT:
                 return createFeatureAbortSpecialArgs(message);
+            case Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS:
+                if (hdmiControlCollectPhysicalAddress()) {
+                    return createReportPhysicalAddressSpecialArgs(message);
+                }
+                return new MessageReportedSpecialArgs();
             default:
                 return new MessageReportedSpecialArgs();
         }
@@ -140,6 +149,23 @@
     }
 
     /**
+     * Constructs the special arguments for a <Report Physical Address> message.
+     *
+     * @param message The HDMI CEC message to log
+     */
+    private MessageReportedSpecialArgs createReportPhysicalAddressSpecialArgs(
+            HdmiCecMessage message) {
+        MessageReportedSpecialArgs specialArgs = new MessageReportedSpecialArgs();
+
+        if (message.getParams().length > 1) {
+            int physicalAddress = (message.getParams()[0] << 8) | message.getParams()[1];
+            specialArgs.mPhysicalAddress = physicalAddress;
+        }
+
+        return specialArgs;
+    }
+
+    /**
      * Writes a HdmiCecMessageReported atom.
      *
      * @param genericArgs Generic arguments; shared by all HdmiCecMessageReported atoms
@@ -156,7 +182,8 @@
                 genericArgs.mSendMessageResult,
                 specialArgs.mUserControlPressedCommand,
                 specialArgs.mFeatureAbortOpcode,
-                specialArgs.mFeatureAbortReason);
+                specialArgs.mFeatureAbortReason,
+                specialArgs.mPhysicalAddress);
     }
 
     /**
@@ -166,7 +193,7 @@
     protected void writeHdmiCecMessageReportedAtom(int uid, int direction,
             int initiatorLogicalAddress, int destinationLogicalAddress, int opcode,
             int sendMessageResult, int userControlPressedCommand, int featureAbortOpcode,
-            int featureAbortReason) {
+            int featureAbortReason, int physicalAddress) {
         FrameworkStatsLog.write(
                 FrameworkStatsLog.HDMI_CEC_MESSAGE_REPORTED,
                 uid,
@@ -177,7 +204,8 @@
                 sendMessageResult,
                 userControlPressedCommand,
                 featureAbortOpcode,
-                featureAbortReason);
+                featureAbortReason,
+                physicalAddress);
     }
 
     /**
@@ -284,5 +312,6 @@
         int mUserControlPressedCommand = HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN;
         int mFeatureAbortOpcode = FEATURE_ABORT_OPCODE_UNKNOWN;
         int mFeatureAbortReason = HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN;
+        int mPhysicalAddress = PHYSICAL_ADDRESS_INVALID;
     }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 0c5069f..6e98bff 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -4027,7 +4027,8 @@
                     return;
                 }
                 if (isTvDevice() && getDisableCecOnStandbyByLowEnergyMode()
-                        && mPowerManager.isLowPowerStandbyEnabled()) {
+                        && mPowerManager.isLowPowerStandbyEnabled()
+                        && !userEnabledCecInOfflineMode()) {
                     Slog.w(TAG, "Disable CEC on standby due to low power energy mode.");
                     setWasCecDisabledOnStandbyByLowEnergyMode(true);
                     getHdmiCecConfig().setIntValue(
@@ -5225,4 +5226,14 @@
                 Constants.PROPERTY_WAS_CEC_DISABLED_ON_STANDBY_BY_LOW_ENERGY_MODE,
                 String.valueOf(value));
     }
+
+    /**
+     * Reads the property that checks if CEC was enabled by the user while in offline mode such that
+     * it won't be disabled when going to sleep by low energy mode.
+     */
+    @VisibleForTesting
+    protected boolean userEnabledCecInOfflineMode() {
+        return SystemProperties.getBoolean(
+                Constants.PROPERTY_USER_ACTION_KEEP_CEC_ENABLED_IN_OFFLINE_MODE, false);
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java b/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java
index b0e9398..f9a1ceb 100644
--- a/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java
+++ b/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java
@@ -25,8 +25,8 @@
  * Feature action that sends <Request Active Source> message and waits for <Active Source>.
  *
  * For TV panels, this action has a delay before sending <Request Active Source>. This is because it
- * should wait for a possible request from LauncherX and can be cancelled if an <Active Source>
- * message was received or the TV switched to another input.
+ * should wait for a possible request from LauncherX or TIF (TV Input Framework) and can be
+ * cancelled if an <Active Source> message was received or the TV switched to another input.
  */
 public class RequestActiveSourceAction extends HdmiCecFeatureAction {
     private static final String TAG = "RequestActiveSourceAction";
@@ -40,9 +40,9 @@
     // Number of retries <Request Active Source> is sent if no device answers this message.
     private static final int MAX_SEND_RETRY_COUNT = 1;
 
-    // Timeout to wait for the LauncherX API call to be completed.
+    // Timeout to wait for LauncherX or TIF to call the CEC API.
     @VisibleForTesting
-    protected static final int TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS = 10000;
+    protected static final int TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS = 15000;
 
     private int mSendRetryCount = 0;
 
@@ -67,7 +67,7 @@
         // We wait for default timeout to allow the message triggered by the LauncherX API call to
         // be sent by the TV and another default timeout in case the message has to be answered
         // (e.g. TV sent a <Set Stream Path> or <Routing Change>).
-        addTimer(mState, TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+        addTimer(mState, TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
         return true;
     }
 
diff --git a/services/core/java/com/android/server/input/AppLaunchShortcutManager.java b/services/core/java/com/android/server/input/AppLaunchShortcutManager.java
index f3820e5..8c028bc 100644
--- a/services/core/java/com/android/server/input/AppLaunchShortcutManager.java
+++ b/services/core/java/com/android/server/input/AppLaunchShortcutManager.java
@@ -210,16 +210,16 @@
 
     /**
      * Handle the shortcut to {@link IShortcutService}
-     * @param keyCode The key code of the event.
-     * @param metaState The meta key modifier state.
-     * @return True if invoked the shortcut, otherwise false.
+     * @return true if invoked the shortcut, otherwise false.
      */
-    private boolean handleShortcutService(int keyCode, int metaState) {
-        final long shortcutCodeMeta = metaState & SHORTCUT_CODE_META_MASK;
+    public boolean handleShortcutService(KeyEvent event) {
+        // TODO(b/358569822): Ideally shortcut service custom shortcuts should be either
+        //  migrated to bookmarks or customizable shortcut APIs.
+        final long shortcutCodeMeta = event.getMetaState() & SHORTCUT_CODE_META_MASK;
         if (shortcutCodeMeta == 0) {
             return false;
         }
-        long shortcutCode = keyCode | (shortcutCodeMeta << Integer.SIZE);
+        long shortcutCode = event.getKeyCode() | (shortcutCodeMeta << Integer.SIZE);
         IShortcutService shortcutService = mShortcutKeyServices.get(shortcutCode);
         if (shortcutService != null) {
             try {
@@ -292,7 +292,6 @@
             return InterceptKeyResult.DO_NOTHING;
         }
 
-        final int metaState = event.getModifiers();
         final int keyCode = event.getKeyCode();
         if (keyCode == KeyEvent.KEYCODE_SEARCH) {
             if (event.getAction() == KeyEvent.ACTION_DOWN) {
@@ -313,15 +312,7 @@
         }
 
         // Intercept shortcuts defined in bookmarks or through application launch keycodes
-        AppLaunchData appLaunchData = interceptShortcut(event);
-
-        // TODO(b/358569822): Ideally shortcut service custom shortcuts should be either
-        //  migrated to bookmarks or customizable shortcut APIs.
-        if (appLaunchData == null && handleShortcutService(keyCode, metaState)) {
-            return InterceptKeyResult.CONSUME_KEY;
-        }
-
-        return new InterceptKeyResult(/* consumed =*/ false, appLaunchData);
+        return new InterceptKeyResult(/* consumed =*/ false, interceptShortcut(event));
     }
 
     /**
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e5b077d..1adf1c9 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -19,6 +19,7 @@
 import static android.Manifest.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW;
 import static android.content.PermissionChecker.PERMISSION_GRANTED;
 import static android.content.PermissionChecker.PID_UNKNOWN;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
 import static android.provider.DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT;
 import static android.view.KeyEvent.KEYCODE_UNKNOWN;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
@@ -136,6 +137,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.DisplayThread;
 import com.android.server.LocalServices;
+import com.android.server.SystemService;
 import com.android.server.Watchdog;
 import com.android.server.input.InputManagerInternal.LidSwitchCallback;
 import com.android.server.input.debug.FocusEventDebugView;
@@ -3036,6 +3038,14 @@
         mNative.resetLockedModifierState();
     }
 
+    private void onUserSwitching(@NonNull SystemService.TargetUser from,
+            @NonNull SystemService.TargetUser to) {
+        if (DEBUG) {
+            Slog.d(TAG, "onUserSwitching from=" + from + " to=" + to);
+        }
+        mHandler.obtainMessage(MSG_CURRENT_USER_CHANGED, to.getUserIdentifier()).sendToTarget();
+    }
+
     private void handleCurrentUserChanged(@UserIdInt int userId) {
         mCurrentUserId = userId;
         mKeyGestureController.setCurrentUserId(userId);
@@ -3396,6 +3406,42 @@
         }
     }
 
+    /**
+     * {@link SystemService} used to publish and manage the lifecycle of {@link InputManagerService}
+     */
+    public static final class Lifecycle extends SystemService {
+
+        private final InputManagerService mService;
+
+        public Lifecycle(@NonNull Context context) {
+            super(context);
+            mService = new InputManagerService(context);
+        }
+
+        @Override
+        public void onStart() {
+            publishBinderService(Context.INPUT_SERVICE, mService,
+                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            // Called on ActivityManager thread.
+            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+                mService.systemRunning();
+            }
+        }
+
+        @Override
+        public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+            mService.onUserSwitching(from, to);
+        }
+
+        public InputManagerService getService() {
+            return mService;
+        }
+    }
+
     private final class LocalService extends InputManagerInternal {
         @Override
         public void setDisplayViewports(List<DisplayViewport> viewports) {
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index 420db90..3b2305c 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -117,7 +117,10 @@
                 Map.entry(Settings.System.getUriFor(Settings.System.POINTER_STROKE_STYLE),
                         (reason) -> updatePointerStrokeStyleFromSettings()),
                 Map.entry(Settings.System.getUriFor(Settings.System.POINTER_SCALE),
-                        (reason) -> updatePointerScaleFromSettings()));
+                        (reason) -> updatePointerScaleFromSettings()),
+                Map.entry(Settings.System.getUriFor(
+                                Settings.System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION),
+                        (reason) -> updateTouchpadThreeFingerTapShortcutEnabled()));
     }
 
     /**
@@ -143,10 +146,6 @@
             observer.accept("just booted");
         }
 
-        // TODO(b/365063048): add an entry to mObservers that calls this instead, once we have a
-        //   setting that can be observed.
-        updateTouchpadThreeFingerTapShortcutEnabled();
-
         configureUserActivityPokeInterval();
     }
 
diff --git a/services/core/java/com/android/server/input/InputShellCommand.java b/services/core/java/com/android/server/input/InputShellCommand.java
index 9833016..5bc08a0 100644
--- a/services/core/java/com/android/server/input/InputShellCommand.java
+++ b/services/core/java/com/android/server/input/InputShellCommand.java
@@ -475,6 +475,7 @@
                 }
             }
         }
+        event = KeyEvent.changeTimeRepeat(event, SystemClock.uptimeMillis(), 0);
         injectKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP), async);
     }
 
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index bb0b190..55d2de2 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -793,6 +793,11 @@
                 return true;
         }
 
+        // Handle shortcuts through shortcut services
+        if (mAppLaunchShortcutManager.handleShortcutService(event)) {
+            return true;
+        }
+
         // Handle custom shortcuts
         if (firstDown) {
             InputGestureData customGesture;
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index d132449..da20891 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -19,13 +19,19 @@
 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
 
 import android.annotation.NonNull;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.InputConfig;
 import android.os.Process;
+import android.util.Slog;
 import android.view.InputApplicationHandle;
 import android.view.InputChannel;
 import android.view.InputWindowHandle;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
+import android.view.WindowMetrics;
+import android.view.inputmethod.Flags;
 
 import com.android.server.input.InputManagerService;
 
@@ -39,8 +45,8 @@
     private final SurfaceControl mInputSurface;
     private boolean mIsIntercepting;
 
-    HandwritingEventReceiverSurface(String name, int displayId, @NonNull SurfaceControl sc,
-            @NonNull InputChannel inputChannel) {
+    HandwritingEventReceiverSurface(Context context, String name, int displayId,
+            @NonNull SurfaceControl sc, @NonNull InputChannel inputChannel) {
         mClientChannel = inputChannel;
         mInputSurface = sc;
 
@@ -59,15 +65,31 @@
                         | InputConfig.SPY
                         | InputConfig.INTERCEPTS_STYLUS;
 
-        // Configure the surface to receive stylus events across the entire display.
-        mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
+        Rect bounds = null;
+        if (Flags.adaptiveHandwritingBounds()) {
+            mWindowHandle.setTouchableRegionCrop(mInputSurface);
+            // Default touchable area to getMaximumWindowMetrics()
+            WindowMetrics windowMetrics =  context.getSystemService(WindowManager.class)
+                    .getMaximumWindowMetrics();
+            bounds = windowMetrics.getBounds();
+            if (DEBUG) Slog.d(TAG, "initial handwriting touchable bounds: " + bounds);
+            mWindowHandle.setTouchableRegion(windowMetrics.getBounds());
+        } else {
+            // Configure the surface to receive stylus events across the entire display.
+            mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
+        }
 
         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
         t.setInputWindowInfo(mInputSurface, mWindowHandle);
         t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_HANDWRITING_SURFACE);
         t.setPosition(mInputSurface, 0, 0);
-        t.setCrop(mInputSurface, null /* crop to parent surface */);
+        if (Flags.adaptiveHandwritingBounds()) {
+            // crop to parent surface if null, else bounds.
+            t.setCrop(mInputSurface, bounds);
+        } else {
+            t.setCrop(mInputSurface, null /* crop to parent surface */);
+        }
         t.show(mInputSurface);
         t.apply();
 
@@ -79,12 +101,23 @@
         mWindowHandle.ownerUid = imeUid;
         mWindowHandle.inputConfig &= ~InputConfig.SPY;
 
+        if (Flags.adaptiveHandwritingBounds()) {
+            // watch outside touch to finish handwriting.
+            mWindowHandle.inputConfig |= InputConfig.WATCH_OUTSIDE_TOUCH;
+        }
         new SurfaceControl.Transaction()
                 .setInputWindowInfo(mInputSurface, mWindowHandle)
                 .apply();
         mIsIntercepting = true;
     }
 
+    void setTouchableRegion(Region touchableRegion) {
+        mWindowHandle.touchableRegion.set(touchableRegion);
+        new SurfaceControl.Transaction()
+                .setInputWindowInfo(mInputSurface, mWindowHandle)
+                .apply();
+    }
+
     void setNotTouchable(boolean notTouchable) {
         if (notTouchable) {
             mWindowHandle.inputConfig |= InputConfig.NOT_TOUCHABLE;
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
index c19cb03..45d7d04 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
@@ -27,6 +27,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManagerInternal;
+import android.graphics.Region;
 import android.hardware.input.InputManager;
 import android.hardware.input.InputManagerGlobal;
 import android.os.Handler;
@@ -139,7 +140,7 @@
         }
 
         mHandwritingSurface = new HandwritingEventReceiverSurface(
-                name, displayId, surface, channel);
+                mContext, name, displayId, surface, channel);
 
         // Use a dup of the input channel so that event processing can be paused by disposing the
         // event receiver without causing a fd hangup.
@@ -163,6 +164,13 @@
         mHandwritingSurface.setNotTouchable(notTouchable);
     }
 
+    void setHandwritingTouchableRegion(Region region) {
+        if (!getCurrentRequestId().isPresent()) {
+            return;
+        }
+        mHandwritingSurface.setTouchableRegion(region);
+    }
+
     boolean isStylusGestureOngoing() {
         if (mRecordingGestureAfterStylusUp && !mHandwritingBuffer.isEmpty()) {
             // If it is less than AFTER_STYLUS_UP_ALLOW_PERIOD_MS after the stylus up event, return
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index b7af9a4..02dd884 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -84,6 +84,7 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
+import android.graphics.Region;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.input.InputManager;
 import android.inputmethodservice.InputMethodService;
@@ -6888,6 +6889,14 @@
 
         @BinderThread
         @Override
+        public void setHandwritingTouchableRegion(Region region) {
+            synchronized (ImfLock.class) {
+                mImms.mHwController.setHandwritingTouchableRegion(region);
+            }
+        }
+
+        @BinderThread
+        @Override
         public void createInputContentUriToken(Uri contentUri, String packageName,
                 AndroidFuture future /* T=IBinder */) {
             @SuppressWarnings("unchecked") final AndroidFuture<IBinder> typedFuture = future;
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 7c9d9c5..d177d0e 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -34,6 +34,7 @@
 import android.hardware.contexthub.HubEndpointInfo;
 import android.hardware.contexthub.IContextHubEndpoint;
 import android.hardware.contexthub.IContextHubEndpointCallback;
+import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback;
 import android.hardware.contexthub.MessageDeliveryStatus;
 import android.hardware.location.ContextHubInfo;
 import android.hardware.location.ContextHubMessage;
@@ -325,7 +326,7 @@
             return;
         }
 
-        if (Flags.offloadApi()) {
+        if (Flags.offloadApi() && Flags.offloadImplementation()) {
             HubInfoRegistry registry;
             try {
                 registry = new HubInfoRegistry(mContextHubWrapper);
@@ -527,8 +528,8 @@
         try {
             mContextHubWrapper.registerEndpointCallback(
                     new ContextHubHalEndpointCallback(mHubInfoRegistry));
-        } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException while registering IEndpointCallback", e);
+        } catch (RemoteException | UnsupportedOperationException e) {
+            Log.e(TAG, "Exception while registering IEndpointCallback", e);
         }
     }
 
@@ -793,6 +794,31 @@
         return null;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+    @Override
+    public void registerEndpointDiscoveryCallbackId(
+            long endpointId, IContextHubEndpointDiscoveryCallback callback) throws RemoteException {
+        super.registerEndpointDiscoveryCallbackId_enforcePermission();
+        // TODO(b/375487784): Implement this
+    }
+
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+    @Override
+    public void registerEndpointDiscoveryCallbackDescriptor(
+            String serviceDescriptor, IContextHubEndpointDiscoveryCallback callback)
+            throws RemoteException {
+        super.registerEndpointDiscoveryCallbackDescriptor_enforcePermission();
+        // TODO(b/375487784): Implement this
+    }
+
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+    @Override
+    public void unregisterEndpointDiscoveryCallback(IContextHubEndpointDiscoveryCallback callback)
+            throws RemoteException {
+        super.unregisterEndpointDiscoveryCallback_enforcePermission();
+        // TODO(b/375487784): Implement this
+    }
+
     /**
      * Creates an internal load transaction callback to be used for old API clients
      *
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 27bc1cf..e886f3b 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -2544,8 +2544,11 @@
             mServiceRef = new WeakReference<>(service);
             mUserRecord = userRecord;
             mSystemProvider =
-                    new SystemMediaRoute2Provider(
-                            service.mContext, UserHandle.of(userRecord.mUserId), looper);
+                    Flags.enableMirroringInMediaRouter2()
+                            ? new SystemMediaRoute2Provider2(
+                                    service.mContext, UserHandle.of(userRecord.mUserId), looper)
+                            : new SystemMediaRoute2Provider(
+                                    service.mContext, UserHandle.of(userRecord.mUserId), looper);
             mRouteProviders.add(mSystemProvider);
             mWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
                     this, mUserRecord.mUserId);
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
new file mode 100644
index 0000000..a86e818
--- /dev/null
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.content.Context;
+import android.media.MediaRoute2ProviderService;
+import android.os.Looper;
+import android.os.UserHandle;
+
+/**
+ * Extends {@link SystemMediaRoute2Provider} by adding system routes provided by {@link
+ * MediaRoute2ProviderService provider services}.
+ *
+ * <p>System routes are those which can handle the system audio and/or video.
+ */
+/* package */ class SystemMediaRoute2Provider2 extends SystemMediaRoute2Provider {
+    SystemMediaRoute2Provider2(Context context, UserHandle user, Looper looper) {
+        super(context, user, looper);
+    }
+}
diff --git a/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java b/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java
index 6c74cba..05fe781 100644
--- a/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java
+++ b/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java
@@ -30,7 +30,8 @@
             int hostUid,
             int targetUid,
             int timeSinceLastActive,
-            int creationSource) {
+            int creationSource,
+            int stopSource) {
         FrameworkStatsLog.write(
                 code,
                 sessionId,
@@ -39,7 +40,8 @@
                 hostUid,
                 targetUid,
                 timeSinceLastActive,
-                creationSource);
+                creationSource,
+                stopSource);
     }
 
     /** Wrapper around {@link FrameworkStatsLog#write} for MediaProjectionTargetChanged atom. */
@@ -49,13 +51,23 @@
             int targetType,
             int hostUid,
             int targetUid,
-            int windowingMode) {
+            int windowingMode,
+            int width,
+            int height,
+            int centerX,
+            int centerY,
+            int targetChangeType) {
         FrameworkStatsLog.write(
                 code,
                 sessionId,
                 targetType,
                 hostUid,
                 targetUid,
-                windowingMode);
+                windowingMode,
+                width,
+                height,
+                centerX,
+                centerY,
+                targetChangeType);
     }
 }
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index df5ecf8..c428f39 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -51,6 +51,7 @@
 import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ServiceInfo;
+import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
 import android.media.MediaRouter;
 import android.media.projection.IMediaProjection;
@@ -60,6 +61,7 @@
 import android.media.projection.MediaProjectionInfo;
 import android.media.projection.MediaProjectionManager;
 import android.media.projection.ReviewGrantedConsentResult;
+import android.media.projection.StopReason;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Handler;
@@ -178,7 +180,7 @@
             if (!mMediaProjectionStopController.isExemptFromStopping(mProjectionGrant, reason)) {
                 Slog.d(TAG, "Content Recording: Stopping MediaProjection due to "
                         + MediaProjectionStopController.stopReasonToString(reason));
-                mProjectionGrant.stop();
+                mProjectionGrant.stop(StopReason.STOP_DEVICE_LOCKED);
             }
         }
     }
@@ -257,7 +259,7 @@
         synchronized (mLock) {
             if (mProjectionGrant != null) {
                 Slog.d(TAG, "Content Recording: Stopped MediaProjection due to user switching");
-                mProjectionGrant.stop();
+                mProjectionGrant.stop(StopReason.STOP_USER_SWITCH);
             }
         }
     }
@@ -295,7 +297,7 @@
             Slog.d(TAG,
                     "Content Recording: Stopped MediaProjection due to foreground service change");
             if (mProjectionGrant != null) {
-                mProjectionGrant.stop();
+                mProjectionGrant.stop(StopReason.STOP_FOREGROUND_SERVICE_CHANGE);
             }
         }
     }
@@ -304,7 +306,7 @@
         if (mProjectionGrant != null) {
             Slog.d(TAG, "Content Recording: Stopped MediaProjection to start new "
                     + "incoming projection");
-            mProjectionGrant.stop();
+            mProjectionGrant.stop(StopReason.STOP_NEW_PROJECTION);
         }
         if (mMediaRouteInfo != null) {
             mMediaRouter.getFallbackRoute().select();
@@ -314,7 +316,10 @@
         dispatchStart(projection);
     }
 
-    private void stopProjectionLocked(final MediaProjection projection) {
+    private void stopProjectionLocked(
+            final MediaProjection projection,
+            @StopReason int stopReason
+    ) {
         Slog.d(TAG, "Content Recording: Stopped active MediaProjection and "
                 + "dispatching stop to callbacks");
         ContentRecordingSession session = projection.mSession;
@@ -322,7 +327,7 @@
                 session != null
                         ? session.getTargetUid()
                         : ContentRecordingSession.TARGET_UID_UNKNOWN;
-        mMediaProjectionMetricsLogger.logStopped(projection.uid, targetUid);
+        mMediaProjectionMetricsLogger.logStopped(projection.uid, targetUid, stopReason);
         mProjectionToken = null;
         mProjectionGrant = null;
         dispatchStop(projection);
@@ -403,7 +408,7 @@
                             + "ContentRecordingSession - id= "
                             + mProjectionGrant.getVirtualDisplayId() + "type=" + projectionType);
 
-                    mProjectionGrant.stop();
+                    mProjectionGrant.stop(StopReason.STOP_ERROR);
                 }
                 return false;
             }
@@ -517,6 +522,18 @@
         }
     }
 
+    @VisibleForTesting
+    void notifyCaptureBoundsChanged(int contentToRecord, int targetUid, Rect captureBounds) {
+        synchronized (mLock) {
+            if (mProjectionGrant == null) {
+                Slog.i(TAG, "Cannot log MediaProjectionTargetChanged atom due to null projection");
+            } else {
+                mMediaProjectionMetricsLogger.logChangedCaptureBounds(
+                        contentToRecord, mProjectionGrant.uid, targetUid, captureBounds);
+            }
+        }
+    }
+
     /**
      * Handles result of dialog shown from
      * {@link BinderService#buildReviewGrantedConsentIntentLocked()}.
@@ -557,7 +574,7 @@
                         Slog.w(TAG, "Content Recording: Stopped MediaProjection due to user "
                                 + "consent result of CANCEL - "
                                 + "id= " + mProjectionGrant.getVirtualDisplayId());
-                        mProjectionGrant.stop();
+                        mProjectionGrant.stop(StopReason.STOP_ERROR);
                     }
                     break;
                 case RECORD_CONTENT_DISPLAY:
@@ -773,14 +790,14 @@
 
         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
         @Override // Binder call
-        public void stopActiveProjection() {
+        public void stopActiveProjection(@StopReason int stopReason) {
             stopActiveProjection_enforcePermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
                     if (mProjectionGrant != null) {
                         Slog.d(TAG, "Content Recording: Stopping active projection");
-                        mProjectionGrant.stop();
+                        mProjectionGrant.stop(stopReason);
                     }
                 }
             } finally {
@@ -790,8 +807,9 @@
 
         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
         @Override // Binder call
-        public void notifyActiveProjectionCapturedContentResized(int width, int height) {
-            notifyActiveProjectionCapturedContentResized_enforcePermission();
+        public void notifyCaptureBoundsChanged(
+                int contentToRecord, int targetProcessUid, Rect newBounds) {
+            notifyCaptureBoundsChanged_enforcePermission();
             synchronized (mLock) {
                 if (!isCurrentProjection(mProjectionGrant)) {
                     return;
@@ -801,7 +819,13 @@
             try {
                 synchronized (mLock) {
                     if (mProjectionGrant != null && mCallbackDelegate != null) {
-                        mCallbackDelegate.dispatchResize(mProjectionGrant, width, height);
+                        // log metrics for the new bounds
+                        MediaProjectionManagerService.this.notifyCaptureBoundsChanged(
+                                contentToRecord, targetProcessUid, newBounds);
+
+                        // update clients of the new update bounds
+                        mCallbackDelegate.dispatchResize(
+                                mProjectionGrant, newBounds.width(), newBounds.height());
                     }
                 }
             } finally {
@@ -1133,7 +1157,7 @@
                         Slog.d(TAG, "Content Recording: MediaProjection stopped by Binder death - "
                                 + "id= " + mVirtualDisplayId);
                         mCallbackDelegate.remove(callback);
-                        stop();
+                        stop(StopReason.STOP_TARGET_REMOVED);
                     };
                     mToken.linkToDeath(mDeathEater, 0);
                 } catch (RemoteException e) {
@@ -1182,7 +1206,7 @@
         }
 
         @Override // Binder call
-        public void stop() {
+        public void stop(@StopReason int stopReason) {
             synchronized (mLock) {
                 if (!isCurrentProjection(asBinder())) {
                     Slog.w(TAG, "Attempted to stop inactive MediaProjection "
@@ -1211,7 +1235,7 @@
                 Slog.d(TAG, "Content Recording: handling stopping this projection token"
                         + " createTime= " + mCreateTimeMillis
                         + " countStarts= " + mCountStarts);
-                stopProjectionLocked(this);
+                stopProjectionLocked(this, stopReason);
                 mToken.unlinkToDeath(mDeathEater, 0);
                 mToken = null;
                 unregisterCallback(mCallback);
@@ -1295,7 +1319,7 @@
                     Slog.v(TAG, "Reusing token: Throw exception due to invalid projection.");
                     // Tear down projection here; necessary to ensure (among other reasons) that
                     // stop is dispatched to client and cast icon disappears from status bar.
-                    mProjectionGrant.stop();
+                    mProjectionGrant.stop(StopReason.STOP_ERROR);
                     throw new SecurityException("Don't re-use the resultData to retrieve "
                             + "the same projection instance, and don't use a token that has "
                             + "timed out. Don't take multiple captures by invoking "
@@ -1315,10 +1339,9 @@
                     Slog.w(TAG,
                             "Content Recording: MediaProjection start disallowed, aborting "
                                     + "MediaProjection");
-                    stop();
+                    stop(StopReason.STOP_DEVICE_LOCKED);
                     return;
                 }
-
                 mVirtualDisplayId = displayId;
 
                 // If prior session was does not have a valid display id, then update the display
@@ -1357,7 +1380,7 @@
                     if (mProjectionGrant != null) {
                         Slog.d(TAG, "Content Recording: Stopped MediaProjection due to "
                                 + "route type of REMOTE_DISPLAY not selected");
-                        mProjectionGrant.stop();
+                        mProjectionGrant.stop(StopReason.STOP_NEW_MEDIA_ROUTE);
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java b/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
index be2a25a..8e5c016 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
@@ -19,15 +19,34 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
 import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
 
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CANCELLED;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_DEVICE_LOCK;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_ERROR;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_FOREGROUND_SERVICE_CHANGE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_HOST_APP_STOP;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_MEDIA_ROUTE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_PROJECTION;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_QS_TILE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_STATUS_BAR_CHIP_STOP;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_TASK_APP_CLOSE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_APP_SELECTOR_DISPLAYED;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_USER_SWITCH;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_BOUNDS;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_POSITION;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_WINDOWING_MODE;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_APP_TASK;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_DISPLAY;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN;
@@ -36,8 +55,12 @@
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_SPLIT_SCREEN;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_UNKNOWN;
 
+import android.app.WindowConfiguration;
 import android.app.WindowConfiguration.WindowingMode;
 import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.media.projection.StopReason;
 import android.util.Log;
 import android.view.ContentRecordingSession.RecordContent;
 
@@ -59,8 +82,10 @@
     private final MediaProjectionSessionIdGenerator mSessionIdGenerator;
     private final MediaProjectionTimestampStore mTimestampStore;
 
-    private int mPreviousState =
-            FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;
+    private final Rect mPreviousTargetBounds = new Rect();
+    private int mPreviousTargetWindowingMode = WINDOWING_MODE_UNDEFINED;
+    private int mPreviousProjectionState =
+            MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;
 
     MediaProjectionMetricsLogger(
             FrameworkStatsLogWrapper frameworkStatsLogWrapper,
@@ -113,7 +138,8 @@
                 hostUid,
                 TARGET_UID_UNKNOWN,
                 timeSinceLastActiveInSeconds,
-                sessionCreationSource);
+                sessionCreationSource,
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
     }
 
     /**
@@ -130,7 +156,8 @@
                 hostUid,
                 TARGET_UID_UNKNOWN,
                 TIME_SINCE_LAST_ACTIVE_UNKNOWN,
-                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
     }
 
     /**
@@ -141,13 +168,12 @@
     public void logProjectionPermissionRequestCancelled(int hostUid) {
         writeStateChanged(
                 mSessionIdGenerator.getCurrentSessionId(),
-                FrameworkStatsLog
-                        .MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CANCELLED,
+                MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CANCELLED,
                 hostUid,
                 TARGET_UID_UNKNOWN,
                 TIME_SINCE_LAST_ACTIVE_UNKNOWN,
-                FrameworkStatsLog
-                        .MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
     }
 
     /**
@@ -163,7 +189,8 @@
                 hostUid,
                 TARGET_UID_UNKNOWN,
                 TIME_SINCE_LAST_ACTIVE_UNKNOWN,
-                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
     }
 
     /**
@@ -180,7 +207,8 @@
                 hostUid,
                 targetUid,
                 TIME_SINCE_LAST_ACTIVE_UNKNOWN,
-                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
     }
 
     /**
@@ -196,14 +224,63 @@
      */
     public void logChangedWindowingMode(
             int contentToRecord, int hostUid, int targetUid, int windowingMode) {
-        Log.d(TAG, "logChangedWindowingMode");
+        Log.d(TAG, "logChangedWindowingMode: windowingMode= "
+                + WindowConfiguration.windowingModeToString(windowingMode));
+        Log.d(TAG, "targetChangeType= changeWindowingMode");
         writeTargetChanged(
                 mSessionIdGenerator.getCurrentSessionId(),
                 contentToRecordToTargetType(contentToRecord),
                 hostUid,
                 targetUid,
-                windowingModeToTargetWindowingMode(windowingMode));
+                windowingModeToTargetWindowingMode(windowingMode),
+                mPreviousTargetBounds.width(),
+                mPreviousTargetBounds.height(),
+                mPreviousTargetBounds.centerX(),
+                mPreviousTargetBounds.centerY(),
+                MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_WINDOWING_MODE);
+        mPreviousTargetWindowingMode = windowingMode;
+    }
 
+    /**
+     * Logs that the bounds of projection's capture target has changed.
+     *
+     * @param contentToRecord ContentRecordingSession.RecordContent indicating whether it is a
+     *                        task capture or display capture - gets converted to the corresponding
+     *                        TargetType before being logged.
+     * @param hostUid UID of the package that initiates MediaProjection.
+     * @param targetUid UID of the package that is captured if selected.
+     * @param captureBounds Updated bounds of the captured region.
+     */
+    public void logChangedCaptureBounds(
+            int contentToRecord, int hostUid, int targetUid, Rect captureBounds) {
+        final Point capturePosition = new Point(captureBounds.centerX(), captureBounds.centerY());
+        Log.d(TAG, "logChangedCaptureBounds: captureBounds= " + captureBounds + " position= "
+                + capturePosition);
+
+        writeTargetChanged(
+                mSessionIdGenerator.getCurrentSessionId(),
+                contentToRecordToTargetType(contentToRecord),
+                hostUid,
+                targetUid,
+                mPreviousTargetWindowingMode,
+                captureBounds.width(),
+                captureBounds.height(),
+                captureBounds.centerX(),
+                captureBounds.centerY(),
+                captureBoundsToTargetChangeType(captureBounds));
+        mPreviousTargetBounds.set(captureBounds);
+    }
+
+    private int captureBoundsToTargetChangeType(Rect captureBounds) {
+        final boolean hasChangedSize = captureBounds.width() != mPreviousTargetBounds.width()
+                && captureBounds.height() != mPreviousTargetBounds.height();
+
+        if (hasChangedSize) {
+            Log.d(TAG, "targetChangeType= changeBounds");
+            return MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_BOUNDS;
+        }
+        Log.d(TAG, "targetChangeType= changePosition");
+        return MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_POSITION;
     }
 
     @VisibleForTesting
@@ -231,45 +308,85 @@
         };
     }
 
+    @VisibleForTesting
+    public int stopReasonToSessionStopSource(@StopReason int stopReason) {
+        return switch (stopReason) {
+            case StopReason.STOP_HOST_APP ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_HOST_APP_STOP;
+            case StopReason.STOP_TARGET_REMOVED ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_TASK_APP_CLOSE;
+            case StopReason.STOP_DEVICE_LOCKED->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_DEVICE_LOCK;
+            case StopReason.STOP_PRIVACY_CHIP ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_STATUS_BAR_CHIP_STOP;
+            case StopReason.STOP_QS_TILE ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_QS_TILE;
+            case StopReason.STOP_USER_SWITCH ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_USER_SWITCH;
+            case StopReason.STOP_FOREGROUND_SERVICE_CHANGE ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_FOREGROUND_SERVICE_CHANGE;
+            case StopReason.STOP_NEW_PROJECTION ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_PROJECTION;
+            case StopReason.STOP_NEW_MEDIA_ROUTE ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_MEDIA_ROUTE;
+            case StopReason.STOP_ERROR ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_ERROR;
+            default ->
+                    MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN;
+        };
+    }
+
     /**
      * Logs that the capturing stopped, either normally or because of error.
      *
      * @param hostUid UID of the package that initiates MediaProjection.
      * @param targetUid UID of the package that is captured if selected.
      */
-    public void logStopped(int hostUid, int targetUid) {
+    public void logStopped(int hostUid, int targetUid, int stopReason) {
         boolean wasCaptureInProgress =
-                mPreviousState
+                mPreviousProjectionState
                         == MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS;
-        Log.d(TAG, "logStopped: wasCaptureInProgress=" + wasCaptureInProgress);
+        Log.d(TAG, "logStopped: wasCaptureInProgress=" + wasCaptureInProgress +
+                " stopReason=" + stopReason);
         writeStateChanged(
                 mSessionIdGenerator.getCurrentSessionId(),
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED,
                 hostUid,
                 targetUid,
                 TIME_SINCE_LAST_ACTIVE_UNKNOWN,
-                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+                MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+                stopReasonToSessionStopSource(stopReason));
 
         if (wasCaptureInProgress) {
             mTimestampStore.registerActiveSessionEnded();
         }
     }
 
-    public void notifyProjectionStateChange(int hostUid, int state, int sessionCreationSource) {
-        writeStateChanged(hostUid, state, sessionCreationSource);
+    public void notifyProjectionStateChange(
+            int hostUid,
+            int state,
+            int sessionCreationSource,
+            int sessionStopSource
+    ) {
+        writeStateChanged(hostUid, state, sessionCreationSource, sessionStopSource);
     }
 
-    private void writeStateChanged(int hostUid, int state, int sessionCreationSource) {
+    private void writeStateChanged(
+            int hostUid,
+            int state,
+            int sessionCreationSource,
+            int sessionStopSource
+    ) {
         mFrameworkStatsLogWrapper.writeStateChanged(
-                /* code */ FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED,
+                /* code */ MEDIA_PROJECTION_STATE_CHANGED,
                 /* session_id */ 123,
                 /* state */ state,
-                /* previous_state */ FrameworkStatsLog
-                        .MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN,
+                /* previous_state */ MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN,
                 /* host_uid */ hostUid,
                 /* target_uid */ -1,
                 /* time_since_last_active */ 0,
-                /* creation_source */ sessionCreationSource);
+                /* creation_source */ sessionCreationSource,
+                /* stop_source */ sessionStopSource);
     }
 
     private void writeStateChanged(
@@ -278,17 +395,19 @@
             int hostUid,
             int targetUid,
             int timeSinceLastActive,
-            int creationSource) {
+            int creationSource,
+            int stopSource) {
         mFrameworkStatsLogWrapper.writeStateChanged(
-                /* code */ FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED,
+                /* code */ MEDIA_PROJECTION_STATE_CHANGED,
                 sessionId,
                 state,
-                mPreviousState,
+                mPreviousProjectionState,
                 hostUid,
                 targetUid,
                 timeSinceLastActive,
-                creationSource);
-        mPreviousState = state;
+                creationSource,
+                stopSource);
+        mPreviousProjectionState = state;
     }
 
     private void writeTargetChanged(
@@ -296,13 +415,23 @@
             int targetType,
             int hostUid,
             int targetUid,
-            int targetWindowingMode) {
+            int targetWindowingMode,
+            int width,
+            int height,
+            int centerX,
+            int centerY,
+            int targetChangeType) {
         mFrameworkStatsLogWrapper.writeTargetChanged(
-                /* code */ FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED,
+                /* code */ MEDIA_PROJECTION_TARGET_CHANGED,
                 sessionId,
                 targetType,
                 hostUid,
                 targetUid,
-                targetWindowingMode);
+                targetWindowingMode,
+                width,
+                height,
+                centerX,
+                centerY,
+                targetChangeType);
     }
 }
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java
index 8495b6c..c7e00d3 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -358,5 +358,10 @@
         public boolean isAutoSoundQualityEnabled() {
             return false;
         }
+
+        @Override
+        public boolean isAmbientBacklightEnabled() {
+            return false;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 7fd9620..f914551 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -755,36 +755,7 @@
                     Log.i(TAG, "isGroupChildWithoutSummary OR isGroupSummaryWithoutChild"
                             + record);
                 }
-
-                ArrayMap<String, NotificationAttributes> ungrouped =
-                        mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey,
-                            new ArrayMap<>());
-                ungrouped.put(record.getKey(), new NotificationAttributes(
-                    record.getFlags(),
-                    record.getNotification().getSmallIcon(),
-                    record.getNotification().color,
-                    record.getNotification().visibility,
-                    record.getNotification().getGroupAlertBehavior(),
-                    record.getChannel().getId()));
-                mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
-                // Create/update summary and group if >= mAutoGroupAtCount notifications
-                //  or if aggregate group exists
-                boolean hasSummary = !mAggregatedNotifications.getOrDefault(fullAggregateGroupKey,
-                    new ArrayMap<>()).isEmpty();
-                if (ungrouped.size() >= mAutoGroupAtCount || hasSummary) {
-                    if (DEBUG) {
-                        if (ungrouped.size() >= mAutoGroupAtCount) {
-                            Log.i(TAG,
-                                "Found >=" + mAutoGroupAtCount
-                                    + " ungrouped notifications => force grouping");
-                        } else {
-                            Log.i(TAG, "Found aggregate summary => force grouping");
-                        }
-                    }
-                    aggregateUngroupedNotifications(fullAggregateGroupKey, sbn.getKey(),
-                            ungrouped, hasSummary, sectioner.mSummaryId);
-                }
-
+                addToUngroupedAndMaybeAggregate(record, fullAggregateGroupKey, sectioner);
                 return;
             }
 
@@ -815,6 +786,38 @@
         }
     }
 
+    @GuardedBy("mAggregatedNotifications")
+    private void addToUngroupedAndMaybeAggregate(NotificationRecord record,
+            FullyQualifiedGroupKey fullAggregateGroupKey, NotificationSectioner sectioner) {
+        ArrayMap<String, NotificationAttributes> ungrouped =
+                mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey,
+                    new ArrayMap<>());
+        ungrouped.put(record.getKey(), new NotificationAttributes(
+                record.getFlags(),
+                record.getNotification().getSmallIcon(),
+                record.getNotification().color,
+                record.getNotification().visibility,
+                record.getNotification().getGroupAlertBehavior(),
+                record.getChannel().getId()));
+        mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+        // Create/update summary and group if >= mAutoGroupAtCount notifications
+        //  or if aggregate group exists
+        boolean hasSummary = !mAggregatedNotifications.getOrDefault(fullAggregateGroupKey,
+                new ArrayMap<>()).isEmpty();
+        if (ungrouped.size() >= mAutoGroupAtCount || hasSummary) {
+            if (DEBUG) {
+                if (ungrouped.size() >= mAutoGroupAtCount) {
+                    Slog.i(TAG, "Found >=" + mAutoGroupAtCount
+                            + " ungrouped notifications => force grouping");
+                } else {
+                    Slog.i(TAG, "Found aggregate summary => force grouping");
+                }
+            }
+            aggregateUngroupedNotifications(fullAggregateGroupKey, record.getKey(),
+                    ungrouped, hasSummary, sectioner.mSummaryId);
+        }
+    }
+
     private static boolean isGroupChildBundled(final NotificationRecord record,
             final Map<String, NotificationRecord> summaryByGroupKey) {
         final StatusBarNotification sbn = record.getSbn();
@@ -897,6 +900,73 @@
         }
     }
 
+    /**
+     * Called when a child notification is removed, after some delay, so that this helper can
+     * trigger a forced grouping if the group has become sparse/singleton
+     * or only the summary is left.
+     *
+     * see also {@link #onNotificationPostedWithDelay(NotificationRecord, List, Map)}
+     *
+     * @param summaryRecord the group summary of the notification that was removed
+     * @param notificationList the full notification list from NotificationManagerService
+     * @param summaryByGroupKey the map of group summaries from NotificationManagerService
+     */
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+    protected void onGroupedNotificationRemovedWithDelay(final NotificationRecord summaryRecord,
+            final List<NotificationRecord> notificationList,
+            final Map<String, NotificationRecord> summaryByGroupKey) {
+        final StatusBarNotification sbn = summaryRecord.getSbn();
+        if (!sbn.isAppGroup()) {
+            return;
+        }
+
+        if (summaryRecord.isCanceled) {
+            return;
+        }
+
+        if (mIsTestHarnessExempted) {
+            return;
+        }
+
+        final NotificationSectioner sectioner = getSection(summaryRecord);
+        if (sectioner == null) {
+            if (DEBUG) {
+                Slog.i(TAG,
+                        "Skipping autogrouping for " + summaryRecord + " no valid section found.");
+            }
+            return;
+        }
+
+        final String pkgName = sbn.getPackageName();
+        final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
+                summaryRecord.getUserId(), pkgName, sectioner);
+
+        // This notification is already aggregated
+        if (summaryRecord.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+            return;
+        }
+
+        synchronized (mAggregatedNotifications) {
+            if (isGroupSummaryWithoutChildren(summaryRecord, notificationList)) {
+                if (DEBUG) {
+                    Slog.i(TAG, "isGroupSummaryWithoutChild " + summaryRecord);
+                }
+                addToUngroupedAndMaybeAggregate(summaryRecord, fullAggregateGroupKey, sectioner);
+                return;
+            }
+
+            // Check if notification removal turned this group into a sparse/singleton group
+            if (Flags.notificationForceGroupSingletons()) {
+                try {
+                    groupSparseGroups(summaryRecord, notificationList, summaryByGroupKey, sectioner,
+                            fullAggregateGroupKey);
+                } catch (Throwable e) {
+                    Slog.wtf(TAG, "Failed to group sparse groups", e);
+                }
+            }
+        }
+    }
+
     private record NotificationMoveOp(NotificationRecord record, FullyQualifiedGroupKey oldGroup,
                                       FullyQualifiedGroupKey newGroup) { }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5182dfe..15af36b 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -26,6 +26,7 @@
 import static android.app.AppOpsManager.OP_RECEIVE_SENSITIVE_NOTIFICATIONS;
 import static android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR;
 import static android.app.Flags.lifetimeExtensionRefactor;
+import static android.app.Flags.notificationClassificationUi;
 import static android.app.Flags.sortSectionByTime;
 import static android.app.Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
 import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
@@ -4225,6 +4226,22 @@
         }
 
         @Override
+        @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+        public @NonNull String[] getTypeAdjustmentDeniedPackages() {
+            checkCallerIsSystemOrSystemUiOrShell();
+            return mAssistants.getTypeAdjustmentDeniedPackages();
+        }
+
+        @Override
+        @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+        public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) {
+            checkCallerIsSystemOrSystemUiOrShell();
+            mAssistants.setTypeAdjustmentForPackageState(pkg, enabled);
+
+            handleSavePolicyFile();
+        }
+
+        @Override
         @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
         public boolean appCanBePromoted(String pkg, int uid) {
             checkCallerIsSystemOrSystemUiOrShell();
@@ -6580,6 +6597,14 @@
                         android.Manifest.permission.INTERACT_ACROSS_USERS,
                         "setNotificationListenerAccessGrantedForUser for user " + userId);
             }
+            if (mUmInternal.isVisibleBackgroundFullUser(userId)) {
+                // The main use case for visible background users is the Automotive multi-display
+                // configuration where a passenger can use a secondary display while the driver is
+                // using the main display. NotificationListeners is designed only for the current
+                // user and work profile. We added a condition to prevent visible background users
+                // from updating the data managed within the NotificationListeners object.
+                return;
+            }
             checkNotificationListenerAccess();
             if (granted && listener.flattenToString().length()
                     > NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
@@ -7006,6 +7031,10 @@
                 if (notificationClassification() && adjustments.containsKey(KEY_TYPE)) {
                     if (!mAssistants.isAdjustmentKeyTypeAllowed(adjustments.getInt(KEY_TYPE))) {
                         toRemove.add(potentialKey);
+                    } else if (notificationClassificationUi()
+                            && !mAssistants.isTypeAdjustmentAllowedForPackage(
+                            r.getSbn().getPackageName())) {
+                        toRemove.add(potentialKey);
                     }
                 }
             }
@@ -10500,6 +10529,27 @@
                             mGroupHelper.onNotificationRemoved(r, mNotificationList);
                         }
                     });
+
+                    // Wait 3 seconds so that the app has a chance to cancel/post
+                    // a group summary or children
+                    final NotificationRecord groupSummary = mSummaryByGroupKey.get(r.getGroupKey());
+                    if (groupSummary != null
+                            && !GroupHelper.isAggregatedGroup(groupSummary)
+                            && !groupSummary.getKey().equals(canceledKey)) {
+                        // We only care about app-provided valid group summaries
+                        final String summaryKey = groupSummary.getKey();
+                        mHandler.removeCallbacksAndEqualMessages(summaryKey);
+                        mHandler.postDelayed(() -> {
+                            synchronized (mNotificationLock) {
+                                NotificationRecord summaryRecord = mNotificationsByKey.get(
+                                        summaryKey);
+                                if (summaryRecord != null) {
+                                    mGroupHelper.onGroupedNotificationRemovedWithDelay(
+                                            summaryRecord, mNotificationList, mSummaryByGroupKey);
+                                }
+                            }
+                        }, summaryKey, DELAY_FORCE_REGROUP_TIME);
+                    }
                 } else {
                     mHandler.post(new Runnable() {
                         @Override
@@ -11643,6 +11693,7 @@
         private static final String ATT_DENIED = "denied_adjustments";
         private static final String ATT_ENABLED_TYPES = "enabled_key_types";
         private static final String ATT_NAS_UNSUPPORTED = "unsupported_adjustments";
+        private static final String ATT_TYPES_DENIED_APPS = "types_denied_apps";
 
         private final Object mLock = new Object();
 
@@ -11658,6 +11709,9 @@
         @GuardedBy("mLock")
         private Map<Integer, HashSet<String>> mNasUnsupported = new ArrayMap<>();
 
+        @GuardedBy("mLock")
+        private Set<String> mClassificationTypeDeniedPackages = new ArraySet<>();
+
         protected ComponentName mDefaultFromConfig = null;
 
         @Override
@@ -11857,6 +11911,44 @@
             }
         }
 
+        @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+        protected @NonNull boolean isTypeAdjustmentAllowedForPackage(String pkg) {
+            synchronized (mLock) {
+                if (notificationClassificationUi()) {
+                    return !mClassificationTypeDeniedPackages.contains(pkg);
+                }
+            }
+            return true;
+        }
+
+        @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+        protected @NonNull String[] getTypeAdjustmentDeniedPackages() {
+            synchronized (mLock) {
+                if (notificationClassificationUi()) {
+                    return mClassificationTypeDeniedPackages.toArray(new String[0]);
+                }
+            }
+            return new String[]{};
+        }
+
+        /**
+         * Set whether a particular package can have its notification channels adjusted to have a
+         * different type by NotificationAssistants.
+         */
+        @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+        public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) {
+            if (!notificationClassificationUi()) {
+                return;
+            }
+            synchronized (mLock) {
+                if (enabled) {
+                    mClassificationTypeDeniedPackages.remove(pkg);
+                } else {
+                    mClassificationTypeDeniedPackages.add(pkg);
+                }
+            }
+        }
+
         protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) {
             for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
                 ArrayList<String> keys = new ArrayList<>(records.size());
@@ -11953,8 +12045,10 @@
                             assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel(),
                                     update);
                         }
+                    } catch (DeadObjectException ex) {
+                        Slog.wtf(TAG, "unable to notify assistant (enqueued): " + info, ex);
                     } catch (RemoteException ex) {
-                        Slog.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+                        Slog.e(TAG, "unable to notify assistant (enqueued): " + info, ex);
                     }
                 }
             }
@@ -12075,19 +12169,21 @@
                     r.getSbn(),
                     r.getNotificationType(),
                     true /* sameUserOnly */,
-                    (assistant, sbnToPost) -> {
+                    (info, sbnToPost) -> {
                         try {
                             if (android.app.Flags.noSbnholder()) {
-                                assistant.onNotificationSnoozedUntilContextFull(
+                                info.onNotificationSnoozedUntilContextFull(
                                         sbnToPost, snoozeCriterionId);
                             } else {
                                 final StatusBarNotificationHolder sbnHolder =
                                         new StatusBarNotificationHolder(sbnToPost);
-                                assistant.onNotificationSnoozedUntilContext(
+                                info.onNotificationSnoozedUntilContext(
                                         sbnHolder, snoozeCriterionId);
                             }
+                        } catch (DeadObjectException ex) {
+                            Slog.wtf(TAG, "unable to notify assistant (snoozed): " + info, ex);
                         } catch (RemoteException ex) {
-                            Slog.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
+                            Slog.e(TAG, "unable to notify assistant (snoozed): " + info, ex);
                         }
                     });
         }
@@ -12315,6 +12411,12 @@
                 out.attribute(null, ATT_TYPES,
                         TextUtils.join(",", mAllowedAdjustmentKeyTypes));
                 out.endTag(null, ATT_ENABLED_TYPES);
+                if (notificationClassificationUi()) {
+                    out.startTag(null, ATT_TYPES_DENIED_APPS);
+                    out.attribute(null, ATT_TYPES,
+                            TextUtils.join(",", mClassificationTypeDeniedPackages));
+                    out.endTag(null, ATT_TYPES_DENIED_APPS);
+                }
             }
         }
 
@@ -12346,6 +12448,14 @@
                         }
                     }
                 }
+            } else if (notificationClassificationUi() && ATT_TYPES_DENIED_APPS.equals(tag)) {
+                final String apps = XmlUtils.readStringAttribute(parser, ATT_TYPES);
+                synchronized (mLock) {
+                    mClassificationTypeDeniedPackages.clear();
+                    if (!TextUtils.isEmpty(apps)) {
+                        mClassificationTypeDeniedPackages.addAll(Arrays.asList(apps.split(",")));
+                    }
+                }
             }
         }
 
@@ -12644,6 +12754,20 @@
         }
 
         @Override
+        public void onUserUnlocked(int user) {
+            if (mUmInternal.isVisibleBackgroundFullUser(user)) {
+                // The main use case for visible background users is the Automotive
+                // multi-display configuration where a passenger can use a secondary
+                // display while the driver is using the main display.
+                // NotificationListeners is designed only for the current user and work
+                // profile. We added a condition to prevent visible background users from
+                // updating the data managed within the NotificationListeners object.
+                return;
+            }
+            super.onUserUnlocked(user);
+        }
+
+        @Override
         protected boolean allowRebindForParentUser() {
             return true;
         }
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index e6f784c..749952e 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -184,6 +184,7 @@
     private static final boolean DEFAULT_SHOW_BADGE = true;
 
     private static final boolean DEFAULT_APP_LOCKED_IMPORTANCE  = false;
+    private static final boolean DEFAULT_CAN_HAVE_PROMOTED_NOTIFS = true;
 
     static final boolean DEFAULT_BUBBLES_ENABLED = true;
     @VisibleForTesting
@@ -369,8 +370,8 @@
                     null, ATT_USER_DEMOTED_INVALID_MSG_APP, false);
             r.hasSentValidBubble = parser.getAttributeBoolean(null, ATT_SENT_VALID_BUBBLE, false);
             if (android.app.Flags.uiRichOngoing()) {
-                r.canHavePromotedNotifs =
-                        parser.getAttributeBoolean(null, ATT_PROMOTE_NOTIFS, false);
+                r.canHavePromotedNotifs = parser.getAttributeBoolean(null, ATT_PROMOTE_NOTIFS,
+                        DEFAULT_CAN_HAVE_PROMOTED_NOTIFS);
             }
 
             final int innerDepth = parser.getDepth();
@@ -748,7 +749,7 @@
                 r.userDemotedMsgApp);
         out.attributeBoolean(null, ATT_SENT_VALID_BUBBLE, r.hasSentValidBubble);
         if (android.app.Flags.uiRichOngoing()) {
-            if (r.canHavePromotedNotifs) {
+            if (r.canHavePromotedNotifs != DEFAULT_CAN_HAVE_PROMOTED_NOTIFS) {
                 out.attributeBoolean(null, ATT_PROMOTE_NOTIFS, r.canHavePromotedNotifs);
             }
         }
@@ -2331,7 +2332,8 @@
                     pw.print(" fixedImportance=");
                     pw.print(r.fixedImportance);
                 }
-                if (android.app.Flags.uiRichOngoing() && r.canHavePromotedNotifs) {
+                if (android.app.Flags.uiRichOngoing()
+                        && r.canHavePromotedNotifs != DEFAULT_CAN_HAVE_PROMOTED_NOTIFS) {
                     pw.print(" promoted=");
                     pw.print(r.canHavePromotedNotifs);
                 }
@@ -3184,7 +3186,8 @@
         long creationTime;
 
         @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
-        boolean canHavePromotedNotifs = false;
+        // Until we enable the UI, we should return false.
+        boolean canHavePromotedNotifs = android.app.Flags.uiRichOngoing();
 
         @UserIdInt int userId;
 
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 81dc38a..dc173b1 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -1941,7 +1941,17 @@
     @Nullable
     public Policy getNotificationPolicy(UserHandle user) {
         synchronized (mConfigLock) {
-            return getNotificationPolicy(getConfigLocked(user));
+            if (Flags.modesMultiuser()) {
+                // Return a fallback (default) policy for users without a zen config.
+                // Note that zen updates (setPolicy, setFilter) won't be applied, so this is mostly
+                // about preventing NPEs for careless callers.
+                ZenModeConfig config = getConfigLocked(user);
+                return config != null
+                        ? getNotificationPolicy(config)
+                        : getNotificationPolicy(mDefaultConfig);
+            } else {
+                return getNotificationPolicy(getConfigLocked(user));
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java b/services/core/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java
index b532d5a..bef3f80 100644
--- a/services/core/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java
+++ b/services/core/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java
@@ -20,8 +20,8 @@
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService;
-import android.util.Slog;
 import android.util.Base64;
+import android.util.Slog;
 
 import java.io.IOException;
 import java.util.Comparator;
@@ -36,12 +36,12 @@
     public InferenceInfoStore(long maxAgeMs) {
         this.maxAgeMs = maxAgeMs;
         this.inferenceInfos = new TreeSet<>(
-                Comparator.comparingLong(InferenceInfo::getStartTimeMs));
+                Comparator.comparingLong(InferenceInfo::getStartTimeMillis));
     }
 
     public List<InferenceInfo> getLatestInferenceInfo(long startTimeEpochMillis) {
         return inferenceInfos.stream().filter(
-                info -> info.getStartTimeMs() > startTimeEpochMillis).toList();
+                info -> info.getStartTimeMillis() > startTimeEpochMillis).toList();
     }
 
     public void addInferenceInfoFromBundle(PersistableBundle pb) {
@@ -85,7 +85,7 @@
 
     private synchronized void add(com.android.server.ondeviceintelligence.nano.InferenceInfo info) {
         while (!inferenceInfos.isEmpty()
-                && System.currentTimeMillis() - inferenceInfos.first().getStartTimeMs()
+                && System.currentTimeMillis() - inferenceInfos.first().getStartTimeMillis()
                 > maxAgeMs) {
             inferenceInfos.pollFirst();
         }
@@ -94,8 +94,8 @@
 
     private static InferenceInfo toInferenceInfo(
             com.android.server.ondeviceintelligence.nano.InferenceInfo info) {
-        return new InferenceInfo.Builder().setUid(info.uid).setStartTimeMs(
-                info.startTimeMs).setEndTimeMs(info.endTimeMs).setSuspendedTimeMs(
+        return new InferenceInfo.Builder(info.uid).setStartTimeMillis(
+                info.startTimeMs).setEndTimeMillis(info.endTimeMs).setSuspendedTimeMillis(
                 info.suspendedTimeMs).build();
     }
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/pm/InstallDependencyHelper.java b/services/core/java/com/android/server/pm/InstallDependencyHelper.java
index 527d680..42b8dd7 100644
--- a/services/core/java/com/android/server/pm/InstallDependencyHelper.java
+++ b/services/core/java/com/android/server/pm/InstallDependencyHelper.java
@@ -16,13 +16,16 @@
 
 package com.android.server.pm;
 
+import static android.content.pm.PackageInstaller.ACTION_INSTALL_DEPENDENCY;
 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
 import static android.os.Process.SYSTEM_UID;
 
 import android.annotation.NonNull;
+import android.app.role.RoleManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageInstaller.SessionInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.dependencyinstaller.DependencyInstallerCallback;
@@ -33,12 +36,15 @@
 import android.os.OutcomeReceiver;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.ArraySet;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.infra.AndroidFuture;
 import com.android.internal.infra.ServiceConnector;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -48,22 +54,27 @@
 public class InstallDependencyHelper {
     private static final String TAG = InstallDependencyHelper.class.getSimpleName();
     private static final boolean DEBUG = true;
-    private static final String ACTION_INSTALL_DEPENDENCY =
-            "android.intent.action.INSTALL_DEPENDENCY";
+    private static final String ROLE_SYSTEM_DEPENDENCY_INSTALLER =
+            "android.app.role.SYSTEM_DEPENDENCY_INSTALLER";
     // The maximum amount of time to wait before the system unbinds from the verifier.
     private static final long UNBIND_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(6);
     private static final long REQUEST_TIMEOUT_MILLIS = TimeUnit.MINUTES.toMillis(1);
 
-    private final SharedLibrariesImpl mSharedLibraries;
     private final Context mContext;
+    private final SharedLibrariesImpl mSharedLibraries;
+    private final PackageInstallerService mPackageInstallerService;
     private final Object mRemoteServiceLock = new Object();
+    @GuardedBy("mTrackers")
+    private final List<DependencyInstallTracker> mTrackers = new ArrayList<>();
 
     @GuardedBy("mRemoteServiceLock")
     private ServiceConnector<IDependencyInstallerService> mRemoteService = null;
 
-    InstallDependencyHelper(Context context, SharedLibrariesImpl sharedLibraries) {
+    InstallDependencyHelper(Context context, SharedLibrariesImpl sharedLibraries,
+            PackageInstallerService packageInstallerService) {
         mContext = context;
         mSharedLibraries = sharedLibraries;
+        mPackageInstallerService = packageInstallerService;
     }
 
     void resolveLibraryDependenciesIfNeeded(PackageLite pkg, Computer snapshot, int userId,
@@ -98,19 +109,8 @@
             return;
         }
 
-        IDependencyInstallerCallback serviceCallback = new IDependencyInstallerCallback.Stub() {
-            @Override
-            public void onAllDependenciesResolved(int[] sessionIds) throws RemoteException {
-                // TODO(b/372862145): Implement waiting for sessions to finish installation
-                callback.onResult(null);
-            }
-
-            @Override
-            public void onFailureToResolveAllDependencies() throws RemoteException {
-                onError(callback, "Failed to resolve all dependencies automatically");
-            }
-        };
-
+        IDependencyInstallerCallback serviceCallback =
+                new DependencyInstallerCallbackCallOnce(handler, callback);
         boolean scheduleSuccess;
         synchronized (mRemoteServiceLock) {
             scheduleSuccess = mRemoteService.run(service -> {
@@ -123,10 +123,28 @@
         }
     }
 
-    private void onError(CallOnceProxy callback, String msg) {
+    void notifySessionComplete(int sessionId, boolean success) {
+        if (DEBUG) {
+            Slog.i(TAG, "Session complete for " + sessionId + " result: " + success);
+        }
+        synchronized (mTrackers) {
+            List<DependencyInstallTracker> completedTrackers = new ArrayList<>();
+            for (DependencyInstallTracker tracker: mTrackers) {
+                if (!tracker.onSessionComplete(sessionId, success)) {
+                    completedTrackers.add(tracker);
+                }
+            }
+            mTrackers.removeAll(completedTrackers);
+        }
+    }
+
+    private static void onError(CallOnceProxy callback, String msg) {
         PackageManagerException pe = new PackageManagerException(
                 INSTALL_FAILED_MISSING_SHARED_LIBRARY, msg);
         callback.onError(pe);
+        if (DEBUG) {
+            Slog.i(TAG, "Orig session error: " + msg);
+        }
     }
 
     private boolean bindToDependencyInstallerIfNeeded(int userId, Handler handler,
@@ -140,8 +158,20 @@
             }
         }
 
+        RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+        if (roleManager == null) {
+            Slog.w(TAG, "Cannot find RoleManager system service");
+            return false;
+        }
+        List<String> holders = roleManager.getRoleHoldersAsUser(
+                ROLE_SYSTEM_DEPENDENCY_INSTALLER, UserHandle.of(userId));
+        if (holders.isEmpty()) {
+            Slog.w(TAG, "No holders of ROLE_SYSTEM_DEPENDENCY_INSTALLER found");
+            return false;
+        }
+
         Intent serviceIntent = new Intent(ACTION_INSTALL_DEPENDENCY);
-        // TODO(b/372862145): Use RoleManager to find the package name
+        serviceIntent.setPackage(holders.getFirst());
         List<ResolveInfo> resolvedIntents = snapshot.queryIntentServicesInternal(
                 serviceIntent, /*resolvedType=*/ null, /*flags=*/0,
                 userId, SYSTEM_UID, Process.INVALID_PID,
@@ -151,7 +181,6 @@
             return false;
         }
 
-
         ResolveInfo resolveInfo = resolvedIntents.getFirst();
         ComponentName componentName = resolveInfo.getComponentInfo().getComponentName();
         serviceIntent.setComponent(componentName);
@@ -253,4 +282,135 @@
             }
         }
     }
+
+    /**
+     * Ensure we call one of the outcomes only once, on the right handler.
+     *
+     * Repeated calls will be no-op.
+     */
+    private class DependencyInstallerCallbackCallOnce extends IDependencyInstallerCallback.Stub {
+
+        private final Handler mHandler;
+        private final CallOnceProxy mCallback;
+
+        @GuardedBy("this")
+        private boolean mCalled = false;
+
+        DependencyInstallerCallbackCallOnce(Handler handler, CallOnceProxy callback) {
+            mHandler = handler;
+            mCallback = callback;
+        }
+
+        // TODO(b/372862145): Consider turning the binder call to two-way so that we can
+        //  throw IllegalArgumentException
+        @Override
+        public void onAllDependenciesResolved(int[] sessionIds) throws RemoteException {
+            synchronized (this) {
+                if (mCalled) {
+                    return;
+                }
+                mCalled = true;
+            }
+
+            ArraySet<Integer> set = new ArraySet<>();
+            for (int i = 0; i < sessionIds.length; i++) {
+                if (DEBUG) {
+                    Slog.i(TAG, "onAllDependenciesResolved called with " + sessionIds[i]);
+                }
+                set.add(sessionIds[i]);
+            }
+
+            DependencyInstallTracker tracker = new DependencyInstallTracker(mCallback, set);
+            synchronized (mTrackers) {
+                mTrackers.add(tracker);
+            }
+
+            // In case any of the session ids have already been installed, check if they
+            // are valid.
+            mHandler.post(() -> {
+                if (DEBUG) {
+                    Slog.i(TAG, "onAllDependenciesResolved cleaning up invalid sessions");
+                }
+
+                for (int i = 0; i < sessionIds.length; i++) {
+                    int sessionId = sessionIds[i];
+                    SessionInfo sessionInfo = mPackageInstallerService.getSessionInfo(sessionId);
+
+                    // Continue waiting if session exists and hasn't passed or failed yet.
+                    if (sessionInfo != null && !sessionInfo.isSessionApplied
+                            && !sessionInfo.isSessionFailed) {
+                        continue;
+                    }
+
+                    if (DEBUG) {
+                        Slog.i(TAG, "onAllDependenciesResolved cleaning up finished"
+                                + " session: " + sessionId);
+                    }
+
+                    // If session info is null, we assume it to be success.
+                    // TODO(b/372862145): Check historical sessions to be more precise.
+                    boolean success = sessionInfo == null || sessionInfo.isSessionApplied;
+
+                    notifySessionComplete(sessionId, /*success=*/success);
+                }
+            });
+        }
+
+        @Override
+        public void onFailureToResolveAllDependencies() throws RemoteException {
+            synchronized (this) {
+                if (mCalled) {
+                    return;
+                }
+                onError(mCallback, "Failed to resolve all dependencies automatically");
+                mCalled = true;
+            }
+        }
+    }
+
+    /**
+     * Tracks a list of session ids against a particular callback.
+     *
+     * If all the sessions completes successfully, it invokes the positive flow. If any of the
+     * sessions fails, it invokes the failure flow immediately.
+     */
+    // TODO(b/372862145): Determine and add support for rebooting while dependency is being resolved
+    private static class DependencyInstallTracker {
+        private final CallOnceProxy mCallback;
+        private final ArraySet<Integer> mPendingSessionIds;
+
+        DependencyInstallTracker(CallOnceProxy callback, ArraySet<Integer> pendingSessionIds) {
+            mCallback = callback;
+            mPendingSessionIds = pendingSessionIds;
+        }
+
+        /**
+         * Process a session complete event.
+         *
+         * Returns true if we still need to continue tracking.
+         */
+        public boolean onSessionComplete(int sessionId, boolean success) {
+            synchronized (this) {
+                if (!mPendingSessionIds.contains(sessionId)) {
+                    // This had no impact on tracker, so continue tracking
+                    return true;
+                }
+
+                if (!success) {
+                    // If one of the dependency fails, the orig session would fail too.
+                    onError(mCallback, "Failed to install all dependencies");
+                    // TODO(b/372862145): Abandon the rest of the pending sessions.
+                    return false; // No point in tracking anymore
+                }
+
+                mPendingSessionIds.remove(sessionId);
+                if (mPendingSessionIds.isEmpty()) {
+                    mCallback.onResult(null);
+                    return false; // Nothing to track anymore
+                }
+                return true; // Keep on tracking
+            }
+        }
+
+    }
 }
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 8168c54..e5e2744 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -229,6 +229,7 @@
     private final SharedLibrariesImpl mSharedLibraries;
     private final PackageManagerServiceInjector mInjector;
     private final UpdateOwnershipHelper mUpdateOwnershipHelper;
+    private final InstallDependencyHelper mInstallDependencyHelper;
 
     private final Object mInternalLock = new Object();
     @GuardedBy("mInternalLock")
@@ -239,7 +240,8 @@
                          AppDataHelper appDataHelper,
                          RemovePackageHelper removePackageHelper,
                          DeletePackageHelper deletePackageHelper,
-                         BroadcastHelper broadcastHelper) {
+                         BroadcastHelper broadcastHelper,
+                         InstallDependencyHelper installDependencyHelper) {
         mPm = pm;
         mInjector = pm.mInjector;
         mAppDataHelper = appDataHelper;
@@ -253,6 +255,7 @@
         mPackageAbiHelper = pm.mInjector.getAbiHelper();
         mSharedLibraries = pm.mInjector.getSharedLibrariesImpl();
         mUpdateOwnershipHelper = pm.mInjector.getUpdateOwnershipHelper();
+        mInstallDependencyHelper = installDependencyHelper;
     }
 
     /**
@@ -1364,6 +1367,10 @@
                 }
             }
         }
+
+        for (InstallRequest request : requests) {
+            mInstallDependencyHelper.notifySessionComplete(request.getSessionId(), success);
+        }
     }
 
     @GuardedBy("mPm.mInstallLock")
diff --git a/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java b/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java
index 99eac37..ea37d8e 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java
@@ -79,8 +79,6 @@
     private final String mSessionErrorMessage;
     private final String mPreVerifiedDomains;
     private final String mPackageName;
-    private final int mInitialVerificationPolicy;
-    private final int mCurrentVerificationPolicy;
 
     PackageInstallerHistoricalSession(int sessionId, int userId, int originalInstallerUid,
             String originalInstallerPackageName, InstallSource installSource, int installerUid,
@@ -92,8 +90,7 @@
             int[] childSessionIds, boolean sessionApplied, boolean sessionFailed,
             boolean sessionReady, int sessionErrorCode, String sessionErrorMessage,
             PreapprovalDetails preapprovalDetails, DomainSet preVerifiedDomains,
-            String packageNameFromApk, int initialVerificationPolicy,
-            int currentVerificationPolicy) {
+            String packageNameFromApk) {
         this.sessionId = sessionId;
         this.userId = userId;
         this.mOriginalInstallerUid = originalInstallerUid;
@@ -143,8 +140,6 @@
 
         this.mPackageName = preapprovalDetails != null ? preapprovalDetails.getPackageName()
                 : packageNameFromApk != null ? packageNameFromApk : params.appPackageName;
-        this.mInitialVerificationPolicy = initialVerificationPolicy;
-        this.mCurrentVerificationPolicy = currentVerificationPolicy;
     }
 
     void dump(IndentingPrintWriter pw) {
@@ -189,8 +184,6 @@
         pw.printPair("mPreapprovalDetails", mPreapprovalDetails);
         pw.printPair("mPreVerifiedDomains", mPreVerifiedDomains);
         pw.printPair("mAppPackageName", mPackageName);
-        pw.printPair("mInitialVerificationPolicy", mInitialVerificationPolicy);
-        pw.printPair("mCurrentVerificationPolicy", mCurrentVerificationPolicy);
         pw.println();
 
         pw.decreaseIndent();
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 9b44f93..47b7850 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -25,22 +25,18 @@
 import static android.content.pm.PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED;
 import static android.content.pm.PackageInstaller.UNARCHIVAL_GENERIC_ERROR;
 import static android.content.pm.PackageInstaller.UNARCHIVAL_OK;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_WARN;
 import static android.content.pm.PackageManager.DELETE_ARCHIVE;
 import static android.content.pm.PackageManager.INSTALL_UNARCHIVE_DRAFT;
 import static android.os.Process.INVALID_UID;
 import static android.os.Process.SYSTEM_UID;
-import static android.os.UserHandle.USER_SYSTEM;
 
 import static com.android.server.pm.PackageArchiver.isArchivingEnabled;
-import static com.android.server.pm.PackageInstallerSession.isValidVerificationPolicy;
 import static com.android.server.pm.PackageManagerService.SHELL_PACKAGE_NAME;
 
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
 import android.Manifest;
-import android.annotation.EnforcePermission;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -89,7 +85,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelableException;
-import android.os.PermissionEnforcer;
 import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteCallbackList;
@@ -131,7 +126,6 @@
 import com.android.server.SystemServiceManager;
 import com.android.server.pm.pkg.PackageStateInternal;
 import com.android.server.pm.utils.RequestThrottle;
-import com.android.server.pm.verify.pkg.VerifierController;
 
 import libcore.io.IoUtils;
 
@@ -219,7 +213,6 @@
     private final StagingManager mStagingManager;
 
     private AppOpsManager mAppOps;
-    private final VerifierController mVerifierController;
     private final InstallDependencyHelper mInstallDependencyHelper;
 
     private final HandlerThread mInstallThread;
@@ -281,14 +274,6 @@
         }
     };
 
-    /**
-     * Default verification policy for incoming installation sessions, mapped from userId to policy.
-     */
-    @GuardedBy("mVerificationPolicyPerUser")
-    private final SparseIntArray mVerificationPolicyPerUser = new SparseIntArray(1);
-    // TODO(b/360129657): update the default policy.
-    private static final int DEFAULT_VERIFICATION_POLICY = VERIFICATION_POLICY_BLOCK_FAIL_WARN;
-
     private static final class Lifecycle extends SystemService {
         private final PackageInstallerService mPackageInstallerService;
 
@@ -318,8 +303,6 @@
 
     public PackageInstallerService(Context context, PackageManagerService pm,
             Supplier<PackageParser2> apexParserSupplier) {
-        super(PermissionEnforcer.fromContext(context));
-
         mContext = context;
         mPm = pm;
 
@@ -343,12 +326,8 @@
         mGentleUpdateHelper = new GentleUpdateHelper(
                 context, mInstallThread.getLooper(), new AppStateHelper(context));
         mPackageArchiver = new PackageArchiver(mContext, mPm);
-        mVerifierController = new VerifierController(mContext, mInstallHandler);
-        synchronized (mVerificationPolicyPerUser) {
-            mVerificationPolicyPerUser.put(USER_SYSTEM, DEFAULT_VERIFICATION_POLICY);
-        }
         mInstallDependencyHelper = new InstallDependencyHelper(mContext,
-                mPm.mInjector.getSharedLibrariesImpl());
+                mPm.mInjector.getSharedLibrariesImpl(), this);
 
         LocalServices.getService(SystemServiceManager.class).startService(
                 new Lifecycle(context, this));
@@ -358,6 +337,10 @@
         return mStagingManager;
     }
 
+    InstallDependencyHelper getInstallDependencyHelper() {
+        return mInstallDependencyHelper;
+    }
+
     boolean okToSendBroadcasts()  {
         return mOkToSendBroadcasts;
     }
@@ -546,7 +529,7 @@
                             session = PackageInstallerSession.readFromXml(in, mInternalCallback,
                                     mContext, mPm, mInstallThread.getLooper(), mStagingManager,
                                     mSessionsDir, this, mSilentUpdatePolicy,
-                                    mVerifierController, mInstallDependencyHelper);
+                                    mInstallDependencyHelper);
                         } catch (Exception e) {
                             Slog.e(TAG, "Could not read session", e);
                             continue;
@@ -1058,17 +1041,11 @@
         InstallSource installSource = InstallSource.create(installerPackageName,
                 originatingPackageName, requestedInstallerPackageName, requestedInstallerPackageUid,
                 requestedInstallerPackageName, installerAttributionTag, params.packageSource);
-        final int verificationPolicy;
-        synchronized (mVerificationPolicyPerUser) {
-            verificationPolicy = mVerificationPolicyPerUser.get(
-                    userId, DEFAULT_VERIFICATION_POLICY);
-        }
         session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
                 mSilentUpdatePolicy, mInstallThread.getLooper(), mStagingManager, sessionId,
                 userId, callingUid, installSource, params, createdMillis, 0L, stageDir, stageCid,
                 null, null, false, false, false, false, null, SessionInfo.INVALID_ID,
                 false, false, false, PackageManager.INSTALL_UNKNOWN, "", null,
-                mVerifierController, verificationPolicy, verificationPolicy,
                 mInstallDependencyHelper);
 
         synchronized (mSessions) {
@@ -1079,7 +1056,6 @@
         mCallbacks.notifySessionCreated(session.sessionId, session.userId);
 
         mSettingsWriteRequest.schedule();
-
         if (LOGD) {
             Slog.d(TAG, "Created session id=" + sessionId + " staged=" + params.isStaged);
         }
@@ -1893,58 +1869,6 @@
         }
     }
 
-    @Override
-    @EnforcePermission(android.Manifest.permission.VERIFICATION_AGENT)
-    public @PackageInstaller.VerificationPolicy int getVerificationPolicy(int userId) {
-        getVerificationPolicy_enforcePermission();
-        synchronized (mVerificationPolicyPerUser) {
-            if (mVerificationPolicyPerUser.indexOfKey(userId) < 0) {
-                throw new IllegalStateException(
-                        "Verification policy for user " + userId + " does not exist."
-                                + " Does the user exist?");
-            }
-            return mVerificationPolicyPerUser.get(userId);
-        }
-    }
-
-    @Override
-    @EnforcePermission(android.Manifest.permission.VERIFICATION_AGENT)
-    public boolean setVerificationPolicy(@PackageInstaller.VerificationPolicy int policy,
-            int userId) {
-        setVerificationPolicy_enforcePermission();
-        final int callingUid = getCallingUid();
-        // Only the verifier currently bound by the system can change the policy, except for Shell
-        if (!PackageManagerServiceUtils.isRootOrShell(callingUid)) {
-            mVerifierController.assertCallerIsCurrentVerifier(callingUid);
-        }
-        if (!isValidVerificationPolicy(policy)) {
-            return false;
-        }
-        synchronized (mVerificationPolicyPerUser) {
-            if (mVerificationPolicyPerUser.indexOfKey(userId) < 0) {
-                throw new IllegalStateException(
-                        "Verification policy for user " + userId + " does not exist."
-                                + " Does the user exist?");
-            }
-            if (policy != mVerificationPolicyPerUser.get(userId)) {
-                mVerificationPolicyPerUser.put(userId, policy);
-            }
-        }
-        return true;
-    }
-
-    void onUserAdded(int userId) {
-        synchronized (mVerificationPolicyPerUser) {
-            mVerificationPolicyPerUser.put(userId, DEFAULT_VERIFICATION_POLICY);
-        }
-    }
-
-    void onUserRemoved(int userId) {
-        synchronized (mVerificationPolicyPerUser) {
-            mVerificationPolicyPerUser.delete(userId);
-        }
-    }
-
     private static int getSessionCount(SparseArray<PackageInstallerSession> sessions,
             int installerUid) {
         int count = 0;
@@ -2341,9 +2265,6 @@
         }
         mSilentUpdatePolicy.dump(pw);
         mGentleUpdateHelper.dump(pw);
-        synchronized (mVerificationPolicyPerUser) {
-            pw.printPair("VerificationPolicyPerUser", mVerificationPolicyPerUser.toString());
-        }
     }
 
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 505b7e6..8f8802e 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -21,17 +21,9 @@
 import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_UPDATED_BY_DO;
 import static android.content.pm.DataLoaderType.INCREMENTAL;
 import static android.content.pm.DataLoaderType.STREAMING;
-import static android.content.pm.PackageInstaller.EXTRA_VERIFICATION_FAILURE_REASON;
 import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;
 import static android.content.pm.PackageInstaller.UNARCHIVAL_OK;
 import static android.content.pm.PackageInstaller.UNARCHIVAL_STATUS_UNSET;
-import static android.content.pm.PackageInstaller.VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE;
-import static android.content.pm.PackageInstaller.VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED;
-import static android.content.pm.PackageInstaller.VERIFICATION_FAILED_REASON_UNKNOWN;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_OPEN;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_WARN;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_NONE;
 import static android.content.pm.PackageItemInfo.MAX_SAFE_LABEL_LENGTH;
 import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED;
 import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_SIGNATURE;
@@ -46,7 +38,6 @@
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
 import static android.content.pm.PackageManager.INSTALL_STAGED;
 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
-import static android.content.pm.verify.pkg.VerificationSession.VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE;
 import static android.os.Process.INVALID_UID;
 import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
 import static android.system.OsConstants.O_CREAT;
@@ -117,9 +108,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.PackageInfoFlags;
 import android.content.pm.PackageManagerInternal;
-import android.content.pm.SharedLibraryInfo;
 import android.content.pm.SigningDetails;
-import android.content.pm.SigningInfo;
 import android.content.pm.dex.DexMetadataHelper;
 import android.content.pm.parsing.ApkLite;
 import android.content.pm.parsing.ApkLiteParseUtils;
@@ -127,7 +116,6 @@
 import android.content.pm.parsing.result.ParseResult;
 import android.content.pm.parsing.result.ParseTypeImpl;
 import android.content.pm.verify.domain.DomainSet;
-import android.content.pm.verify.pkg.VerificationStatus;
 import android.content.res.ApkAssets;
 import android.content.res.AssetManager;
 import android.content.res.Configuration;
@@ -135,7 +123,6 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.icu.util.ULocale;
-import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -148,7 +135,6 @@
 import android.os.OutcomeReceiver;
 import android.os.ParcelFileDescriptor;
 import android.os.ParcelableException;
-import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.RevocableFileDescriptor;
@@ -206,7 +192,6 @@
 import com.android.server.pm.dex.DexManager;
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageStateInternal;
-import com.android.server.pm.verify.pkg.VerifierController;
 
 import libcore.io.IoUtils;
 import libcore.util.EmptyArray;
@@ -321,8 +306,6 @@
     private static final String ATTR_APPLICATION_ENABLED_SETTING_PERSISTENT =
             "applicationEnabledSettingPersistent";
     private static final String ATTR_DOMAIN = "domain";
-    private static final String ATTR_INITIAL_VERIFICATION_POLICY = "initialVerificationPolicy";
-    private static final String ATTR_CURRENT_VERIFICATION_POLICY = "currentVerificationPolicy";
 
     private static final String PROPERTY_NAME_INHERIT_NATIVE = "pi.inherit_native_on_dont_kill";
     private static final int[] EMPTY_CHILD_SESSION_ARRAY = EmptyArray.INT;
@@ -420,19 +403,9 @@
     private final PackageSessionProvider mSessionProvider;
     private final SilentUpdatePolicy mSilentUpdatePolicy;
     /**
-     * The initial verification policy assigned to this session when it was first created.
-     */
-    private final int mInitialVerificationPolicy;
-    /**
-     * The active verification policy, which might be different from the initial verification policy
-     * assigned to this session or the default policy currently used by the system.
-     */
-    private final AtomicInteger mCurrentVerificationPolicy;
-    /**
      * Note all calls must be done outside {@link #mLock} to prevent lock inversion.
      */
     private final StagingManager mStagingManager;
-    @NonNull private final VerifierController mVerifierController;
 
     private final InstallDependencyHelper mInstallDependencyHelper;
 
@@ -812,8 +785,7 @@
             if (errorMsg != null) {
                 Slog.e(TAG, "verifySession error: " + errorMsg);
                 setSessionFailed(INSTALL_FAILED_INTERNAL_ERROR, errorMsg);
-                onSessionVerificationFailure(INSTALL_FAILED_INTERNAL_ERROR, errorMsg,
-                        /* extras= */ null);
+                onSessionVerificationFailure(INSTALL_FAILED_INTERNAL_ERROR, errorMsg);
                 return false;
             }
             return true;
@@ -1092,6 +1064,12 @@
         final boolean isInstallDpcPackagesPermissionGranted = (snapshot.checkUidPermission(
                 android.Manifest.permission.INSTALL_DPC_PACKAGES, mInstallerUid)
                 == PackageManager.PERMISSION_GRANTED);
+        boolean isInstallDependencyPackagesPermissionGranted = false;
+        if (Flags.sdkDependencyInstaller()) {
+            isInstallDependencyPackagesPermissionGranted = (snapshot.checkUidPermission(
+                    android.Manifest.permission.INSTALL_DEPENDENCY_SHARED_LIBRARIES, mInstallerUid)
+                    == PackageManager.PERMISSION_GRANTED);
+        }
         // Also query the package uid for archived packages, so that the user confirmation
         // dialog can be displayed for updating archived apps.
         final int targetPackageUid = snapshot.getPackageUid(packageName,
@@ -1113,10 +1091,18 @@
         final boolean isSelfUpdate = targetPackageUid == mInstallerUid;
         final boolean isEmergencyInstall =
                 isEmergencyInstallerEnabled(packageName, snapshot, userId, mInstallerUid);
+        boolean isSdkOrStaticLibraryInstall = false;
+        synchronized (mLock) {
+            if (mPackageLite != null) {
+                isSdkOrStaticLibraryInstall =
+                        mPackageLite.isIsSdkLibrary() || mPackageLite.isIsStaticLibrary();
+            }
+        }
         final boolean isPermissionGranted = isInstallPermissionGranted
                 || (isUpdatePermissionGranted && isUpdate)
                 || (isSelfUpdatePermissionGranted && isSelfUpdate)
-                || (isInstallDpcPackagesPermissionGranted && hasDeviceAdminReceiver);
+                || (isInstallDpcPackagesPermissionGranted && hasDeviceAdminReceiver)
+                || (isInstallDependencyPackagesPermissionGranted && isSdkOrStaticLibraryInstall);
         final boolean isInstallerRoot = (mInstallerUid == Process.ROOT_UID);
         final boolean isInstallerSystem = (mInstallerUid == Process.SYSTEM_UID);
         final boolean isInstallerShell = (mInstallerUid == Process.SHELL_UID);
@@ -1189,9 +1175,6 @@
             @Nullable int[] childSessionIds, int parentSessionId, boolean isReady,
             boolean isFailed, boolean isApplied, int sessionErrorCode,
             String sessionErrorMessage, DomainSet preVerifiedDomains,
-            @NonNull VerifierController verifierController,
-            @PackageInstaller.VerificationPolicy int initialVerificationPolicy,
-            @PackageInstaller.VerificationPolicy int currentVerificationPolicy,
             InstallDependencyHelper installDependencyHelper) {
         mCallback = callback;
         mContext = context;
@@ -1201,9 +1184,6 @@
         mSilentUpdatePolicy = silentUpdatePolicy;
         mHandler = new Handler(looper, mHandlerCallback);
         mStagingManager = stagingManager;
-        mVerifierController = verifierController;
-        mInitialVerificationPolicy = initialVerificationPolicy;
-        mCurrentVerificationPolicy = new AtomicInteger(currentVerificationPolicy);
         mInstallDependencyHelper = installDependencyHelper;
 
         this.sessionId = sessionId;
@@ -1289,14 +1269,6 @@
                         "Archived installation can only use Streaming System DataLoader.");
             }
         }
-
-        if (shouldUseVerificationService()) {
-            // Start binding to the verification service, if not bound already.
-            mVerifierController.bindToVerifierServiceIfNeeded(mPm::snapshotComputer, userId);
-            if (!TextUtils.isEmpty(params.appPackageName)) {
-                mVerifierController.notifyPackageNameAvailable(params.appPackageName);
-            }
-        }
     }
 
     PackageInstallerHistoricalSession createHistoricalSession() {
@@ -1314,8 +1286,7 @@
                     mStageDirInUse, mDestroyed, mFds.size(), mBridges.size(), mFinalStatus,
                     mFinalMessage, params, mParentSessionId, getChildSessionIdsLocked(),
                     mSessionApplied, mSessionFailed, mSessionReady, mSessionErrorCode,
-                    mSessionErrorMessage, mPreapprovalDetails, mPreVerifiedDomains, mPackageName,
-                    mInitialVerificationPolicy, mCurrentVerificationPolicy.get());
+                    mSessionErrorMessage, mPreapprovalDetails, mPreVerifiedDomains, mPackageName);
         }
     }
 
@@ -2610,10 +2581,10 @@
         dispatchSessionFinished(error, detailMessage, null);
     }
 
-    private void onSessionVerificationFailure(int error, String msg, Bundle extras) {
+    private void onSessionVerificationFailure(int error, String msg) {
         Slog.e(TAG, "Failed to verify session " + sessionId);
         // Dispatch message to remove session from PackageInstallerService.
-        dispatchSessionFinished(error, msg, extras);
+        dispatchSessionFinished(error, msg, null);
         maybeFinishChildSessions(error, msg);
     }
 
@@ -2893,60 +2864,9 @@
             final String completeMsg = ExceptionUtils.getCompleteMessage(e);
             final String errorMsg = PackageManager.installStatusToString(e.error, completeMsg);
             setSessionFailed(e.error, errorMsg);
-            onSessionVerificationFailure(e.error, errorMsg, /* extras= */ null);
+            onSessionVerificationFailure(e.error, errorMsg);
         }
-        if (shouldUseVerificationService()) {
-            final SigningInfo signingInfo;
-            final List<SharedLibraryInfo> declaredLibraries;
-            synchronized (mLock) {
-                signingInfo = new SigningInfo(mSigningDetails);
-                declaredLibraries =
-                        mPackageLite == null ? null : mPackageLite.getDeclaredLibraries();
-            }
-            // Send the request to the verifier and wait for its response before the rest of
-            // the installation can proceed.
-            final VerifierCallback verifierCallback = new VerifierCallback();
-            if (!mVerifierController.startVerificationSession(mPm::snapshotComputer, userId,
-                    sessionId, getPackageName(), Uri.fromFile(stageDir), signingInfo,
-                    declaredLibraries, mCurrentVerificationPolicy.get(),
-                    /* extensionParams= */ null, verifierCallback, /* retry= */ false)) {
-                // A verifier is installed but cannot be connected.
-                verifierCallback.onConnectionFailed();
-            }
-        } else {
-            // No need to check with verifier. Proceed with the rest of the verification.
-            resumeVerify();
-        }
-    }
 
-    private boolean shouldUseVerificationService() {
-        if (!Flags.verificationService()) {
-            // Feature is not enabled.
-            return false;
-        }
-        if ((params.installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
-            // adb installs are exempted from verification unless explicitly requested
-            if (!params.forceVerification) {
-                return false;
-            }
-        }
-        final String verifierPackageName = mVerifierController.getVerifierPackageName(
-                mPm::snapshotComputer, userId);
-        if (verifierPackageName == null) {
-            // Feature is enabled but no verifier installed.
-            return false;
-        }
-        synchronized (mLock) {
-            if (verifierPackageName.equals(mPackageName)) {
-                // The verifier itself is being updated. Skip.
-                Slog.w(TAG, "Skipping verification service because the verifier is being updated");
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private void resumeVerify() {
         if (mVerificationInProgress) {
             Slog.w(TAG, "Verification is already in progress for session " + sessionId);
             return;
@@ -2975,143 +2895,10 @@
             final String completeMsg = ExceptionUtils.getCompleteMessage(e);
             final String errorMsg = PackageManager.installStatusToString(e.error, completeMsg);
             setSessionFailed(e.error, errorMsg);
-            onSessionVerificationFailure(e.error, errorMsg, /* extras= */ null);
+            onSessionVerificationFailure(e.error, errorMsg);
         }
     }
 
-    /**
-     * Used for the VerifierController to report status back.
-     */
-    public class VerifierCallback {
-        /**
-         * Called by the VerifierController when the verifier requests to get the current
-         * verification policy for this session.
-         */
-        public @PackageInstaller.VerificationPolicy int getVerificationPolicy() {
-            return mCurrentVerificationPolicy.get();
-        }
-        /**
-         * Called by the VerifierController when the verifier requests to change the verification
-         * policy for this session.
-         */
-        public boolean setVerificationPolicy(@PackageInstaller.VerificationPolicy int policy) {
-            if (!isValidVerificationPolicy(policy)) {
-                return false;
-            }
-            mCurrentVerificationPolicy.set(policy);
-            return true;
-        }
-        /**
-         * Called by the VerifierController when the connection has failed.
-         */
-        public void onConnectionFailed() {
-            // TODO(b/360129657): prompt user on fail warning
-            handleNonPackageBlockedFailure(
-                    /* onFailWarning= */ PackageInstallerSession.this::resumeVerify,
-                    /* onFailClosed= */ () -> {
-                        Bundle bundle = new Bundle();
-                        bundle.putInt(EXTRA_VERIFICATION_FAILURE_REASON,
-                                VERIFICATION_FAILED_REASON_UNKNOWN);
-                        onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
-                                "A verifier agent is available on device but cannot be connected.",
-                                bundle);
-                    });
-        }
-        /**
-         * Called by the VerifierController when the verification request has timed out.
-         */
-        public void onTimeout() {
-            // Always notify the verifier, regardless of the policy.
-            mVerifierController.notifyVerificationTimeout(sessionId);
-            // TODO(b/360129657): prompt user on fail warning
-            handleNonPackageBlockedFailure(
-                    /* onFailWarning= */ PackageInstallerSession.this::resumeVerify,
-                    /* onFailClosed= */ () -> {
-                        Bundle bundle = new Bundle();
-                        bundle.putInt(EXTRA_VERIFICATION_FAILURE_REASON,
-                                VERIFICATION_FAILED_REASON_UNKNOWN);
-                        onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
-                                "Verification timed out; missing a response from the verifier"
-                                        + " within the time limit", bundle);
-                    });
-        }
-        /**
-         * Called by the VerifierController when the verification request has received a complete
-         * response.
-         */
-        public void onVerificationCompleteReceived(@NonNull VerificationStatus statusReceived,
-                @Nullable PersistableBundle extensionResponse) {
-            // TODO: handle extension response
-            mHandler.post(() -> {
-                if (statusReceived.isVerified()
-                        || mCurrentVerificationPolicy.get() == VERIFICATION_POLICY_NONE) {
-                    // Continue with the rest of the verification and installation.
-                    resumeVerify();
-                    return;
-                }
-                // Package is blocked.
-                StringBuilder sb = new StringBuilder("Verifier rejected the installation");
-                if (!TextUtils.isEmpty(statusReceived.getFailureMessage())) {
-                    sb.append(" with message: ").append(statusReceived.getFailureMessage());
-                }
-                Bundle bundle = new Bundle();
-                bundle.putInt(EXTRA_VERIFICATION_FAILURE_REASON,
-                        VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED);
-                onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
-                        sb.toString(), bundle);
-            });
-        }
-        /**
-         * Called by the VerifierController when the verification request has received an incomplete
-         * response.
-         */
-        public void onVerificationIncompleteReceived(int incompleteReason) {
-            // TODO(b/360129657): prompt user on fail warning
-            handleNonPackageBlockedFailure(
-                    /* onFailWarning= */ PackageInstallerSession.this::resumeVerify,
-                    /* onFailClosed= */ () -> {
-                        final int failureReason;
-                        StringBuilder sb = new StringBuilder(
-                                "Verification cannot be completed because of ");
-                        if (incompleteReason == VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE) {
-                            failureReason = VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE;
-                            sb.append("unavailable network.");
-                        } else {
-                            failureReason = VERIFICATION_FAILED_REASON_UNKNOWN;
-                            sb.append("unknown reasons.");
-                        }
-                        Bundle bundle = new Bundle();
-                        bundle.putInt(EXTRA_VERIFICATION_FAILURE_REASON, failureReason);
-                        onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
-                                sb.toString(), bundle);
-                    });
-        }
-
-        private void handleNonPackageBlockedFailure(Runnable onFailWarning, Runnable onFailClosed) {
-            final Runnable r = switch (mCurrentVerificationPolicy.get()) {
-                case VERIFICATION_POLICY_NONE, VERIFICATION_POLICY_BLOCK_FAIL_OPEN ->
-                        PackageInstallerSession.this::resumeVerify;
-                case VERIFICATION_POLICY_BLOCK_FAIL_WARN -> onFailWarning;
-                case VERIFICATION_POLICY_BLOCK_FAIL_CLOSED -> onFailClosed;
-                default -> {
-                    Log.wtf(TAG, "Unknown verification policy: "
-                            + mCurrentVerificationPolicy.get());
-                    yield onFailClosed;
-                }
-            };
-            mHandler.post(r);
-        }
-    }
-
-    /**
-     * Returns whether a policy is a valid verification policy.
-     */
-    public static boolean isValidVerificationPolicy(
-            @PackageInstaller.VerificationPolicy int policy) {
-        return policy >= VERIFICATION_POLICY_NONE
-                && policy <= VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-    }
-
     private IntentSender getRemoteStatusReceiver() {
         synchronized (mLock) {
             return mRemoteStatusReceiver;
@@ -3287,7 +3074,7 @@
                 if (error == INSTALL_SUCCEEDED) {
                     onVerificationComplete();
                 } else {
-                    onSessionVerificationFailure(error, msg, /* extras= */ null);
+                    onSessionVerificationFailure(error, msg);
                 }
             });
         });
@@ -5486,23 +5273,6 @@
         }
     }
 
-    /**
-     * @return the initial policy for the verification request assigned to the session when created.
-     */
-    @VisibleForTesting
-    public @PackageInstaller.VerificationPolicy int getInitialVerificationPolicy() {
-        assertCallerIsOwnerOrRoot();
-        return mInitialVerificationPolicy;
-    }
-
-    /**
-     * @return the current policy for the verification request associated with this session.
-     */
-    @VisibleForTesting
-    public @PackageInstaller.VerificationPolicy int getCurrentVerificationPolicy() {
-        assertCallerIsOwnerOrRoot();
-        return mCurrentVerificationPolicy.get();
-    }
 
     void setSessionReady() {
         synchronized (mLock) {
@@ -5673,14 +5443,6 @@
             }
         } catch (InstallerException ignored) {
         }
-        if (shouldUseVerificationService()
-                && !TextUtils.isEmpty(params.appPackageName)
-                && !isCommitted()) {
-            // Only notify for the cancellation if the verification request has not
-            // been sent out, which happens right after commit() is called.
-            mVerifierController.notifyVerificationCancelled(
-                    params.appPackageName);
-        }
     }
 
     void dump(IndentingPrintWriter pw) {
@@ -5741,8 +5503,6 @@
         if (mPreVerifiedDomains != null) {
             pw.printPair("mPreVerifiedDomains", mPreVerifiedDomains);
         }
-        pw.printPair("mInitialVerificationPolicy", mInitialVerificationPolicy);
-        pw.printPair("mCurrentVerificationPolicy", mCurrentVerificationPolicy.get());
         pw.println();
 
         pw.decreaseIndent();
@@ -5808,10 +5568,6 @@
             if (!ArrayUtils.isEmpty(warnings)) {
                 fillIn.putStringArrayListExtra(PackageInstaller.EXTRA_WARNINGS, warnings);
             }
-            if (extras.containsKey(EXTRA_VERIFICATION_FAILURE_REASON)) {
-                fillIn.putExtra(EXTRA_VERIFICATION_FAILURE_REASON,
-                        extras.getInt(EXTRA_VERIFICATION_FAILURE_REASON));
-            }
         }
         try {
             final BroadcastOptions options = BroadcastOptions.makeBasic();
@@ -5967,9 +5723,6 @@
             out.attributeInt(null, ATTR_INSTALL_REASON, params.installReason);
             writeBooleanAttribute(out, ATTR_APPLICATION_ENABLED_SETTING_PERSISTENT,
                     params.applicationEnabledSettingPersistent);
-            out.attributeInt(null, ATTR_INITIAL_VERIFICATION_POLICY, mInitialVerificationPolicy);
-            out.attributeInt(null, ATTR_CURRENT_VERIFICATION_POLICY,
-                    mCurrentVerificationPolicy.get());
 
             final boolean isDataLoader = params.dataLoaderParams != null;
             writeBooleanAttribute(out, ATTR_IS_DATALOADER, isDataLoader);
@@ -6090,7 +5843,6 @@
             @NonNull StagingManager stagingManager, @NonNull File sessionsDir,
             @NonNull PackageSessionProvider sessionProvider,
             @NonNull SilentUpdatePolicy silentUpdatePolicy,
-            @NonNull VerifierController verifierController,
             @NonNull InstallDependencyHelper installDependencyHelper)
             throws IOException, XmlPullParserException {
         final int sessionId = in.getAttributeInt(null, ATTR_SESSION_ID);
@@ -6121,10 +5873,6 @@
         final boolean sealed = in.getAttributeBoolean(null, ATTR_SEALED, false);
         final int parentSessionId = in.getAttributeInt(null, ATTR_PARENT_SESSION_ID,
                 SessionInfo.INVALID_ID);
-        final int initialVerificationPolicy = in.getAttributeInt(null,
-                ATTR_INITIAL_VERIFICATION_POLICY, VERIFICATION_POLICY_NONE);
-        final int currentVerificationPolicy = in.getAttributeInt(null,
-                ATTR_CURRENT_VERIFICATION_POLICY, VERIFICATION_POLICY_NONE);
 
         final SessionParams params = new SessionParams(
                 SessionParams.MODE_INVALID);
@@ -6299,7 +6047,7 @@
                 installerUid, installSource, params, createdMillis, committedMillis, stageDir,
                 stageCid, fileArray, checksumsMap, prepared, committed, destroyed, sealed,
                 childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied,
-                sessionErrorCode, sessionErrorMessage, preVerifiedDomains, verifierController,
-                initialVerificationPolicy, currentVerificationPolicy, installDependencyHelper);
+                sessionErrorCode, sessionErrorMessage, preVerifiedDomains,
+                installDependencyHelper);
     }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9d48efe9..040b194 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2118,7 +2118,8 @@
         mDeletePackageHelper = new DeletePackageHelper(this, mRemovePackageHelper,
                 mBroadcastHelper);
         mInstallPackageHelper = new InstallPackageHelper(this, mAppDataHelper, mRemovePackageHelper,
-                mDeletePackageHelper, mBroadcastHelper);
+                mDeletePackageHelper, mBroadcastHelper,
+                injector.getPackageInstallerService().getInstallDependencyHelper());
 
         mInstantAppRegistry = new InstantAppRegistry(mContext, mPermissionManager,
                 mInjector.getUserManagerInternal(), mDeletePackageHelper);
@@ -4421,7 +4422,6 @@
             mPendingBroadcasts.remove(userId);
             mAppsFilter.onUserDeleted(snapshotComputer(), userId);
             mPermissionManager.onUserRemoved(userId);
-            mInstallerService.onUserRemoved(userId);
         }
         mInstantAppRegistry.onUserRemoved(userId);
         mPackageMonitorCallbackHelper.onUserRemoved(userId);
@@ -4472,7 +4472,6 @@
             mLegacyPermissionManager.grantDefaultPermissions(userId);
             mPermissionManager.setDefaultPermissionGrantFingerprint(Build.FINGERPRINT, userId);
             mDomainVerificationManager.clearUser(userId);
-            mInstallerService.onUserAdded(userId);
         }
     }
 
@@ -5876,6 +5875,67 @@
                     userId, callingPackage);
         }
 
+        @Override
+        public void setPageSizeAppCompatFlagsSettingsOverride(String packageName, boolean enabled) {
+            final int callingUid = Binder.getCallingUid();
+            final int callingAppId = UserHandle.getAppId(callingUid);
+
+            if (!PackageManagerServiceUtils.isSystemOrRoot(callingAppId)) {
+                throw new SecurityException("Caller must be the system or root.");
+            }
+
+            int settingsMode = enabled
+                    ? ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_ENABLED
+                    : ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_DISABLED;
+            PackageStateMutator.Result result =
+                    commitPackageStateMutation(
+                            null,
+                            packageName,
+                            packageState ->
+                                    packageState
+                                            .setPageSizeAppCompatFlags(settingsMode));
+            if (result.isSpecificPackageNull()) {
+                throw new IllegalArgumentException("Unknown package: " + packageName);
+            }
+            scheduleWriteSettings();
+        }
+
+        @Override
+        public boolean isPageSizeCompatEnabled(String packageName) {
+            final int callingUid = Binder.getCallingUid();
+            final int callingAppId = UserHandle.getAppId(callingUid);
+            final int userId = UserHandle.getCallingUserId();
+
+            if (!PackageManagerServiceUtils.isSystemOrRoot(callingAppId)) {
+                throw new SecurityException("Caller must be the system or root.");
+            }
+
+            PackageStateInternal packageState =
+                    snapshotComputer().getPackageStateForInstalledAndFiltered(
+                            packageName, callingUid, userId);
+
+            return packageState == null ? false : packageState.isPageSizeAppCompatEnabled();
+        }
+
+        @Override
+        public String getPageSizeCompatWarningMessage(String packageName) {
+            final int callingUid = Binder.getCallingUid();
+            final int callingAppId = UserHandle.getAppId(callingUid);
+            final int userId = UserHandle.getCallingUserId();
+
+            if (!PackageManagerServiceUtils.isSystemOrRoot(callingAppId)) {
+                throw new SecurityException("Caller must be the system or root.");
+            }
+
+            PackageStateInternal packageState =
+                    snapshotComputer().getPackageStateForInstalledAndFiltered(
+                            packageName, callingUid, userId);
+
+            return packageState == null
+                    ? null
+                    : packageState.getPageSizeCompatWarningMessage(mContext);
+        }
+
         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_USERS)
         @Override
         public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
@@ -6580,6 +6640,20 @@
         }
 
         @Override
+        @NonNull
+        public List<String> getAllApexDirectories() {
+            PackageManagerServiceUtils.enforceSystemOrRoot(
+                    "getAllApexDirectories can only be called by system or root");
+            List<String> apexDirectories = new ArrayList<>();
+            List<ApexManager.ActiveApexInfo> apexes = mApexManager.getActiveApexInfos();
+            for (int i = 0; i < apexes.size(); i++) {
+                ApexManager.ActiveApexInfo apex = apexes.get(i);
+                apexDirectories.add(apex.apexDirectory.getAbsolutePath());
+            }
+            return apexDirectories;
+        }
+
+        @Override
         public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
                 throws RemoteException {
             try {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 961b4b3c..aa235c2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -399,10 +399,6 @@
                     return runUnarchive();
                 case "get-domain-verification-agent":
                     return runGetDomainVerificationAgent();
-                case "get-verification-policy":
-                    return runGetVerificationPolicy();
-                case "set-verification-policy":
-                    return runSetVerificationPolicy();
                 default: {
                     if (ART_SERVICE_COMMANDS.contains(cmd)) {
                         return runArtServiceCommand();
@@ -3603,12 +3599,9 @@
                             .setCompilerFilter(sessionParams.dexoptCompilerFilter)
                             .build();
                     break;
-                case "--force-verification":
-                    sessionParams.setForceVerification();
-                    break;
                 case "--disable-auto-install-dependencies":
                     if (Flags.sdkDependencyInstaller()) {
-                        sessionParams.setEnableAutoInstallDependencies(false);
+                        sessionParams.setAutoInstallDependenciesEnabled(false);
                     } else {
                         throw new IllegalArgumentException("Unknown option " + opt);
                     }
@@ -4656,87 +4649,6 @@
         return 0;
     }
 
-    private int runGetVerificationPolicy() throws RemoteException {
-        final PrintWriter pw = getOutPrintWriter();
-        int userId = UserHandle.USER_ALL;
-
-        String opt;
-        while ((opt = getNextOption()) != null) {
-            if (opt.equals("--user")) {
-                userId = UserHandle.parseUserArg(getNextArgRequired());
-                if (userId != UserHandle.USER_ALL && userId != UserHandle.USER_CURRENT) {
-                    UserManagerInternal umi =
-                            LocalServices.getService(UserManagerInternal.class);
-                    UserInfo userInfo = umi.getUserInfo(userId);
-                    if (userInfo == null) {
-                        pw.println("Failure [user " + userId + " doesn't exist]");
-                        return 1;
-                    }
-                }
-            } else {
-                pw.println("Error: Unknown option: " + opt);
-                return 1;
-            }
-        }
-        final int translatedUserId =
-                translateUserId(userId, UserHandle.USER_SYSTEM, "runGetVerificationPolicy");
-        try {
-            final IPackageInstaller installer = mInterface.getPackageInstaller();
-            // TODO(b/360129657): global verification policy should be per user
-            final int policy = installer.getVerificationPolicy(translatedUserId);
-            pw.println(policy);
-        } catch (Exception e) {
-            pw.println("Failure [" + e.getMessage() + "]");
-            return 1;
-        }
-        return 0;
-    }
-
-    private int runSetVerificationPolicy() throws RemoteException {
-        final PrintWriter pw = getOutPrintWriter();
-        int userId = UserHandle.USER_ALL;
-
-        String opt;
-        while ((opt = getNextOption()) != null) {
-            if (opt.equals("--user")) {
-                userId = UserHandle.parseUserArg(getNextArgRequired());
-                if (userId != UserHandle.USER_ALL && userId != UserHandle.USER_CURRENT) {
-                    UserManagerInternal umi =
-                            LocalServices.getService(UserManagerInternal.class);
-                    UserInfo userInfo = umi.getUserInfo(userId);
-                    if (userInfo == null) {
-                        pw.println("Failure [user " + userId + " doesn't exist]");
-                        return 1;
-                    }
-                }
-            } else {
-                pw.println("Error: Unknown option: " + opt);
-                return 1;
-            }
-        }
-        final String policyStr = getNextArg();
-        if (policyStr == null) {
-            pw.println("Error: policy not specified");
-            return 1;
-        }
-        final int translatedUserId =
-                translateUserId(userId, UserHandle.USER_SYSTEM, "runSetVerificationPolicy");
-        try {
-            final IPackageInstaller installer = mInterface.getPackageInstaller();
-            // TODO(b/360129657): global verification policy should be per user
-            final boolean success = installer.setVerificationPolicy(Integer.parseInt(policyStr),
-                    translatedUserId);
-            if (!success) {
-                pw.println("Failure setting verification policy.");
-                return 1;
-            }
-        } catch (Exception e) {
-            pw.println("Failure [" + e.getMessage() + "]");
-            return 1;
-        }
-        return 0;
-    }
-
     @Override
     public void onHelp() {
         final PrintWriter pw = getOutPrintWriter();
@@ -4900,7 +4812,6 @@
         pw.println("          https://source.android.com/docs/core/runtime/configure"
                 + "#compiler_filters");
         pw.println("          or 'skip'");
-        pw.println("      --force-verification: if set, enable the verification for this install");
         if (Flags.sdkDependencyInstaller()) {
             pw.println("      --disable-auto-install-dependencies: if set, any missing shared");
             pw.println("          library dependencies will not be auto-installed");
@@ -5169,14 +5080,6 @@
         pw.println("      --user: return the agent of the given user (SYSTEM_USER if unspecified)");
         pw.println("  get-package-storage-stats [--user <USER_ID>] <PACKAGE>");
         pw.println("    Return the storage stats for the given app, if present");
-        pw.println("  get-verification-policy [--user USER_ID]");
-        pw.println("    Display current verification enforcement policy which will be applied to");
-        pw.println("    all the future installation sessions");
-        pw.println("      --user: show the policy of the given user (SYSTEM_USER if unspecified)");
-        pw.println("  set-verification-policy POLICY [--user USER_ID]");
-        pw.println("    Sets the verification policy of all the future installation sessions.");
-        pw.println("      --user: set the policy of the given user (SYSTEM_USER if unspecified)");
-        pw.println("");
         pw.println("");
         printArtServiceHelp();
         pw.println("");
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 9428de7..fb16b86 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -27,6 +27,7 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.SharedLibraryInfo;
@@ -221,6 +222,8 @@
     /** @see PackageState#getCategoryOverride() */
     private int categoryOverride = ApplicationInfo.CATEGORY_UNDEFINED;
 
+    private int mPageSizeAppCompatFlags = ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED;
+
     @NonNull
     private final PackageStateUnserialized pkgState = new PackageStateUnserialized(this);
 
@@ -863,6 +866,8 @@
         }
 
         copyMimeGroups(other.mimeGroups);
+        mPageSizeAppCompatFlags = other.mPageSizeAppCompatFlags;
+
         pkgState.updateFrom(other.pkgState);
         onChanged();
     }
@@ -1617,6 +1622,34 @@
         return this;
     }
 
+    /**
+     * @see Set page size app compat mode.
+     */
+    public PackageSetting setPageSizeAppCompatFlags(int mode) {
+        if (mode < 0 || mode >= ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MAX) {
+            throw new IllegalArgumentException("Invalid page size compat mode specified");
+        }
+
+        // OR assignment is used here to avoid overriding the mode set by the manifest.
+        this.mPageSizeAppCompatFlags |= mode;
+
+        // Only one bit of the following can be set at same time. Both are needed to detect app
+        // compat 'disabled' state from settings vs bit was never set.
+        if (ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_ENABLED == mode) {
+            this.mPageSizeAppCompatFlags &=
+                    ~ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_DISABLED;
+        } else if (ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_DISABLED == mode) {
+            this.mPageSizeAppCompatFlags &=
+                    ~ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_ENABLED;
+        }
+        onChanged();
+        return this;
+    }
+
+    public int getPageSizeAppCompatFlags() {
+        return mPageSizeAppCompatFlags;
+    }
+
     public PackageSetting setLegacyNativeLibraryPath(
             String legacyNativeLibraryPathString) {
         this.legacyNativeLibraryPath = legacyNativeLibraryPathString;
@@ -1787,6 +1820,63 @@
         return getBoolean(Booleans.SCANNED_AS_STOPPED_SYSTEM_APP);
     }
 
+    /** Returns true if ELF files will be loaded in Page size compatibility mode */
+    @Override
+    public boolean isPageSizeAppCompatEnabled() {
+        // If manifest or settings has disabled the compat mode, don't run app in compat mode.
+        boolean manifestOverrideDisabled = (mPageSizeAppCompatFlags
+                &  ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_DISABLED) != 0;
+        boolean settingsOverrideDisabled = (mPageSizeAppCompatFlags
+                &  ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_DISABLED) != 0;
+        if (manifestOverrideDisabled || settingsOverrideDisabled) {
+            return false;
+        }
+
+        int mask =
+                ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_ELF_NOT_ALIGNED
+                        | ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_ENABLED
+                        | ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_SETTINGS_OVERRIDE_ENABLED;
+        return (mPageSizeAppCompatFlags & mask) != 0;
+    }
+
+    /**
+     * Returns dialog string based on alignment of uncompressed shared libs inside the APK and ELF
+     * alignment.
+     */
+    @Override
+    public String getPageSizeCompatWarningMessage(Context context) {
+        boolean manifestOverrideEnabled =  (mPageSizeAppCompatFlags
+                & ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_ENABLED) != 0;
+        boolean settingsOverrideEnabled =  (mPageSizeAppCompatFlags
+                & ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_ENABLED) != 0;
+        if (manifestOverrideEnabled || settingsOverrideEnabled) {
+            return null;
+        }
+
+        boolean uncompressedLibsNotAligned = (mPageSizeAppCompatFlags
+                & ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNCOMPRESSED_LIBS_NOT_ALIGNED) != 0;
+        boolean elfNotAligned = (mPageSizeAppCompatFlags
+                & ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_ELF_NOT_ALIGNED) != 0;
+
+        if (uncompressedLibsNotAligned && elfNotAligned) {
+            return context.getText(
+                            com.android.internal.R.string.page_size_compat_apk_and_elf_warning)
+                    .toString();
+        }
+
+        if (uncompressedLibsNotAligned) {
+            return context.getText(com.android.internal.R.string.page_size_compat_apk_warning)
+                    .toString();
+        }
+
+        if (elfNotAligned) {
+            return context.getText(com.android.internal.R.string.page_size_compat_elf_warning)
+                    .toString();
+        }
+
+        return null;
+    }
+
 
 
     // Code below generated by codegen v1.0.23.
@@ -1952,7 +2042,6 @@
     @Deprecated
     private void __metadata() {}
 
-
     //@formatter:on
     // End of generated code
 
diff --git a/services/core/java/com/android/server/pm/SaferIntentUtils.java b/services/core/java/com/android/server/pm/SaferIntentUtils.java
index bc36fab..854e142 100644
--- a/services/core/java/com/android/server/pm/SaferIntentUtils.java
+++ b/services/core/java/com/android/server/pm/SaferIntentUtils.java
@@ -26,6 +26,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
 import android.compat.annotation.EnabledAfter;
 import android.compat.annotation.Overridable;
 import android.content.Intent;
@@ -88,6 +89,22 @@
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
     private static final long IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS = 229362273;
 
+    /**
+     * Intents sent from apps enabling this feature will stop resolving to components with
+     * non matching intent filters, even when explicitly setting a component name, unless the
+     * target components are in the same app as the calling app.
+     * <p>
+     * When an app registers an exported component in its manifest and adds &lt;intent-filter&gt;s,
+     * the component can be started by any intent - even those that do not match the intent filter.
+     * This has proven to be something that many developers find counterintuitive.
+     * Without checking the intent when the component is started, in some circumstances this can
+     * allow 3P apps to trigger internal-only functionality.
+     */
+    @ChangeId
+    @Overridable
+    @Disabled
+    private static final long ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS = 161252188;
+
     @Nullable
     private static ParsedMainComponent infoToComponent(
             ComponentInfo info, ComponentResolverApi resolver, boolean isReceiver) {
@@ -249,6 +266,20 @@
      */
     public static void enforceIntentFilterMatching(
             IntentArgs args, List<ResolveInfo> resolveInfos) {
+        // Switch to the new intent matching logic if the feature flag is enabled.
+        // Otherwise, use the existing AppCompat based implementation.
+        if (Flags.enableIntentMatchingFlags()) {
+            enforceIntentFilterMatchingWithIntentMatchingFlags(args, resolveInfos);
+        } else {
+            enforceIntentFilterMatchingWithAppCompat(args, resolveInfos);
+        }
+    }
+
+    /**
+     * This version of the method is implemented in Android B and uses "IntentMatchingFlags"
+     */
+    private static void enforceIntentFilterMatchingWithIntentMatchingFlags(
+                IntentArgs args, List<ResolveInfo> resolveInfos) {
         if (DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.get()) return;
 
         // Do not enforce filter matching when the caller is system or root
@@ -339,6 +370,97 @@
     }
 
     /**
+     * This version of the method is implemented in Android V and uses "AppCompat"
+     */
+    private static void enforceIntentFilterMatchingWithAppCompat(
+            IntentArgs args, List<ResolveInfo> resolveInfos) {
+        if (DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.get()) return;
+
+        // Do not enforce filter matching when the caller is system or root
+        if (ActivityManager.canAccessUnexportedComponents(args.callingUid)) return;
+
+        final Computer computer = (Computer) args.snapshot;
+        final ComponentResolverApi resolver = computer.getComponentResolver();
+
+        final Printer logPrinter = DEBUG_INTENT_MATCHING
+                ? new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM)
+                : null;
+
+        final boolean enforceMatch = Flags.enforceIntentFilterMatch()
+                && args.isChangeEnabled(ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS);
+        final boolean blockNullAction = Flags.blockNullActionIntents()
+                && args.isChangeEnabled(IntentFilter.BLOCK_NULL_ACTION_INTENTS);
+
+        for (int i = resolveInfos.size() - 1; i >= 0; --i) {
+            final ComponentInfo info = resolveInfos.get(i).getComponentInfo();
+
+            // Skip filter matching when the caller is targeting the same app
+            if (UserHandle.isSameApp(args.callingUid, info.applicationInfo.uid)) {
+                continue;
+            }
+
+            final ParsedMainComponent comp = infoToComponent(info, resolver, args.isReceiver);
+
+            if (comp == null || comp.getIntents().isEmpty()) {
+                continue;
+            }
+
+            Boolean match = null;
+
+            if (args.intent.getAction() == null) {
+                args.reportEvent(
+                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH,
+                        enforceMatch && blockNullAction);
+                if (blockNullAction) {
+                    // Skip intent filter matching if blocking null action
+                    match = false;
+                }
+            }
+
+            if (match == null) {
+                // Check if any intent filter matches
+                for (int j = 0, size = comp.getIntents().size(); j < size; ++j) {
+                    IntentFilter intentFilter = comp.getIntents().get(j).getIntentFilter();
+                    if (IntentResolver.intentMatchesFilter(
+                            intentFilter, args.intent, args.resolvedType)) {
+                        match = true;
+                        break;
+                    }
+                }
+            }
+
+            // At this point, the value `match` has the following states:
+            // null : Intent does not match any intent filter
+            // false: Null action intent detected AND blockNullAction == true
+            // true : The intent matches at least one intent filter
+
+            if (match == null) {
+                args.reportEvent(
+                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH,
+                        enforceMatch);
+                match = false;
+            }
+
+            if (!match) {
+                // All non-matching intents has to be marked accordingly
+                if (Flags.enforceIntentFilterMatch()) {
+                    args.intent.addExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
+                }
+                if (enforceMatch) {
+                    Slog.w(TAG, "Intent does not match component's intent filter: " + args.intent);
+                    Slog.w(TAG, "Access blocked: " + comp.getComponentName());
+                    if (DEBUG_INTENT_MATCHING) {
+                        Slog.v(TAG, "Component intent filters:");
+                        comp.getIntents().forEach(f -> f.getIntentFilter().dump(logPrinter, "  "));
+                        Slog.v(TAG, "-----------------------------");
+                    }
+                    resolveInfos.remove(i);
+                }
+            }
+        }
+    }
+
+    /**
      * Filter non-exported components from the componentList if intent is implicit.
      * <p>
      * Implicit intents cannot be used to start Services since API 21+.
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 1f672a0..485a280 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3313,6 +3313,11 @@
         if (pkg.getBaseRevisionCode() != 0) {
             serializer.attributeInt(null, "baseRevisionCode", pkg.getBaseRevisionCode());
         }
+        if (pkg.getPageSizeAppCompatFlags()
+                != ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED) {
+            serializer.attributeInt(null, "pageSizeCompat", pkg.getPageSizeAppCompatFlags());
+        }
+
         serializer.attributeFloat(null, "loadingProgress", pkg.getLoadingProgress());
         serializer.attributeLongHex(null, "loadingCompletedTime", pkg.getLoadingCompletedTime());
 
@@ -4129,6 +4134,7 @@
         boolean isScannedAsStoppedSystemApp = false;
         boolean isSdkLibrary = false;
         int baseRevisionCode = 0;
+        int PageSizeCompat = 0;
         try {
             name = parser.getAttributeValue(null, ATTR_NAME);
             realName = parser.getAttributeValue(null, "realName");
@@ -4175,6 +4181,8 @@
             appMetadataSource = parser.getAttributeInt(null, "appMetadataSource",
                     PackageManager.APP_METADATA_SOURCE_UNKNOWN);
             baseRevisionCode = parser.getAttributeInt(null, "baseRevisionCode", 0);
+            PageSizeCompat = parser.getAttributeInt(null, "pageSizeCompat",
+                    ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED);
 
             isScannedAsStoppedSystemApp = parser.getAttributeBoolean(null,
                 "scannedAsStoppedSystemApp", false);
@@ -4330,7 +4338,8 @@
                     .setTargetSdkVersion(targetSdkVersion)
                     .setBaseRevisionCode(baseRevisionCode)
                     .setRestrictUpdateHash(restrictUpdateHash)
-                    .setScannedAsStoppedSystemApp(isScannedAsStoppedSystemApp);
+                    .setScannedAsStoppedSystemApp(isScannedAsStoppedSystemApp)
+                    .setPageSizeAppCompatFlags(PageSizeCompat);
             // Handle legacy string here for single-user mode
             final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
             if (enabledStr != null) {
@@ -5211,6 +5220,10 @@
                 pw.print(" (override=true)");
             }
             pw.println();
+            pw.print(prefix);
+            pw.print("  pageSizeCompat=");
+            pw.print(ps.getPageSizeAppCompatFlags());
+            pw.println();
             if (!ps.getPkg().getQueriesPackages().isEmpty()) {
                 pw.append(prefix).append("  queriesPackages=")
                         .println(ps.getPkg().getQueriesPackages());
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b2b8aaf..066fce0 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -6122,8 +6122,11 @@
             // If the user switch hasn't been explicitly toggled on or off by the user, turn it on.
             if (android.provider.Settings.Global.getString(mContext.getContentResolver(),
                     android.provider.Settings.Global.USER_SWITCHER_ENABLED) == null) {
-                android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                        android.provider.Settings.Global.USER_SWITCHER_ENABLED, 1);
+                if (Resources.getSystem().getBoolean(
+                        com.android.internal.R.bool.config_enableUserSwitcherUponUserCreation)) {
+                    android.provider.Settings.Global.putInt(mContext.getContentResolver(),
+                            android.provider.Settings.Global.USER_SWITCHER_ENABLED, 1);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/pkg/PackageState.java b/services/core/java/com/android/server/pm/pkg/PackageState.java
index bbc17c8..33fc066 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageState.java
@@ -22,6 +22,7 @@
 import android.annotation.Size;
 import android.annotation.SystemApi;
 import android.annotation.UserIdInt;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -198,6 +199,21 @@
     int getCategoryOverride();
 
     /**
+     * Returns true if ELF files will be loaded in Page size compatibility mode
+     *
+     * @hide
+     */
+    boolean isPageSizeAppCompatEnabled();
+
+    /**
+     * Returns dialog string based on alignment of uncompressed shared libs inside the APK and ELF
+     * alignment.
+     *
+     * @hide
+     */
+    String getPageSizeCompatWarningMessage(Context context);
+
+    /**
      * The install time CPU override, if any. This value is written at install time
      * and doesn't change during the life of an install. If non-null,
      * {@link #getPrimaryCpuAbiLegacy()} will also contain the same value.
diff --git a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java
index 253eb40..a46c4a6 100644
--- a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java
+++ b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java
@@ -257,6 +257,16 @@
 
         @NonNull
         @Override
+        public PackageStateWrite setPageSizeAppCompatFlags(
+                @ApplicationInfo.PageSizeAppCompatFlags int mode) {
+            if (mState != null) {
+                mState.setPageSizeAppCompatFlags(mode);
+            }
+            return this;
+        }
+
+        @NonNull
+        @Override
         public PackageStateWrite setUpdateAvailable(boolean updateAvailable) {
             if (mState != null) {
                 mState.setUpdateAvailable(updateAvailable);
diff --git a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java
index 55d96f3..f8f8695 100644
--- a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java
+++ b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java
@@ -46,6 +46,10 @@
     @NonNull
     PackageStateWrite setCategoryOverride(@ApplicationInfo.Category int category);
 
+    /** set 16Kb App compat mode. @see ApplicationInfo.PageSizeAppCompatFlags */
+    @NonNull
+    PackageStateWrite setPageSizeAppCompatFlags(@ApplicationInfo.PageSizeAppCompatFlags int mode);
+
     @NonNull
     PackageStateWrite setUpdateAvailable(boolean updateAvailable);
 
diff --git a/services/core/java/com/android/server/pm/verify/pkg/VerificationStatusTracker.java b/services/core/java/com/android/server/pm/verify/pkg/VerificationStatusTracker.java
deleted file mode 100644
index 67ac2a7..0000000
--- a/services/core/java/com/android/server/pm/verify/pkg/VerificationStatusTracker.java
+++ /dev/null
@@ -1,91 +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.server.pm.verify.pkg;
-
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * This class keeps record of the current timeout status of a verification request.
- */
-public final class VerificationStatusTracker {
-    private final @CurrentTimeMillisLong long mStartTime;
-    private @CurrentTimeMillisLong long mTimeoutTime;
-    private final @CurrentTimeMillisLong long mMaxTimeoutTime;
-    @NonNull
-    private final VerifierController.Injector mInjector;
-
-    /**
-     * By default, the timeout time is the default timeout duration plus the current time (when
-     * the timer starts for a verification request). Both the default timeout time and the max
-     * timeout time cannot be changed after the timer has started, but the actual timeout time
-     * can be extended via {@link #extendTimeRemaining} to the maximum allowed.
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
-    public VerificationStatusTracker(long defaultTimeoutMillis, long maxExtendedTimeoutMillis,
-            @NonNull VerifierController.Injector injector) {
-        mStartTime = injector.getCurrentTimeMillis();
-        mTimeoutTime = mStartTime + defaultTimeoutMillis;
-        mMaxTimeoutTime = mStartTime + maxExtendedTimeoutMillis;
-        mInjector = injector;
-    }
-
-    /**
-     * Used by the controller to inform the verifier agent about the timestamp when the verification
-     * request will timeout.
-     */
-    public @CurrentTimeMillisLong long getTimeoutTime() {
-        return mTimeoutTime;
-    }
-
-    /**
-     * Used by the controller to decide when to check for timeout again.
-     * @return 0 if the timeout time has been reached, otherwise the remaining time in milliseconds
-     * before the timeout is reached.
-     */
-    public @CurrentTimeMillisLong long getRemainingTime() {
-        final long remainingTime = mTimeoutTime - mInjector.getCurrentTimeMillis();
-        if (remainingTime < 0) {
-            return 0;
-        }
-        return remainingTime;
-    }
-
-    /**
-     * Used by the controller to extend the timeout duration of the verification request, upon
-     * receiving the callback from the verifier agent.
-     * @return the amount of time in millis that the timeout has been extended, subject to the max
-     * amount allowed.
-     */
-    public long extendTimeRemaining(@CurrentTimeMillisLong long additionalMs) {
-        if (mTimeoutTime + additionalMs > mMaxTimeoutTime) {
-            additionalMs = mMaxTimeoutTime - mTimeoutTime;
-        }
-        mTimeoutTime += additionalMs;
-        return additionalMs;
-    }
-
-    /**
-     * Used by the controller to get the timeout status of the request.
-     * @return False if the request still has some time left before timeout, otherwise return True.
-     */
-    public boolean isTimeout() {
-        return mInjector.getCurrentTimeMillis() >= mTimeoutTime;
-    }
-}
diff --git a/services/core/java/com/android/server/pm/verify/pkg/VerifierController.java b/services/core/java/com/android/server/pm/verify/pkg/VerifierController.java
deleted file mode 100644
index 78849d2..0000000
--- a/services/core/java/com/android/server/pm/verify/pkg/VerifierController.java
+++ /dev/null
@@ -1,721 +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.server.pm.verify.pkg;
-
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
-import static android.os.Process.INVALID_UID;
-import static android.os.Process.SYSTEM_UID;
-import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningInfo;
-import android.content.pm.verify.pkg.IVerificationSessionInterface;
-import android.content.pm.verify.pkg.IVerifierService;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.os.PersistableBundle;
-import android.os.Process;
-import android.os.UserHandle;
-import android.provider.DeviceConfig;
-import android.util.Pair;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.infra.AndroidFuture;
-import com.android.internal.infra.ServiceConnector;
-import com.android.server.pm.Computer;
-import com.android.server.pm.PackageInstallerSession;
-import com.android.server.pm.pkg.PackageStateInternal;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-/**
- * This class manages the bind to the verifier agent installed on the device that implements
- * {@link android.content.pm.verify.pkg.VerifierService} and handles all its interactions.
- */
-public class VerifierController {
-    private static final String TAG = "VerifierController";
-    private static final boolean DEBUG = false;
-
-    /**
-     * Configurable maximum amount of time in milliseconds to wait for a verifier to respond to
-     * a verification request.
-     * Flag type: {@code long}
-     * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
-     */
-    private static final String PROPERTY_VERIFICATION_REQUEST_TIMEOUT_MILLIS =
-            "verification_request_timeout_millis";
-    // Default duration to wait for a verifier to respond to a verification request.
-    private static final long DEFAULT_VERIFICATION_REQUEST_TIMEOUT_MILLIS =
-            TimeUnit.MINUTES.toMillis(1);
-    /**
-     * Configurable maximum amount of time in milliseconds that the verifier can request to extend
-     * the verification request timeout duration to. This is the maximum amount of time the system
-     * can wait for a request before it times out.
-     * Flag type: {@code long}
-     * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
-     */
-    private static final String PROPERTY_MAX_VERIFICATION_REQUEST_EXTENDED_TIMEOUT_MILLIS =
-            "max_verification_request_extended_timeout_millis";
-    // Max duration allowed to wait for a verifier to respond to a verification request.
-    private static final long DEFAULT_MAX_VERIFICATION_REQUEST_EXTENDED_TIMEOUT_MILLIS =
-            TimeUnit.MINUTES.toMillis(10);
-    /**
-     * Configurable maximum amount of time in milliseconds for the system to wait from the moment
-     * when the installation session requires a verification, till when the request is delivered to
-     * the verifier, pending the connection to be established. If the request has not been delivered
-     * to the verifier within this amount of time, e.g., because the verifier has crashed or ANR'd,
-     * the controller then sends a failure status back to the installation session.
-     * Flag type: {@code long}
-     * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
-     */
-    private static final String PROPERTY_VERIFIER_CONNECTION_TIMEOUT_MILLIS =
-            "verifier_connection_timeout_millis";
-    // The maximum amount of time to wait from the moment when the session requires a verification,
-    // till when the request is delivered to the verifier, pending the connection to be established.
-    private static final long DEFAULT_VERIFIER_CONNECTION_TIMEOUT_MILLIS =
-            TimeUnit.SECONDS.toMillis(10);
-
-    // The maximum amount of time to wait before the system unbinds from the verifier.
-    private static final long UNBIND_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(6);
-
-    private final Context mContext;
-    private final Handler mHandler;
-    // Guards the remote service object, as well as the verifier name and UID, which should all be
-    // changed at the same time.
-    private final Object mLock = new Object();
-    @Nullable
-    @GuardedBy("mLock")
-    private ServiceConnector<IVerifierService> mRemoteService;
-    @Nullable
-    @GuardedBy("mLock")
-    private ComponentName mRemoteServiceComponentName;
-    @GuardedBy("mLock")
-    private int mRemoteServiceUid = INVALID_UID;
-    @NonNull
-    private Injector mInjector;
-
-    // Repository of active verification sessions and their status, mapping from id to status.
-    @NonNull
-    @GuardedBy("mVerificationStatus")
-    private final SparseArray<VerificationStatusTracker> mVerificationStatus = new SparseArray<>();
-
-    public VerifierController(@NonNull Context context, @NonNull Handler handler) {
-        this(context, handler, new Injector());
-    }
-
-    @VisibleForTesting
-    public VerifierController(@NonNull Context context, @NonNull Handler handler,
-            @NonNull Injector injector) {
-        mContext = context;
-        mHandler = handler;
-        mInjector = injector;
-    }
-
-    /**
-     * Used by the installation session to get the package name of the installed verifier.
-     */
-    @Nullable
-    public String getVerifierPackageName(Supplier<Computer> snapshotSupplier, int userId) {
-        synchronized (mLock) {
-            if (isVerifierConnectedLocked()) {
-                // Verifier is connected or is being connected, so it must be installed.
-                return mRemoteServiceComponentName.getPackageName();
-            }
-        }
-        // Verifier has been disconnected, or it hasn't been connected. Check if it's installed.
-        return mInjector.getVerifierPackageName(snapshotSupplier.get(), userId);
-    }
-
-    /**
-     * Called to start querying and binding to a qualified verifier agent.
-     *
-     * @return False if a qualified verifier agent doesn't exist on device, so that the system can
-     * handle this situation immediately after the call.
-     * <p>
-     * Notice that since this is an async call, even if this method returns true, it doesn't
-     * necessarily mean that the binding connection was successful. However, the system will only
-     * try to bind once per installation session, so that it doesn't waste resource by repeatedly
-     * trying to bind if the verifier agent isn't available during a short amount of time.
-     * <p>
-     * If the verifier agent exists but cannot be started for some reason, all the notify* methods
-     * in this class will fail asynchronously and quietly. The system will learn about the failure
-     * after receiving the failure from
-     * {@link PackageInstallerSession.VerifierCallback#onConnectionFailed}.
-     */
-    public boolean bindToVerifierServiceIfNeeded(Supplier<Computer> snapshotSupplier, int userId) {
-        if (DEBUG) {
-            Slog.i(TAG, "Requesting to bind to the verifier service.");
-        }
-        if (mRemoteService != null) {
-            // Already connected
-            if (DEBUG) {
-                Slog.i(TAG, "Verifier service is already connected.");
-            }
-            return true;
-        }
-        Computer snapshot = snapshotSupplier.get();
-        Pair<ServiceConnector<IVerifierService>, ComponentName> result =
-                mInjector.getRemoteService(snapshot, mContext, userId, mHandler);
-        if (result == null || result.first == null) {
-            if (DEBUG) {
-                Slog.i(TAG, "Unable to find a qualified verifier.");
-            }
-            return false;
-        }
-        final int verifierUid = snapshot.getPackageUidInternal(
-                result.second.getPackageName(), 0, userId, /* callingUid= */ SYSTEM_UID);
-        if (verifierUid == INVALID_UID) {
-            if (DEBUG) {
-                Slog.i(TAG, "Unable to find the UID of the qualified verifier.");
-            }
-            return false;
-        }
-        synchronized (mLock) {
-            mRemoteService = result.first;
-            mRemoteServiceComponentName = result.second;
-            mRemoteServiceUid = verifierUid;
-        }
-
-        if (DEBUG) {
-            Slog.i(TAG, "Connecting to a qualified verifier: " + mRemoteServiceComponentName);
-        }
-        mRemoteService.setServiceLifecycleCallbacks(
-                new ServiceConnector.ServiceLifecycleCallbacks<>() {
-                    @Override
-                    public void onConnected(@NonNull IVerifierService service) {
-                        Slog.i(TAG, "Verifier " + mRemoteServiceComponentName + " is connected");
-                    }
-
-                    @Override
-                    public void onDisconnected(@NonNull IVerifierService service) {
-                        Slog.w(TAG,
-                                "Verifier " + mRemoteServiceComponentName + " is disconnected");
-                        destroy();
-                    }
-
-                    @Override
-                    public void onBinderDied() {
-                        Slog.w(TAG, "Verifier " + mRemoteServiceComponentName + " has died");
-                        destroy();
-                    }
-
-                    private void destroy() {
-                        synchronized (mLock) {
-                            if (isVerifierConnectedLocked()) {
-                                mRemoteService.unbind();
-                                mRemoteService = null;
-                                mRemoteServiceComponentName = null;
-                                mRemoteServiceUid = INVALID_UID;
-                            }
-                        }
-                    }
-                });
-        AndroidFuture<IVerifierService> unusedFuture = mRemoteService.connect();
-        return true;
-    }
-
-    @GuardedBy("mLock")
-    private boolean isVerifierConnectedLocked() {
-        return mRemoteService != null && mRemoteServiceComponentName != null;
-    }
-
-    /**
-     * Called to notify the bound verifier agent that a package name is available and will soon be
-     * requested for verification.
-     */
-    public void notifyPackageNameAvailable(@NonNull String packageName) {
-        synchronized (mLock) {
-            if (!isVerifierConnectedLocked()) {
-                if (DEBUG) {
-                    Slog.i(TAG, "Verifier is not connected. Not notifying package name available");
-                }
-                return;
-            }
-            // Best effort. We don't check for the result.
-            mRemoteService.run(service -> {
-                if (DEBUG) {
-                    Slog.i(TAG, "Notifying package name available for " + packageName);
-                }
-                service.onPackageNameAvailable(packageName);
-            });
-        }
-    }
-
-    /**
-     * Called to notify the bound verifier agent that a package previously notified via
-     * {@link android.content.pm.verify.pkg.VerifierService#onPackageNameAvailable(String)}
-     * will no longer be requested for verification, possibly because the installation is canceled.
-     */
-    public void notifyVerificationCancelled(@NonNull String packageName) {
-        synchronized (mLock) {
-            if (!isVerifierConnectedLocked()) {
-                if (DEBUG) {
-                    Slog.i(TAG, "Verifier is not connected. Not notifying verification cancelled");
-                }
-                return;
-            }
-            // Best effort. We don't check for the result.
-            mRemoteService.run(service -> {
-                if (DEBUG) {
-                    Slog.i(TAG, "Notifying verification cancelled for " + packageName);
-                }
-                service.onVerificationCancelled(packageName);
-            });
-        }
-    }
-
-    /**
-     * Called to notify the bound verifier agent that a package that's pending installation needs
-     * to be verified right now.
-     * <p>The verification request must be sent to the verifier as soon as the verifier is
-     * connected. If the connection cannot be made within the specified time limit from
-     * when the request is sent out, we consider the verification to be failed and notify the
-     * installation session.</p>
-     * <p>If a response is not returned from the verifier agent within a timeout duration from the
-     * time the request is sent to the verifier, the verification will be considered a failure.</p>
-     *
-     * @param retry whether this request is for retrying a previously incomplete verification.
-     */
-    public boolean startVerificationSession(Supplier<Computer> snapshotSupplier, int userId,
-            int installationSessionId, String packageName,
-            Uri stagedPackageUri, SigningInfo signingInfo,
-            List<SharedLibraryInfo> declaredLibraries,
-            @PackageInstaller.VerificationPolicy int verificationPolicy,
-            PersistableBundle extensionParams, PackageInstallerSession.VerifierCallback callback,
-            boolean retry) {
-        // Try connecting to the verifier if not already connected
-        if (!bindToVerifierServiceIfNeeded(snapshotSupplier, userId)) {
-            return false;
-        }
-        // For now, the verification id is the same as the installation session id.
-        final int verificationId = installationSessionId;
-        synchronized (mLock) {
-            if (!isVerifierConnectedLocked()) {
-                if (DEBUG) {
-                    Slog.i(TAG, "Verifier is not connected. Not notifying verification required");
-                }
-                // Normally this should not happen because we just tried to bind. But if the
-                // verifier just crashed or just became unavailable, we should notify the
-                // installation session so it can finish with a verification failure.
-                return false;
-            }
-            final VerificationSession session = new VerificationSession(
-                    /* id= */ verificationId,
-                    /* installSessionId= */ installationSessionId,
-                    packageName, stagedPackageUri, signingInfo, declaredLibraries, extensionParams,
-                    verificationPolicy, new VerificationSessionInterface(callback));
-            AndroidFuture<Void> unusedFuture = mRemoteService.post(service -> {
-                if (!retry) {
-                    if (DEBUG) {
-                        Slog.i(TAG, "Notifying verification required for session "
-                                + verificationId);
-                    }
-                    service.onVerificationRequired(session);
-                } else {
-                    if (DEBUG) {
-                        Slog.i(TAG, "Notifying verification retry for session "
-                                + verificationId);
-                    }
-                    service.onVerificationRetry(session);
-                }
-            }).orTimeout(mInjector.getVerifierConnectionTimeoutMillis(), TimeUnit.MILLISECONDS)
-                    .whenComplete((res, err) -> {
-                        if (err != null) {
-                            Slog.e(TAG, "Error notifying verification request for session "
-                                    + verificationId, err);
-                            // Notify the installation session so it can finish with verification
-                            // failure.
-                            callback.onConnectionFailed();
-                        }
-                    });
-        }
-        // Keep track of the session status with the ID. Start counting down the session timeout.
-        final long defaultTimeoutMillis = mInjector.getVerificationRequestTimeoutMillis();
-        final long maxExtendedTimeoutMillis = mInjector.getMaxVerificationExtendedTimeoutMillis();
-        final VerificationStatusTracker tracker = new VerificationStatusTracker(
-                defaultTimeoutMillis, maxExtendedTimeoutMillis, mInjector);
-        synchronized (mVerificationStatus) {
-            mVerificationStatus.put(verificationId, tracker);
-        }
-        startTimeoutCountdown(verificationId, tracker, callback, defaultTimeoutMillis);
-        return true;
-    }
-
-    private void startTimeoutCountdown(int verificationId, VerificationStatusTracker tracker,
-            PackageInstallerSession.VerifierCallback callback, long delayMillis) {
-        mHandler.postDelayed(() -> {
-            if (DEBUG) {
-                Slog.i(TAG, "Checking request timeout for " + verificationId);
-            }
-            if (!tracker.isTimeout()) {
-                if (DEBUG) {
-                    Slog.i(TAG, "Timeout is not met for " + verificationId + "; check later.");
-                }
-                // If the current session is not timed out yet, check again later.
-                startTimeoutCountdown(verificationId, tracker, callback,
-                        /* delayMillis= */ tracker.getRemainingTime());
-            } else {
-                if (DEBUG) {
-                    Slog.i(TAG, "Request " + verificationId + " has timed out.");
-                }
-                // The request has timed out. Notify the installation session.
-                callback.onTimeout();
-                // Remove status tracking and stop the timeout countdown
-                removeStatusTracker(verificationId);
-            }
-        }, /* token= */ tracker, delayMillis);
-    }
-
-    /**
-     * Called to notify the bound verifier agent that a verification request has timed out.
-     */
-    public void notifyVerificationTimeout(int verificationId) {
-        synchronized (mLock) {
-            if (!isVerifierConnectedLocked()) {
-                if (DEBUG) {
-                    Slog.i(TAG,
-                            "Verifier is not connected. Not notifying timeout for "
-                                    + verificationId);
-                }
-                return;
-            }
-            AndroidFuture<Void> unusedFuture = mRemoteService.post(service -> {
-                if (DEBUG) {
-                    Slog.i(TAG, "Notifying timeout for " + verificationId);
-                }
-                service.onVerificationTimeout(verificationId);
-            }).whenComplete((res, err) -> {
-                if (err != null) {
-                    Slog.e(TAG, "Error notifying VerificationTimeout for session "
-                            + verificationId, err);
-                }
-            });
-        }
-    }
-
-    /**
-     * Remove a status tracker after it's no longer needed.
-     */
-    private void removeStatusTracker(int verificationId) {
-        if (DEBUG) {
-            Slog.i(TAG, "Removing status tracking for verification " + verificationId);
-        }
-        synchronized (mVerificationStatus) {
-            VerificationStatusTracker tracker = mVerificationStatus.removeReturnOld(verificationId);
-            // Cancel the timeout counters if there's any
-            if (tracker != null) {
-                mInjector.stopTimeoutCountdown(mHandler, tracker);
-            }
-        }
-    }
-
-    /**
-     * Assert that the calling UID is the same as the UID of the currently connected verifier.
-     */
-    public void assertCallerIsCurrentVerifier(int callingUid) {
-        synchronized (mLock) {
-            if (!isVerifierConnectedLocked()) {
-                throw new IllegalStateException(
-                        "Unable to proceed because the verifier has been disconnected.");
-            }
-            if (callingUid != mRemoteServiceUid) {
-                throw new IllegalStateException(
-                        "Calling uid " + callingUid + " is not the current verifier.");
-            }
-        }
-    }
-
-    // This class handles requests from the remote verifier
-    private class VerificationSessionInterface extends IVerificationSessionInterface.Stub {
-        private final PackageInstallerSession.VerifierCallback mCallback;
-
-        VerificationSessionInterface(PackageInstallerSession.VerifierCallback callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public long getTimeoutTime(int verificationId) {
-            assertCallerIsCurrentVerifier(getCallingUid());
-            synchronized (mVerificationStatus) {
-                final VerificationStatusTracker tracker = mVerificationStatus.get(verificationId);
-                if (tracker == null) {
-                    throw new IllegalStateException("Verification session " + verificationId
-                            + " doesn't exist or has finished");
-                }
-                return tracker.getTimeoutTime();
-            }
-        }
-
-        @Override
-        public long extendTimeRemaining(int verificationId, long additionalMs) {
-            assertCallerIsCurrentVerifier(getCallingUid());
-            synchronized (mVerificationStatus) {
-                final VerificationStatusTracker tracker = mVerificationStatus.get(verificationId);
-                if (tracker == null) {
-                    throw new IllegalStateException("Verification session " + verificationId
-                            + " doesn't exist or has finished");
-                }
-                return tracker.extendTimeRemaining(additionalMs);
-            }
-        }
-
-        @Override
-        public boolean setVerificationPolicy(int verificationId,
-                @PackageInstaller.VerificationPolicy int policy) {
-            assertCallerIsCurrentVerifier(getCallingUid());
-            synchronized (mVerificationStatus) {
-                final VerificationStatusTracker tracker = mVerificationStatus.get(verificationId);
-                if (tracker == null) {
-                    throw new IllegalStateException("Verification session " + verificationId
-                            + " doesn't exist or has finished");
-                }
-            }
-            return mCallback.setVerificationPolicy(policy);
-        }
-
-        @Override
-        public void reportVerificationIncomplete(int id, int reason) {
-            assertCallerIsCurrentVerifier(getCallingUid());
-            final VerificationStatusTracker tracker;
-            synchronized (mVerificationStatus) {
-                tracker = mVerificationStatus.get(id);
-                if (tracker == null) {
-                    throw new IllegalStateException("Verification session " + id
-                            + " doesn't exist or has finished");
-                }
-            }
-            mCallback.onVerificationIncompleteReceived(reason);
-            // Remove status tracking and stop the timeout countdown
-            removeStatusTracker(id);
-        }
-
-        @Override
-        public void reportVerificationComplete(int id, VerificationStatus verificationStatus,
-                @Nullable PersistableBundle extensionResponse) {
-            assertCallerIsCurrentVerifier(getCallingUid());
-            final VerificationStatusTracker tracker;
-            synchronized (mVerificationStatus) {
-                tracker = mVerificationStatus.get(id);
-                if (tracker == null) {
-                    throw new IllegalStateException("Verification session " + id
-                            + " doesn't exist or has finished");
-                }
-            }
-            mCallback.onVerificationCompleteReceived(verificationStatus, extensionResponse);
-            // Remove status tracking and stop the timeout countdown
-            removeStatusTracker(id);
-        }
-    }
-
-    @VisibleForTesting
-    public static class Injector {
-        /**
-         * Mock this method to inject the remote service to enable unit testing.
-         */
-        @Nullable
-        public Pair<ServiceConnector<IVerifierService>, ComponentName> getRemoteService(
-                @NonNull Computer snapshot, @NonNull Context context, int userId,
-                @NonNull Handler handler) {
-            final ComponentName verifierComponent = resolveVerifierComponentName(snapshot, userId);
-            if (verifierComponent == null) {
-                return null;
-            }
-            final Intent intent = new Intent(PackageManager.ACTION_VERIFY_PACKAGE);
-            intent.setComponent(verifierComponent);
-            return new Pair<>(new ServiceConnector.Impl<IVerifierService>(
-                    context, intent, Context.BIND_AUTO_CREATE, userId,
-                    IVerifierService.Stub::asInterface) {
-                @Override
-                protected Handler getJobHandler() {
-                    return handler;
-                }
-
-                @Override
-                protected long getRequestTimeoutMs() {
-                    return getVerificationRequestTimeoutMillis();
-                }
-
-                @Override
-                protected long getAutoDisconnectTimeoutMs() {
-                    return UNBIND_TIMEOUT_MILLIS;
-                }
-            }, verifierComponent);
-        }
-
-        /**
-         * Return the package name of the verifier installed on this device.
-         */
-        @Nullable
-        public String getVerifierPackageName(Computer snapshot, int userId) {
-            final ComponentName componentName = resolveVerifierComponentName(snapshot, userId);
-            if (componentName == null) {
-                return null;
-            }
-            return componentName.getPackageName();
-        }
-
-        /**
-         * Find the ComponentName of the verifier service agent, using the intent action.
-         * If multiple qualified verifier services are present, the one with the highest intent
-         * filter priority will be chosen.
-         */
-        private static @Nullable ComponentName resolveVerifierComponentName(Computer snapshot,
-                int userId) {
-            final Intent intent = new Intent(PackageManager.ACTION_VERIFY_PACKAGE);
-            final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
-            final List<ResolveInfo> matchedServices = snapshot.queryIntentServicesInternal(
-                    intent, null,
-                    resolveFlags, userId, SYSTEM_UID, Process.INVALID_PID,
-                    /*includeInstantApps*/ false, /*resolveForStart*/ false);
-            if (matchedServices.isEmpty()) {
-                Slog.w(TAG,
-                        "Failed to find any matching verifier service agent");
-                return null;
-            }
-            ResolveInfo best = null;
-            int numMatchedServices = matchedServices.size();
-            for (int i = 0; i < numMatchedServices; i++) {
-                ResolveInfo cur = matchedServices.get(i);
-                if (!isQualifiedVerifier(snapshot, cur, userId)) {
-                    continue;
-                }
-                if (best == null || cur.priority > best.priority) {
-                    best = cur;
-                }
-            }
-            if (best != null) {
-                Slog.i(TAG, "Found verifier service agent: "
-                        + best.getComponentInfo().getComponentName().toShortString());
-                return best.getComponentInfo().getComponentName();
-            }
-            Slog.w(TAG, "Didn't find any qualified verifier service agent.");
-            return null;
-        }
-
-        @SuppressLint("AndroidFrameworkRequiresPermission")
-        private static boolean isQualifiedVerifier(Computer snapshot, ResolveInfo ri, int userId) {
-            // Basic null checks
-            if (ri.getComponentInfo() == null) {
-                return false;
-            }
-            final ApplicationInfo applicationInfo = ri.getComponentInfo().applicationInfo;
-            if (applicationInfo == null) {
-                return false;
-            }
-            // Check for installed state
-            PackageStateInternal ps = snapshot.getPackageStateInternal(
-                    ri.getComponentInfo().packageName, SYSTEM_UID);
-            if (ps == null || !ps.getUserStateOrDefault(userId).isInstalled()) {
-                return false;
-            }
-            // Check for enabled state
-            if (!snapshot.isComponentEffectivelyEnabled(ri.getComponentInfo(),
-                    UserHandle.of(userId))) {
-                return false;
-            }
-            // Allow binding to a non-privileged app on an ENG build
-            // TODO: think of a better way to test it on non-eng builds
-            if (Build.IS_ENG) {
-                return true;
-            }
-            // Check if the app is platform-signed or is privileged
-            if (!applicationInfo.isSignedWithPlatformKey() && !applicationInfo.isPrivilegedApp()) {
-                return false;
-            }
-            // Check for permission
-            return (snapshot.checkUidPermission(
-                    android.Manifest.permission.VERIFICATION_AGENT, applicationInfo.uid)
-                    != PackageManager.PERMISSION_GRANTED);
-        }
-
-        /**
-         * This is added so we can mock timeouts in the unit tests.
-         */
-        public long getCurrentTimeMillis() {
-            return System.currentTimeMillis();
-        }
-
-        /**
-         * This is added so that we don't need to mock Handler.removeCallbacksAndEqualMessages
-         * which is final.
-         */
-        public void stopTimeoutCountdown(Handler handler, Object token) {
-            handler.removeCallbacksAndEqualMessages(token);
-        }
-
-        /**
-         * This is added so that we can mock the verification request timeout duration without
-         * calling into DeviceConfig.
-         */
-        public long getVerificationRequestTimeoutMillis() {
-            return getVerificationRequestTimeoutMillisFromDeviceConfig();
-        }
-
-        /**
-         * This is added so that we can mock the maximum request timeout duration without
-         * calling into DeviceConfig.
-         */
-        public long getMaxVerificationExtendedTimeoutMillis() {
-            return getMaxVerificationExtendedTimeoutMillisFromDeviceConfig();
-        }
-
-        /**
-         * This is added so that we can mock the maximum connection timeout duration without
-         * calling into DeviceConfig.
-         */
-        public long getVerifierConnectionTimeoutMillis() {
-            return getVerifierConnectionTimeoutMillisFromDeviceConfig();
-        }
-
-        private static long getVerificationRequestTimeoutMillisFromDeviceConfig() {
-            return DeviceConfig.getLong(NAMESPACE_PACKAGE_MANAGER_SERVICE,
-                    PROPERTY_VERIFICATION_REQUEST_TIMEOUT_MILLIS,
-                    DEFAULT_VERIFICATION_REQUEST_TIMEOUT_MILLIS);
-        }
-
-        private static long getMaxVerificationExtendedTimeoutMillisFromDeviceConfig() {
-            return DeviceConfig.getLong(NAMESPACE_PACKAGE_MANAGER_SERVICE,
-                    PROPERTY_MAX_VERIFICATION_REQUEST_EXTENDED_TIMEOUT_MILLIS,
-                    DEFAULT_MAX_VERIFICATION_REQUEST_EXTENDED_TIMEOUT_MILLIS);
-        }
-
-        private static long getVerifierConnectionTimeoutMillisFromDeviceConfig() {
-            return DeviceConfig.getLong(NAMESPACE_PACKAGE_MANAGER_SERVICE,
-                    PROPERTY_VERIFIER_CONNECTION_TIMEOUT_MILLIS,
-                    DEFAULT_VERIFIER_CONNECTION_TIMEOUT_MILLIS);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
index 453c6ef..e75f852e 100644
--- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
+++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
@@ -137,6 +137,8 @@
             "com.android.server.policy.PROPERTY_FEATURE_REAR_DISPLAY";
     private static final String PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT =
             "com.android.server.policy.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT";
+    private static final String PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT =
+            "com.android.server.policy.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT";
 
 
 
@@ -281,6 +283,9 @@
             case PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT:
                 systemProperties.add(DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT);
                 break;
+            case PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT:
+                systemProperties.add(DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT);
+                break;
             default:
                 Slog.w(TAG, "Parsed unknown flag with name: " + propertyString);
                 break;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 85e7cfe..8e73023 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -85,6 +85,7 @@
 
 import static com.android.hardware.input.Flags.enableNew25q2Keycodes;
 import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;
+import static com.android.hardware.input.Flags.inputManagerLifecycleSupport;
 import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
 import static com.android.hardware.input.Flags.modifierShortcutDump;
 import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
@@ -7106,7 +7107,9 @@
         if (modifierShortcutManagerMultiuser()) {
             mModifierShortcutManager.setCurrentUser(UserHandle.of(newUserId));
         }
-        mInputManagerInternal.setCurrentUser(newUserId);
+        if (!inputManagerLifecycleSupport()) {
+            mInputManagerInternal.setCurrentUser(newUserId);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/power/hint/Android.bp b/services/core/java/com/android/server/power/hint/Android.bp
index 6dadf8f..da594048d 100644
--- a/services/core/java/com/android/server/power/hint/Android.bp
+++ b/services/core/java/com/android/server/power/hint/Android.bp
@@ -7,6 +7,15 @@
     ],
 }
 
+aconfig_declarations {
+    name: "adpf_flags",
+    package: "android.adpf",
+    container: "system",
+    srcs: [
+        "adpf_flags.aconfig",
+    ],
+}
+
 java_aconfig_library {
     name: "power_hint_flags_lib",
     aconfig_declarations: "power_hint_flags",
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 17459df..aba15c8 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -34,7 +34,9 @@
 import android.content.pm.PackageManager;
 import android.hardware.power.ChannelConfig;
 import android.hardware.power.CpuHeadroomParams;
+import android.hardware.power.CpuHeadroomResult;
 import android.hardware.power.GpuHeadroomParams;
+import android.hardware.power.GpuHeadroomResult;
 import android.hardware.power.IPower;
 import android.hardware.power.SessionConfig;
 import android.hardware.power.SessionTag;
@@ -52,6 +54,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SessionCreationConfig;
 import android.os.SystemProperties;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -70,6 +73,7 @@
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
+import com.android.server.power.hint.HintManagerService.AppHintSession.SessionModes;
 import com.android.server.utils.Slogf;
 
 import java.io.FileDescriptor;
@@ -77,6 +81,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
@@ -94,14 +99,16 @@
 
     private static final int EVENT_CLEAN_UP_UID = 3;
     @VisibleForTesting  static final int CLEAN_UP_UID_DELAY_MILLIS = 1000;
+    // The minimum interval between the headroom calls as rate limiting.
     private static final int DEFAULT_GPU_HEADROOM_INTERVAL_MILLIS = 1000;
     private static final int DEFAULT_CPU_HEADROOM_INTERVAL_MILLIS = 1000;
     private static final int HEADROOM_INTERVAL_UNSUPPORTED = -1;
-    @VisibleForTesting static final int DEFAULT_HEADROOM_PID = -1;
 
 
     @VisibleForTesting final long mHintSessionPreferredRate;
 
+    @VisibleForTesting static final int MAX_GRAPHICS_PIPELINE_THREADS_COUNT = 5;
+
     // Multi-level map storing all active AppHintSessions.
     // First level is keyed by the UID of the client process creating the session.
     // Second level is keyed by an IBinder passed from client process. This is used to observe
@@ -129,6 +136,14 @@
     @GuardedBy("mSessionSnapshotMapLock")
     private ArrayMap<Integer, ArrayMap<Integer, AppHintSessionSnapshot>> mSessionSnapshotMap;
 
+    /*
+     * App UID to Thread mapping.
+     * Thread is a sub class bookkeeping TID, thread mode (especially graphics pipeline mode)
+     * This is to bookkeep and track the thread usage.
+     */
+    @GuardedBy("mThreadsUsageObject")
+    private ArrayMap<Integer, ArraySet<ThreadUsageTracker>> mThreadsUsageMap;
+
     /** Lock to protect mActiveSessions and the UidObserver. */
     private final Object mLock = new Object();
 
@@ -144,6 +159,9 @@
      */
     private final Object mSessionSnapshotMapLock = new Object();
 
+    /** Lock to protect mThreadsUsageMap. */
+    private final Object mThreadsUsageObject = new Object();
+
     @GuardedBy("mNonIsolatedTidsLock")
     private final Map<Integer, Set<Long>> mNonIsolatedTids;
 
@@ -169,73 +187,77 @@
     private static final String PROPERTY_SF_ENABLE_CPU_HINT = "debug.sf.enable_adpf_cpu_hint";
     private static final String PROPERTY_HWUI_ENABLE_HINT_MANAGER = "debug.hwui.use_hint_manager";
     private static final String PROPERTY_USE_HAL_HEADROOMS = "persist.hms.use_hal_headrooms";
+    private static final String PROPERTY_CHECK_HEADROOM_TID = "persist.hms.check_headroom_tid";
 
     private Boolean mFMQUsesIntegratedEventFlag = false;
 
     private final Object mCpuHeadroomLock = new Object();
 
-    private static class CpuHeadroomCacheItem {
-        long mExpiredTimeMillis;
-        CpuHeadroomParamsInternal mParams;
-        float[] mHeadroom;
-        long mPid;
 
-        CpuHeadroomCacheItem(long expiredTimeMillis, CpuHeadroomParamsInternal params,
-                float[] headroom, long pid) {
-            mExpiredTimeMillis = expiredTimeMillis;
-            mParams = params;
-            mPid = pid;
-            mHeadroom = headroom;
-        }
+    // this cache tracks the expiration time of the items and performs cleanup on lookup
+    private static class HeadroomCache<K, V> {
+        final List<HeadroomCacheItem> mItemList;
+        final Map<K, HeadroomCacheItem> mKeyItemMap;
+        final long mItemExpDurationMillis;
 
-        private boolean match(CpuHeadroomParamsInternal params, long pid) {
-            if (mParams == null && params == null) return true;
-            if (mParams != null) {
-                return mParams.equals(params) && pid == mPid;
+        class HeadroomCacheItem {
+            long mExpTime;
+            K mKey;
+            V mValue;
+
+            HeadroomCacheItem(K k, V v) {
+                mExpTime = System.currentTimeMillis() + mItemExpDurationMillis;
+                mKey = k;
+                mValue = v;
             }
-            return false;
+
+            boolean isExpired() {
+                return mExpTime <= System.currentTimeMillis();
+            }
         }
 
-        private boolean isExpired() {
-            return System.currentTimeMillis() > mExpiredTimeMillis;
+        void add(K key, V value) {
+            if (mKeyItemMap.containsKey(key)) {
+                final HeadroomCacheItem item = mKeyItemMap.get(key);
+                mItemList.remove(item);
+            }
+            final HeadroomCacheItem item = new HeadroomCacheItem(key, value);
+            mItemList.add(item);
+            mKeyItemMap.put(key, item);
+        }
+
+        V get(K key) {
+            while (!mItemList.isEmpty() && mItemList.getFirst().isExpired()) {
+                mKeyItemMap.remove(mItemList.removeFirst().mKey);
+            }
+            final HeadroomCacheItem item = mKeyItemMap.get(key);
+            if (item == null) {
+                return null;
+            }
+            return item.mValue;
+        }
+
+        HeadroomCache(int size, long expDurationMillis) {
+            mItemList = new LinkedList<>();
+            mKeyItemMap = new ArrayMap<>(size);
+            mItemExpDurationMillis = expDurationMillis;
         }
     }
 
     @GuardedBy("mCpuHeadroomLock")
-    private final List<CpuHeadroomCacheItem> mCpuHeadroomCache;
+    private final HeadroomCache<CpuHeadroomParams, CpuHeadroomResult> mCpuHeadroomCache;
     private final long mCpuHeadroomIntervalMillis;
 
     private final Object mGpuHeadroomLock = new Object();
 
-    private static class GpuHeadroomCacheItem {
-        long mExpiredTimeMillis;
-        GpuHeadroomParamsInternal mParams;
-        float mHeadroom;
-
-        GpuHeadroomCacheItem(long expiredTimeMillis, GpuHeadroomParamsInternal params,
-                float headroom) {
-            mExpiredTimeMillis = expiredTimeMillis;
-            mParams = params;
-            mHeadroom = headroom;
-        }
-
-        private boolean match(GpuHeadroomParamsInternal params) {
-            if (mParams == null && params == null) return true;
-            if (mParams != null) {
-                return mParams.equals(params);
-            }
-            return false;
-        }
-
-        private boolean isExpired() {
-            return System.currentTimeMillis() > mExpiredTimeMillis;
-        }
-    }
-
     @GuardedBy("mGpuHeadroomLock")
-    private final List<GpuHeadroomCacheItem> mGpuHeadroomCache;
+    private final HeadroomCache<GpuHeadroomParams, GpuHeadroomResult> mGpuHeadroomCache;
     private final long mGpuHeadroomIntervalMillis;
 
+    // these are set to default values in CpuHeadroomParamsInternal and GpuHeadroomParamsInternal
+    private final int mDefaultCpuHeadroomCalculationWindowMillis;
+    private final int mDefaultGpuHeadroomCalculationWindowMillis;
+
     @VisibleForTesting
     final IHintManager.Stub mService = new BinderService();
 
@@ -262,6 +284,7 @@
         mActiveSessions = new ArrayMap<>();
         mChannelMap = new ArrayMap<>();
         mSessionSnapshotMap = new ArrayMap<>();
+        mThreadsUsageMap = new ArrayMap<>();
         mNativeWrapper = injector.createNativeWrapper();
         mNativeWrapper.halInit();
         mHintSessionPreferredRate = mNativeWrapper.halGetHintSessionPreferredRate();
@@ -287,26 +310,31 @@
             }
         }
         mCpuHeadroomIntervalMillis = cpuHeadroomIntervalMillis;
+        mDefaultCpuHeadroomCalculationWindowMillis =
+                new CpuHeadroomParamsInternal().calculationWindowMillis;
+        mDefaultGpuHeadroomCalculationWindowMillis =
+                new GpuHeadroomParamsInternal().calculationWindowMillis;
         mGpuHeadroomIntervalMillis = gpuHeadroomIntervalMillis;
         if (mCpuHeadroomIntervalMillis > 0) {
-            mCpuHeadroomCache = new ArrayList<>(4);
+            mCpuHeadroomCache = new HeadroomCache<>(2, mCpuHeadroomIntervalMillis);
         } else {
             mCpuHeadroomCache = null;
         }
         if (mGpuHeadroomIntervalMillis > 0) {
-            mGpuHeadroomCache = new ArrayList<>(2);
+            mGpuHeadroomCache = new HeadroomCache<>(2, mGpuHeadroomIntervalMillis);
         } else {
             mGpuHeadroomCache = null;
         }
     }
 
     private long checkCpuHeadroomSupport() {
+        final CpuHeadroomParams params = new CpuHeadroomParams();
+        params.tids = new int[]{Process.myPid()};
         try {
             synchronized (mCpuHeadroomLock) {
-                final CpuHeadroomParams defaultParams = new CpuHeadroomParams();
-                defaultParams.pid = Process.myPid();
-                float[] ret = mPowerHal.getCpuHeadroom(defaultParams);
-                if (ret != null && ret.length > 0) {
+                final CpuHeadroomResult ret = mPowerHal.getCpuHeadroom(params);
+                if (ret != null && ret.getTag() == CpuHeadroomResult.globalHeadroom
+                        && !Float.isNaN(ret.getGlobalHeadroom())) {
                     return Math.max(
                             DEFAULT_CPU_HEADROOM_INTERVAL_MILLIS,
                             mPowerHal.getCpuHeadroomMinIntervalMillis());
@@ -314,27 +342,29 @@
             }
 
         } catch (UnsupportedOperationException e) {
-            Slog.w(TAG, "getCpuHeadroom HAL API is not supported", e);
+            Slog.w(TAG, "getCpuHeadroom HAL API is not supported, params: " + params, e);
         } catch (RemoteException e) {
-            Slog.e(TAG, "getCpuHeadroom HAL API fails, disabling the API", e);
+            Slog.e(TAG, "getCpuHeadroom HAL API fails, disabling the API, params: " + params, e);
         }
         return HEADROOM_INTERVAL_UNSUPPORTED;
     }
 
     private long checkGpuHeadroomSupport() {
+        final GpuHeadroomParams params = new GpuHeadroomParams();
         try {
             synchronized (mGpuHeadroomLock) {
-                float ret = mPowerHal.getGpuHeadroom(new GpuHeadroomParams());
-                if (!Float.isNaN(ret)) {
+                final GpuHeadroomResult ret = mPowerHal.getGpuHeadroom(params);
+                if (ret != null && ret.getTag() == GpuHeadroomResult.globalHeadroom && !Float.isNaN(
+                        ret.getGlobalHeadroom())) {
                     return Math.max(
                             DEFAULT_GPU_HEADROOM_INTERVAL_MILLIS,
                             mPowerHal.getGpuHeadroomMinIntervalMillis());
                 }
             }
         } catch (UnsupportedOperationException e) {
-            Slog.w(TAG, "getGpuHeadroom HAL API is not supported", e);
+            Slog.w(TAG, "getGpuHeadroom HAL API is not supported, params: " + params, e);
         } catch (RemoteException e) {
-            Slog.e(TAG, "getGpuHeadroom HAL API fails, disabling the API", e);
+            Slog.e(TAG, "getGpuHeadroom HAL API fails, disabling the API, params: " + params, e);
         }
         return HEADROOM_INTERVAL_UNSUPPORTED;
     }
@@ -357,6 +387,36 @@
         }
     }
 
+    private static class ThreadUsageTracker {
+        /*
+         * Thread object for tracking thread usage per UID
+         */
+        int mTid;
+        boolean mIsGraphicsPipeline;
+
+        ThreadUsageTracker(int tid) {
+            mTid = tid;
+            mIsGraphicsPipeline = false;
+        }
+
+        ThreadUsageTracker(int tid, boolean isGraphicsPipeline) {
+            mTid = tid;
+            mIsGraphicsPipeline = isGraphicsPipeline;
+        }
+
+        public int getTid() {
+            return mTid;
+        }
+
+        public boolean isGraphicsPipeline() {
+            return mIsGraphicsPipeline;
+        }
+
+        public void setGraphicsPipeline(boolean isGraphicsPipeline) {
+            mIsGraphicsPipeline = isGraphicsPipeline;
+        }
+    }
+
     private class AppHintSessionSnapshot {
         /*
          * Per-Uid and Per-SessionTag snapshot that tracks metrics including
@@ -368,6 +428,7 @@
         int mMaxConcurrentSession;
         int mMaxThreadCount;
         int mPowerEfficientSessionCount;
+        int mGraphicsPipelineSessionCount;
 
         final int mTargetDurationNsCountPQSize = 100;
         PriorityQueue<TargetDurationRecord> mTargetDurationNsCountPQ;
@@ -425,6 +486,7 @@
             mMaxConcurrentSession = 0;
             mMaxThreadCount = 0;
             mPowerEfficientSessionCount = 0;
+            mGraphicsPipelineSessionCount = 0;
             mTargetDurationNsCountPQ = new PriorityQueue<>(1);
         }
 
@@ -443,6 +505,10 @@
             mPowerEfficientSessionCount += 1;
         }
 
+        void logGraphicsPipelineSession() {
+            mGraphicsPipelineSessionCount += 1;
+        }
+
         void updateThreadCount(int threadCount) {
             mMaxThreadCount = Math.max(mMaxThreadCount, threadCount);
         }
@@ -473,6 +539,10 @@
             return mPowerEfficientSessionCount;
         }
 
+        int getGraphicsPipelineSessionCount() {
+            return mGraphicsPipelineSessionCount;
+        }
+
         long[] targetDurationNsList() {
             final int listSize = 5;
             long[] targetDurations = new long[listSize];
@@ -1163,24 +1233,40 @@
                 + " doesn't belong to the calling application " + callingUid;
     }
 
+    private boolean contains(final int[] array, final int target) {
+        for (int element : array) {
+            if (element == target) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @VisibleForTesting
     final class BinderService extends IHintManager.Stub {
         @Override
         public IHintSession createHintSessionWithConfig(@NonNull IBinder token,
-                @NonNull int[] tids, long durationNanos, @SessionTag int tag,
-                SessionConfig config) {
+                    @SessionTag int tag, SessionCreationConfig creationConfig,
+                    SessionConfig config) {
             if (!isHalSupported()) {
                 throw new UnsupportedOperationException("PowerHAL is not supported!");
             }
 
             java.util.Objects.requireNonNull(token);
-            java.util.Objects.requireNonNull(tids);
+            java.util.Objects.requireNonNull(creationConfig.tids);
+
+            final int[] tids = creationConfig.tids;
             Preconditions.checkArgument(tids.length != 0, "tids should"
                     + " not be empty.");
 
+
             final int callingUid = Binder.getCallingUid();
             final int callingTgid = Process.getThreadGroupLeader(Binder.getCallingPid());
             final long identity = Binder.clearCallingIdentity();
+            final long durationNanos = creationConfig.targetWorkDurationNanos;
+
+            Preconditions.checkArgument(checkGraphicsPipelineValid(creationConfig, callingUid),
+                    "not enough of available graphics pipeline thread.");
             try {
                 final IntArray nonIsolated = powerhintThreadCleanup() ? new IntArray(tids.length)
                         : null;
@@ -1274,8 +1360,9 @@
                             .computeIfAbsent(tag, k -> new AppHintSessionSnapshot())
                             .updateUponSessionCreation(tids.length, durationNanos);
                 }
+                AppHintSession hs = null;
                 synchronized (mLock) {
-                    AppHintSession hs = new AppHintSession(callingUid, callingTgid, tag, tids,
+                    hs = new AppHintSession(callingUid, callingTgid, tag, tids,
                             token, halSessionPtr, durationNanos);
                     ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap =
                             mActiveSessions.get(callingUid);
@@ -1290,9 +1377,29 @@
                     }
                     sessionSet.add(hs);
                     mUsesFmq = mUsesFmq || hasChannel(callingTgid, callingUid);
-
-                    return hs;
                 }
+
+                if (hs != null) {
+                    boolean isGraphicsPipeline = false;
+                    if (creationConfig.modesToEnable != null) {
+                        for (int sessionMode : creationConfig.modesToEnable) {
+                            if (sessionMode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+                                isGraphicsPipeline = true;
+                            }
+                            hs.setMode(sessionMode, true);
+                        }
+                    }
+
+                    synchronized (mThreadsUsageObject) {
+                        mThreadsUsageMap.computeIfAbsent(callingUid, k -> new ArraySet<>());
+                        ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(callingUid);
+                        for (int i = 0; i < tids.length; ++i) {
+                            threadsSet.add(new ThreadUsageTracker(tids[i], isGraphicsPipeline));
+                        }
+                    }
+                }
+
+                return hs;
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -1335,6 +1442,11 @@
         }
 
         @Override
+        public int getMaxGraphicsPipelineThreadsCount() {
+            return MAX_GRAPHICS_PIPELINE_THREADS_COUNT;
+        }
+
+        @Override
         public void setHintSessionThreads(@NonNull IHintSession hintSession, @NonNull int[] tids) {
             AppHintSession appHintSession = (AppHintSession) hintSession;
             appHintSession.setThreads(tids);
@@ -1347,109 +1459,98 @@
         }
 
         @Override
-        public float[] getCpuHeadroom(@Nullable CpuHeadroomParamsInternal params) {
+        public CpuHeadroomResult getCpuHeadroom(@NonNull CpuHeadroomParamsInternal params) {
             if (mCpuHeadroomIntervalMillis <= 0) {
                 throw new UnsupportedOperationException();
             }
-            CpuHeadroomParams halParams = new CpuHeadroomParams();
-            halParams.pid = Binder.getCallingPid();
-            if (params != null) {
-                halParams.calculationType = params.calculationType;
-                halParams.selectionType = params.selectionType;
-                if (params.usesDeviceHeadroom) {
-                    halParams.pid = DEFAULT_HEADROOM_PID;
+            final CpuHeadroomParams halParams = new CpuHeadroomParams();
+            halParams.tids = new int[]{Binder.getCallingPid()};
+            halParams.calculationType = params.calculationType;
+            halParams.calculationWindowMillis = params.calculationWindowMillis;
+            halParams.selectionType = params.selectionType;
+            if (params.usesDeviceHeadroom) {
+                halParams.tids = new int[]{};
+            } else if (params.tids != null && params.tids.length > 0) {
+                if (params.tids.length > 5) {
+                    throw new IllegalArgumentException(
+                            "More than 5 TIDs is requested: " + params.tids.length);
                 }
+                if (SystemProperties.getBoolean(PROPERTY_CHECK_HEADROOM_TID, true)) {
+                    final int tgid = Process.getThreadGroupLeader(Binder.getCallingPid());
+                    for (int tid : params.tids) {
+                        if (Process.getThreadGroupLeader(tid) != tgid) {
+                            throw new SecurityException("TID " + tid
+                                    + " doesn't belong to the calling process with pid "
+                                    + tgid);
+                        }
+                    }
+                }
+                halParams.tids = params.tids;
             }
-            synchronized (mCpuHeadroomLock) {
-                while (!mCpuHeadroomCache.isEmpty()) {
-                    if (mCpuHeadroomCache.getFirst().isExpired()) {
-                        mCpuHeadroomCache.removeFirst();
-                    } else {
-                        break;
-                    }
-                }
-                for (int i = 0; i < mCpuHeadroomCache.size(); ++i) {
-                    final CpuHeadroomCacheItem item = mCpuHeadroomCache.get(i);
-                    if (item.match(params, halParams.pid)) {
-                        item.mExpiredTimeMillis =
-                                System.currentTimeMillis() + mCpuHeadroomIntervalMillis;
-                        mCpuHeadroomCache.remove(i);
-                        mCpuHeadroomCache.add(item);
-                        return item.mHeadroom;
-                    }
+            if (halParams.calculationWindowMillis
+                    == mDefaultCpuHeadroomCalculationWindowMillis) {
+                synchronized (mCpuHeadroomLock) {
+                    final CpuHeadroomResult res = mCpuHeadroomCache.get(halParams);
+                    if (res != null) return res;
                 }
             }
             // return from HAL directly
             try {
-                float[] headroom = mPowerHal.getCpuHeadroom(halParams);
-                if (headroom == null || headroom.length == 0) {
-                    Slog.wtf(TAG,
-                            "CPU headroom from Power HAL is invalid: " + Arrays.toString(headroom));
-                    return new float[]{Float.NaN};
+                final CpuHeadroomResult result = mPowerHal.getCpuHeadroom(halParams);
+                if (result == null) {
+                    Slog.wtf(TAG, "CPU headroom from Power HAL is invalid");
+                    return null;
                 }
-                synchronized (mCpuHeadroomLock) {
-                    mCpuHeadroomCache.add(new CpuHeadroomCacheItem(
-                            System.currentTimeMillis() + mCpuHeadroomIntervalMillis,
-                            params, headroom, halParams.pid
-                    ));
+                if (halParams.calculationWindowMillis
+                        == mDefaultCpuHeadroomCalculationWindowMillis) {
+                    synchronized (mCpuHeadroomLock) {
+                        mCpuHeadroomCache.add(halParams, result);
+                    }
                 }
-                return headroom;
-
+                return result;
             } catch (RemoteException e) {
-                return new float[]{Float.NaN};
+                Slog.e(TAG, "Failed to get CPU headroom from Power HAL", e);
+                return null;
             }
         }
 
         @Override
-        public float getGpuHeadroom(@Nullable GpuHeadroomParamsInternal params) {
+        public GpuHeadroomResult getGpuHeadroom(@NonNull GpuHeadroomParamsInternal params) {
             if (mGpuHeadroomIntervalMillis <= 0) {
                 throw new UnsupportedOperationException();
             }
-            GpuHeadroomParams halParams = new GpuHeadroomParams();
-            if (params != null) {
-                halParams.calculationType = params.calculationType;
-            }
-            synchronized (mGpuHeadroomLock) {
-                while (!mGpuHeadroomCache.isEmpty()) {
-                    if (mGpuHeadroomCache.getFirst().isExpired()) {
-                        mGpuHeadroomCache.removeFirst();
-                    } else {
-                        break;
-                    }
-                }
-                for (int i = 0; i < mGpuHeadroomCache.size(); ++i) {
-                    final GpuHeadroomCacheItem item = mGpuHeadroomCache.get(i);
-                    if (item.match(params)) {
-                        item.mExpiredTimeMillis =
-                                System.currentTimeMillis() + mGpuHeadroomIntervalMillis;
-                        mGpuHeadroomCache.remove(i);
-                        mGpuHeadroomCache.add(item);
-                        return item.mHeadroom;
-                    }
+            final GpuHeadroomParams halParams = new GpuHeadroomParams();
+            halParams.calculationType = params.calculationType;
+            halParams.calculationWindowMillis = params.calculationWindowMillis;
+            if (halParams.calculationWindowMillis
+                    == mDefaultGpuHeadroomCalculationWindowMillis) {
+                synchronized (mGpuHeadroomLock) {
+                    final GpuHeadroomResult res = mGpuHeadroomCache.get(halParams);
+                    if (res != null) return res;
                 }
             }
             // return from HAL directly
             try {
-                float headroom = mPowerHal.getGpuHeadroom(halParams);
-                if (Float.isNaN(headroom)) {
-                    Slog.wtf(TAG,
-                            "GPU headroom from Power HAL is NaN");
-                    return Float.NaN;
+                final GpuHeadroomResult headroom = mPowerHal.getGpuHeadroom(halParams);
+                if (headroom == null) {
+                    Slog.wtf(TAG, "GPU headroom from Power HAL is invalid");
+                    return null;
                 }
-                synchronized (mGpuHeadroomLock) {
-                    mGpuHeadroomCache.add(new GpuHeadroomCacheItem(
-                            System.currentTimeMillis() + mGpuHeadroomIntervalMillis,
-                            params, headroom
-                    ));
+                if (halParams.calculationWindowMillis
+                        == mDefaultGpuHeadroomCalculationWindowMillis) {
+                    synchronized (mGpuHeadroomLock) {
+                        mGpuHeadroomCache.add(halParams, headroom);
+                    }
                 }
                 return headroom;
             } catch (RemoteException e) {
-                return Float.NaN;
+                Slog.e(TAG, "Failed to get GPU headroom from Power HAL", e);
+                return null;
             }
         }
 
         @Override
-        public long getCpuHeadroomMinIntervalMillis() throws RemoteException {
+        public long getCpuHeadroomMinIntervalMillis() {
             if (mCpuHeadroomIntervalMillis <= 0) {
                 throw new UnsupportedOperationException();
             }
@@ -1457,7 +1558,7 @@
         }
 
         @Override
-        public long getGpuHeadroomMinIntervalMillis() throws RemoteException {
+        public long getGpuHeadroomMinIntervalMillis() {
             if (mGpuHeadroomIntervalMillis <= 0) {
                 throw new UnsupportedOperationException();
             }
@@ -1470,6 +1571,7 @@
                 return;
             }
             pw.println("HintSessionPreferredRate: " + mHintSessionPreferredRate);
+            pw.println("MaxGraphicsPipelineThreadsCount: " + MAX_GRAPHICS_PIPELINE_THREADS_COUNT);
             pw.println("HAL Support: " + isHalSupported());
             pw.println("Active Sessions:");
             synchronized (mLock) {
@@ -1492,21 +1594,66 @@
                 CpuHeadroomParamsInternal params = new CpuHeadroomParamsInternal();
                 params.selectionType = CpuHeadroomParams.SelectionType.ALL;
                 params.usesDeviceHeadroom = true;
-                pw.println("CPU headroom: " + Arrays.toString(getCpuHeadroom(params)));
+                CpuHeadroomResult ret = getCpuHeadroom(params);
+                pw.println("CPU headroom: " + (ret == null ? "N/A" : ret.getGlobalHeadroom()));
                 params = new CpuHeadroomParamsInternal();
                 params.selectionType = CpuHeadroomParams.SelectionType.PER_CORE;
                 params.usesDeviceHeadroom = true;
-                pw.println("CPU headroom per core: " + Arrays.toString(getCpuHeadroom(params)));
+                ret = getCpuHeadroom(params);
+                pw.println("CPU headroom per core: " + (ret == null ? "N/A"
+                        : Arrays.toString(ret.getPerCoreHeadroom())));
             } catch (Exception e) {
+                Slog.d(TAG, "Failed to dump CPU headroom", e);
                 pw.println("CPU headroom: N/A");
             }
             try {
-                pw.println("GPU headroom: " + getGpuHeadroom(null));
+                GpuHeadroomResult ret = getGpuHeadroom(new GpuHeadroomParamsInternal());
+                pw.println("GPU headroom: " + (ret == null ? "N/A" : ret.getGlobalHeadroom()));
             } catch (Exception e) {
+                Slog.d(TAG, "Failed to dump GPU headroom", e);
                 pw.println("GPU headroom: N/A");
             }
         }
 
+        private boolean checkGraphicsPipelineValid(SessionCreationConfig creationConfig, int uid) {
+            if (creationConfig.modesToEnable == null) {
+                return true;
+            }
+            boolean setGraphicsPipeline = false;
+            for (int modeToEnable : creationConfig.modesToEnable) {
+                if (modeToEnable == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+                    setGraphicsPipeline = true;
+                }
+            }
+            if (!setGraphicsPipeline) {
+                return true;
+            }
+
+            synchronized (mThreadsUsageObject) {
+                // count used graphics pipeline threads for the calling UID
+                // consider the case that new tids are overlapping with in session tids
+                ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(uid);
+                if (threadsSet == null) {
+                    return true;
+                }
+
+                final int newThreadCount = creationConfig.tids.length;
+                int graphicsPipelineThreadCount = 0;
+                for (ThreadUsageTracker t : threadsSet) {
+                    // count graphics pipeline threads in use
+                    // and exclude overlapping ones
+                    if (t.isGraphicsPipeline()) {
+                        graphicsPipelineThreadCount++;
+                        if (contains(creationConfig.tids, t.getTid())) {
+                            graphicsPipelineThreadCount--;
+                        }
+                    }
+                }
+                return graphicsPipelineThreadCount + newThreadCount
+                        <= MAX_GRAPHICS_PIPELINE_THREADS_COUNT;
+            }
+        }
+
         private void logPerformanceHintSessionAtom(int uid, long sessionId,
                 long targetDuration, int[] tids, @SessionTag int sessionTag) {
             FrameworkStatsLog.write(FrameworkStatsLog.PERFORMANCE_HINT_SESSION_REPORTED, uid,
@@ -1537,11 +1684,14 @@
         protected boolean mUpdateAllowedByProcState;
         protected int[] mNewThreadIds;
         protected boolean mPowerEfficient;
+        protected boolean mGraphicsPipeline;
         protected boolean mHasBeenPowerEfficient;
+        protected boolean mHasBeenGraphicsPipeline;
         protected boolean mShouldForcePause;
 
-        private enum SessionModes {
+        enum SessionModes {
             POWER_EFFICIENCY,
+            GRAPHICS_PIPELINE,
         };
 
         protected AppHintSession(
@@ -1556,7 +1706,9 @@
             mTargetDurationNanos = durationNanos;
             mUpdateAllowedByProcState = true;
             mPowerEfficient = false;
+            mGraphicsPipeline = false;
             mHasBeenPowerEfficient = false;
+            mHasBeenGraphicsPipeline = false;
             mShouldForcePause = false;
             final boolean allowed = mUidObserver.isUidForeground(mUid);
             updateHintAllowedByProcState(allowed);
@@ -1677,6 +1829,25 @@
                 }
                 sessionSnapshot.updateUponSessionClose();
             }
+
+            if (mGraphicsPipeline) {
+                synchronized (mThreadsUsageObject) {
+                    ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(mUid);
+                    if (threadsSet == null) {
+                        Slogf.w(TAG, "Threads Set is null for uid " + mUid);
+                        return;
+                    }
+                    // remove all tids associated with this session
+                    for (int i = 0; i < threadsSet.size(); ++i) {
+                        if (contains(mThreadIds, threadsSet.valueAt(i).getTid())) {
+                            threadsSet.removeAt(i);
+                        }
+                    }
+                    if (threadsSet.isEmpty()) {
+                        mThreadsUsageMap.remove(mUid);
+                    }
+                }
+            }
             if (powerhintThreadCleanup()) {
                 synchronized (mNonIsolatedTidsLock) {
                     final int[] tids = getTidsInternal();
@@ -1713,6 +1884,33 @@
                 throw new IllegalArgumentException("Thread id list can't be empty.");
             }
 
+
+            final int callingUid = Binder.getCallingUid();
+            if (mGraphicsPipeline) {
+                synchronized (mThreadsUsageObject) {
+                    // replace original tids with new tids
+                    ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(callingUid);
+                    int graphicsPipelineThreadCount = 0;
+                    if (threadsSet != null) {
+                        // We count the graphics pipeline threads that are
+                        // *not* in this session, since those in this session
+                        // will be replaced. Then if the count plus the new tids
+                        // is over max available graphics pipeline threads we raise
+                        // an exception.
+                        for (ThreadUsageTracker t : threadsSet) {
+                            if (t.isGraphicsPipeline() && !contains(mThreadIds, t.getTid())) {
+                                graphicsPipelineThreadCount++;
+                            }
+                        }
+                        if (graphicsPipelineThreadCount + tids.length
+                                > MAX_GRAPHICS_PIPELINE_THREADS_COUNT) {
+                            throw new IllegalArgumentException(
+                                    "Not enough available graphics pipeline threads.");
+                        }
+                    }
+                }
+            }
+
             synchronized (this) {
                 if (mHalSessionPtr == 0) {
                     return;
@@ -1724,7 +1922,6 @@
                     return;
                 }
                 if (checkTid) {
-                    final int callingUid = Binder.getCallingUid();
                     final int callingTgid = Process.getThreadGroupLeader(Binder.getCallingPid());
                     final IntArray nonIsolated = powerhintThreadCleanup() ? new IntArray() : null;
                     final long identity = Binder.clearCallingIdentity();
@@ -1770,6 +1967,23 @@
                     }
                 }
                 mNativeWrapper.halSetThreads(mHalSessionPtr, tids);
+
+                synchronized (mThreadsUsageObject) {
+                    // replace old tids with new ones
+                    ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(callingUid);
+                    if (threadsSet == null) {
+                        mThreadsUsageMap.put(callingUid, new ArraySet<ThreadUsageTracker>());
+                        threadsSet = mThreadsUsageMap.get(callingUid);
+                    }
+                    for (int i = 0; i < threadsSet.size(); ++i) {
+                        if (contains(mThreadIds, threadsSet.valueAt(i).getTid())) {
+                            threadsSet.removeAt(i);
+                        }
+                    }
+                    for (int tid : tids) {
+                        threadsSet.add(new ThreadUsageTracker(tid, mGraphicsPipeline));
+                    }
+                }
                 mThreadIds = tids;
                 mNewThreadIds = null;
                 // if the update is allowed but the session is force paused by tid clean up, then
@@ -1831,26 +2045,49 @@
                         + " greater than zero.");
                 if (mode == SessionModes.POWER_EFFICIENCY.ordinal()) {
                     mPowerEfficient = enabled;
+                } else if (mode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+                    mGraphicsPipeline = enabled;
                 }
                 mNativeWrapper.halSetMode(mHalSessionPtr, mode, enabled);
             }
-            if (enabled && (mode == SessionModes.POWER_EFFICIENCY.ordinal())) {
-                if (!mHasBeenPowerEfficient) {
-                    mHasBeenPowerEfficient = true;
-                    synchronized (mSessionSnapshotMapLock) {
-                        ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
-                                mSessionSnapshotMap.get(mUid);
-                        if (sessionSnapshots == null) {
-                            Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
-                            return;
+            if (enabled) {
+                if (mode == SessionModes.POWER_EFFICIENCY.ordinal()) {
+                    if (!mHasBeenPowerEfficient) {
+                        mHasBeenPowerEfficient = true;
+                        synchronized (mSessionSnapshotMapLock) {
+                            ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
+                                    mSessionSnapshotMap.get(mUid);
+                            if (sessionSnapshots == null) {
+                                Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
+                                return;
+                            }
+                            AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
+                            if (sessionSnapshot == null) {
+                                Slogf.w(TAG, "Session snapshot is null for uid " + mUid
+                                        + " and tag " + mTag);
+                                return;
+                            }
+                            sessionSnapshot.logPowerEfficientSession();
                         }
-                        AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
-                        if (sessionSnapshot == null) {
-                            Slogf.w(TAG, "Session snapshot is null for uid " + mUid
-                                    + " and tag " + mTag);
-                            return;
+                    }
+                } else if (mode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+                    if (!mHasBeenGraphicsPipeline) {
+                        mHasBeenGraphicsPipeline = true;
+                        synchronized (mSessionSnapshotMapLock) {
+                            ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
+                                    mSessionSnapshotMap.get(mUid);
+                            if (sessionSnapshots == null) {
+                                Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
+                                return;
+                            }
+                            AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
+                            if (sessionSnapshot == null) {
+                                Slogf.w(TAG, "Session snapshot is null for uid " + mUid
+                                        + " and tag " + mTag);
+                                return;
+                            }
+                            sessionSnapshot.logGraphicsPipelineSession();
                         }
-                        sessionSnapshot.logPowerEfficientSession();
                     }
                 }
             }
@@ -1877,6 +2114,12 @@
             }
         }
 
+        public boolean isGraphicsPipeline() {
+            synchronized (this) {
+                return mGraphicsPipeline;
+            }
+        }
+
         public int getUid() {
             return mUid;
         }
@@ -1964,6 +2207,7 @@
                 pw.println(prefix + "SessionAllowedByProcState: " + mUpdateAllowedByProcState);
                 pw.println(prefix + "SessionForcePaused: " + mShouldForcePause);
                 pw.println(prefix + "PowerEfficient: " + (mPowerEfficient ? "true" : "false"));
+                pw.println(prefix + "GraphicsPipeline: " + (mGraphicsPipeline ? "true" : "false"));
             }
         }
 
diff --git a/services/core/java/com/android/server/power/hint/adpf_flags.aconfig b/services/core/java/com/android/server/power/hint/adpf_flags.aconfig
new file mode 100644
index 0000000..147d76b
--- /dev/null
+++ b/services/core/java/com/android/server/power/hint/adpf_flags.aconfig
@@ -0,0 +1,7 @@
+# New location for generic ADPF flags across the system
+# This will be moved to the top-level frameworks/base adpf library
+# once it lands
+
+package: "android.adpf"
+container: "system"
+
diff --git a/services/core/java/com/android/server/power/hint/flags.aconfig b/services/core/java/com/android/server/power/hint/flags.aconfig
index e56b68c..c231f5a 100644
--- a/services/core/java/com/android/server/power/hint/flags.aconfig
+++ b/services/core/java/com/android/server/power/hint/flags.aconfig
@@ -21,3 +21,10 @@
     description: "Set reset_on_fork flag."
     bug: "370988407"
 }
+
+flag {
+    name: "cpu_headroom_affinity_check"
+    namespace: "game"
+    description: "Check affinity on CPU headroom."
+    bug: "346604998"
+}
diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
index 606bd1d..63e8d99 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -26,6 +26,7 @@
 import android.os.Handler;
 import android.os.Process;
 import android.util.Log;
+import android.util.LogWriter;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -34,6 +35,7 @@
 import com.android.internal.os.MonotonicClock;
 import com.android.internal.os.PowerProfile;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -44,6 +46,8 @@
  */
 public class BatteryUsageStatsProvider {
     private static final String TAG = "BatteryUsageStatsProv";
+    private static final boolean DEBUG = false;
+
     private final Context mContext;
     private final PowerAttributor mPowerAttributor;
     private final PowerStatsStore mPowerStatsStore;
@@ -262,17 +266,25 @@
 
     private BatteryUsageStats getBatteryUsageStats(BatteryStatsImpl stats,
             BatteryUsageStatsQuery query, long currentTimeMs) {
+        BatteryUsageStats batteryUsageStats;
         if ((query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_ACCUMULATED) != 0) {
-            return getAccumulatedBatteryUsageStats(stats, query, currentTimeMs);
+            batteryUsageStats = getAccumulatedBatteryUsageStats(stats, query, currentTimeMs);
         } else if (query.getAggregatedToTimestamp() == 0) {
             BatteryUsageStats.Builder builder = computeBatteryUsageStats(stats, query,
                     query.getMonotonicStartTime(),
                     query.getMonotonicEndTime(), currentTimeMs);
-            return builder.build();
+            batteryUsageStats = builder.build();
         } else {
-            return getAggregatedBatteryUsageStats(stats, query);
+            batteryUsageStats = getAggregatedBatteryUsageStats(stats, query);
         }
+        if (DEBUG) {
+            Slog.d(TAG, "query = " + query);
+            PrintWriter pw = new PrintWriter(new LogWriter(Log.DEBUG, TAG));
+            batteryUsageStats.dump(pw, "");
+            pw.flush();
+        }
+        return batteryUsageStats;
     }
 
     private BatteryUsageStats getAccumulatedBatteryUsageStats(BatteryStatsImpl stats,
@@ -319,7 +331,7 @@
 
         if (accumulatedStats.builder == null) {
             accumulatedStats.builder = new BatteryUsageStats.Builder(
-                    stats.getCustomEnergyConsumerNames(), false, true, true, true, 0);
+                    stats.getCustomEnergyConsumerNames(), true, true, true, 0);
             accumulatedStats.startWallClockTime = stats.getStartClockTime();
             accumulatedStats.builder.setStatsStartTimestamp(accumulatedStats.startWallClockTime);
         }
@@ -338,8 +350,6 @@
     private BatteryUsageStats.Builder computeBatteryUsageStats(BatteryStatsImpl stats,
             BatteryUsageStatsQuery query, long monotonicStartTime, long monotonicEndTime,
             long currentTimeMs) {
-        final boolean includePowerModels = (query.getFlags()
-                & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0;
         final boolean includeProcessStateData = ((query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0)
                 && stats.isProcessStateDataAvailable();
@@ -353,8 +363,7 @@
         }
 
         final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder(
-                customEnergyConsumerNames, includePowerModels,
-                includeProcessStateData, query.isScreenStateDataNeeded(),
+                customEnergyConsumerNames, includeProcessStateData, query.isScreenStateDataNeeded(),
                 query.isPowerStateDataNeeded(), minConsumedPowerThreshold);
 
         synchronized (stats) {
@@ -444,8 +453,6 @@
 
     private BatteryUsageStats getAggregatedBatteryUsageStats(BatteryStatsImpl stats,
             BatteryUsageStatsQuery query) {
-        final boolean includePowerModels = (query.getFlags()
-                & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0;
         final boolean includeProcessStateData = ((query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0)
                 && stats.isProcessStateDataAvailable();
@@ -453,7 +460,7 @@
 
         final String[] customEnergyConsumerNames = stats.getCustomEnergyConsumerNames();
         final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
-                customEnergyConsumerNames, includePowerModels, includeProcessStateData,
+                customEnergyConsumerNames, includeProcessStateData,
                 query.isScreenStateDataNeeded(), query.isPowerStateDataNeeded(),
                 minConsumedPowerThreshold);
         if (mPowerStatsStore == null) {
diff --git a/services/core/java/com/android/server/power/stats/processor/PowerStatsExporter.java b/services/core/java/com/android/server/power/stats/processor/PowerStatsExporter.java
index b2442c8..ef0e63b 100644
--- a/services/core/java/com/android/server/power/stats/processor/PowerStatsExporter.java
+++ b/services/core/java/com/android/server/power/stats/processor/PowerStatsExporter.java
@@ -224,13 +224,12 @@
         BatteryConsumer.Key key = getKeyForPartialTotal(batteryUsageStatsBuilder, deviceScope,
                 powerComponentId, screenState, powerState);
         if (key != null) {
-            deviceScope.addConsumedPower(key, totalPower[0],
-                    BatteryConsumer.POWER_MODEL_UNDEFINED);
+            deviceScope.addConsumedPower(key, totalPower[0]);
             deviceScope.addUsageDurationMillis(key, durationMs[0]);
         }
         key = deviceScope.getKey(powerComponentId, BatteryConsumer.PROCESS_STATE_UNSPECIFIED);
         if (key != null) {
-            deviceScope.addConsumedPower(key, totalPower[0], BatteryConsumer.POWER_MODEL_UNDEFINED);
+            deviceScope.addConsumedPower(key, totalPower[0]);
             deviceScope.addUsageDurationMillis(key, durationMs[0]);
         }
     }
@@ -373,7 +372,7 @@
                 BatteryConsumer.Key key = builder.getKey(powerComponentId, procState,
                         resultScreenState, resultPowerState);
                 if (key != null) {
-                    builder.addConsumedPower(key, power, BatteryConsumer.POWER_MODEL_UNDEFINED);
+                    builder.addConsumedPower(key, power);
                     builder.addUsageDurationMillis(key, duration);
                 }
             }
@@ -384,8 +383,7 @@
                         BatteryConsumer.PROCESS_STATE_UNSPECIFIED);
                 if (key != null) {
                     builder.addConsumedPower(key,
-                            powerByProcState[BatteryConsumer.PROCESS_STATE_UNSPECIFIED],
-                            BatteryConsumer.POWER_MODEL_UNDEFINED);
+                            powerByProcState[BatteryConsumer.PROCESS_STATE_UNSPECIFIED]);
                     builder.addUsageDurationMillis(key,
                             durationByProcState[BatteryConsumer.PROCESS_STATE_UNSPECIFIED]);
                 }
@@ -399,11 +397,9 @@
         BatteryConsumer.Key key = getKeyForPartialTotal(batteryUsageStatsBuilder, allAppsScope,
                 powerComponentId, screenState, powerState);
         if (key != null) {
-            allAppsScope.addConsumedPower(key, powerAllApps,
-                    BatteryConsumer.POWER_MODEL_UNDEFINED);
+            allAppsScope.addConsumedPower(key, powerAllApps);
         }
-        allAppsScope.addConsumedPower(powerComponentId, powerAllApps,
-                BatteryConsumer.POWER_MODEL_UNDEFINED);
+        allAppsScope.addConsumedPower(powerComponentId, powerAllApps);
     }
 
     @Nullable
diff --git a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
index e780be4..2cc08c3 100644
--- a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
+++ b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
@@ -46,7 +46,9 @@
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.security.advancedprotection.features.AdvancedProtectionHook;
 import com.android.server.security.advancedprotection.features.AdvancedProtectionProvider;
+import com.android.server.security.advancedprotection.features.DisallowCellular2GAdvancedProtectionHook;
 import com.android.server.security.advancedprotection.features.DisallowInstallUnknownSourcesAdvancedProtectionHook;
+import com.android.server.security.advancedprotection.features.MemoryTaggingExtensionHook;
 
 import java.io.FileDescriptor;
 import java.util.ArrayList;
@@ -80,6 +82,12 @@
         if (android.security.Flags.aapmFeatureDisableInstallUnknownSources()) {
             mHooks.add(new DisallowInstallUnknownSourcesAdvancedProtectionHook(mContext, enabled));
         }
+        if (android.security.Flags.aapmFeatureMemoryTaggingExtension()) {
+            mHooks.add(new MemoryTaggingExtensionHook(mContext, enabled));
+        }
+        if (android.security.Flags.aapmFeatureDisableCellular2g()) {
+            mHooks.add(new DisallowCellular2GAdvancedProtectionHook(mContext, enabled));
+        }
     }
 
     // Only for tests
@@ -141,7 +149,7 @@
     }
 
     @Override
-    @EnforcePermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+    @EnforcePermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
     public void setAdvancedProtectionEnabled(boolean enabled) {
         setAdvancedProtectionEnabled_enforcePermission();
         final long identity = Binder.clearCallingIdentity();
@@ -159,7 +167,7 @@
     }
 
     @Override
-    @EnforcePermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+    @EnforcePermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
     public List<AdvancedProtectionFeature> getAdvancedProtectionFeatures() {
         getAdvancedProtectionFeatures_enforcePermission();
         List<AdvancedProtectionFeature> features = new ArrayList<>();
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java
new file mode 100644
index 0000000..b9c8d3d
--- /dev/null
+++ b/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java
@@ -0,0 +1,86 @@
+/*
+ * 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.security.advancedprotection.features;
+
+import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY;
+import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G;
+
+import android.annotation.NonNull;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.UserManager;
+import android.security.advancedprotection.AdvancedProtectionFeature;
+import android.telephony.TelephonyManager;
+import android.util.Slog;
+
+/** @hide */
+public final class DisallowCellular2GAdvancedProtectionHook extends AdvancedProtectionHook {
+    private static final String TAG = "AdvancedProtectionDisallowCellular2G";
+
+    private final AdvancedProtectionFeature mFeature =
+            new AdvancedProtectionFeature(FEATURE_ID_DISALLOW_CELLULAR_2G);
+    private final DevicePolicyManager mDevicePolicyManager;
+    private final TelephonyManager mTelephonyManager;
+
+    public DisallowCellular2GAdvancedProtectionHook(@NonNull Context context, boolean enabled) {
+        super(context, enabled);
+        mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
+        mTelephonyManager = context.getSystemService(TelephonyManager.class);
+
+        setPolicy(enabled);
+    }
+
+    @NonNull
+    @Override
+    public AdvancedProtectionFeature getFeature() {
+        return mFeature;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return mTelephonyManager.isDataCapable();
+    }
+
+    private void setPolicy(boolean enabled) {
+        Slog.i(TAG, "setPolicy called with " + enabled);
+
+        if (enabled) {
+            Slog.d(TAG, "Setting DISALLOW_CELLULAR_2G_GLOBALLY restriction");
+            mDevicePolicyManager.addUserRestrictionGlobally(
+                    ADVANCED_PROTECTION_SYSTEM_ENTITY, UserManager.DISALLOW_CELLULAR_2G);
+        } else {
+            Slog.d(TAG, "Clearing DISALLOW_CELLULAR_2G_GLOBALLY restriction");
+            mDevicePolicyManager.clearUserRestrictionGlobally(
+                    ADVANCED_PROTECTION_SYSTEM_ENTITY, UserManager.DISALLOW_CELLULAR_2G);
+        }
+    }
+
+    @Override
+    public void onAdvancedProtectionChanged(boolean enabled) {
+        setPolicy(enabled);
+
+        // Leave 2G disabled even if APM is disabled.
+        if (!enabled) {
+            long oldAllowedTypes =
+                    mTelephonyManager.getAllowedNetworkTypesForReason(
+                            TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G);
+            long newAllowedTypes = oldAllowedTypes & ~TelephonyManager.NETWORK_CLASS_BITMASK_2G;
+            mTelephonyManager.setAllowedNetworkTypesForReason(
+                    TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G, newAllowedTypes);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/MemoryTaggingExtensionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/MemoryTaggingExtensionHook.java
new file mode 100644
index 0000000..d3d3937
--- /dev/null
+++ b/services/core/java/com/android/server/security/advancedprotection/features/MemoryTaggingExtensionHook.java
@@ -0,0 +1,81 @@
+/*
+ * 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.security.advancedprotection.features;
+
+import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY;
+import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_ENABLE_MTE;
+
+import android.annotation.NonNull;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.SystemProperties;
+import android.security.advancedprotection.AdvancedProtectionFeature;
+import android.util.Slog;
+
+/** @hide */
+public final class MemoryTaggingExtensionHook
+        extends AdvancedProtectionHook {
+    private static final String TAG = "AdvancedProtectionMTE";
+    private static final String MTE_DPM_SYSTEM_PROPERTY =
+            "ro.arm64.memtag.bootctl_device_policy_manager";
+    private static final String MTE_SETTINGS_SYSTEM_PROPERTY =
+            "ro.arm64.memtag.bootctl_settings_toggle";
+
+    private final AdvancedProtectionFeature mFeature = new AdvancedProtectionFeature(
+            FEATURE_ID_ENABLE_MTE);
+    private final DevicePolicyManager mDevicePolicyManager;
+
+    public MemoryTaggingExtensionHook(@NonNull Context context,
+            boolean enabled) {
+        super(context, enabled);
+        mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
+        onAdvancedProtectionChanged(enabled);
+    }
+
+    @NonNull
+    @Override
+    public AdvancedProtectionFeature getFeature() {
+        return mFeature;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return SystemProperties.getBoolean(MTE_DPM_SYSTEM_PROPERTY,
+                SystemProperties.getBoolean(MTE_SETTINGS_SYSTEM_PROPERTY, false));
+    }
+
+    @Override
+    public void onAdvancedProtectionChanged(boolean enabled) {
+        if (!isAvailable()) {
+            Slog.i(TAG, "MTE unavailable on device, skipping.");
+            return;
+        }
+        final int mtePolicy;
+        if (enabled) {
+            mtePolicy = DevicePolicyManager.MTE_ENABLED;
+        } else {
+            mtePolicy = DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY;
+        }
+
+        Slog.d(TAG, "Setting MTE state to " + mtePolicy);
+        try {
+            mDevicePolicyManager.setMtePolicy(ADVANCED_PROTECTION_SYSTEM_ENTITY, mtePolicy);
+        } catch (UnsupportedOperationException e) {
+            Slog.i(TAG, "Setting MTE policy unsupported", e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java b/services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java
index 06e9dcd..0ea88e8 100644
--- a/services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java
@@ -36,6 +36,9 @@
     private static final int MSG_DISABLE = 2;
 
     private static final int STORED_EVENTS_SIZE_LIMIT = 1024;
+    private static final IntrusionDetectionAdminReceiver ADMIN_RECEIVER =
+            new IntrusionDetectionAdminReceiver();
+
     private final IntrusionDetectionService mIntrusionDetectionService;
     private final ArrayList<DataSource> mDataSources;
 
@@ -60,10 +63,19 @@
      * Initialize DataSources
      * @return Whether the initialization succeeds.
      */
-    // TODO: Add the corresponding data sources
     public boolean initialize() {
         SecurityLogSource securityLogSource = new SecurityLogSource(mContext, this);
         mDataSources.add(securityLogSource);
+
+        NetworkLogSource networkLogSource = new NetworkLogSource(mContext, this);
+        ADMIN_RECEIVER.setNetworkLogEventCallback(networkLogSource);
+        mDataSources.add(networkLogSource);
+
+        for (DataSource ds : mDataSources) {
+            if (!ds.initialize()) {
+                return false;
+            }
+        }
         return true;
     }
 
diff --git a/services/core/java/com/android/server/security/intrusiondetection/DataSource.java b/services/core/java/com/android/server/security/intrusiondetection/DataSource.java
index 0bc4482..61fac46 100644
--- a/services/core/java/com/android/server/security/intrusiondetection/DataSource.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/DataSource.java
@@ -18,6 +18,11 @@
 
 public interface DataSource {
     /**
+     * Initialize the data source.
+     */
+    boolean initialize();
+
+    /**
      * Enable the data collection.
      */
     void enable();
diff --git a/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionAdminReceiver.java b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionAdminReceiver.java
new file mode 100644
index 0000000..dba7374
--- /dev/null
+++ b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionAdminReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * 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.security.intrusiondetection;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Slog;
+
+public class IntrusionDetectionAdminReceiver extends DeviceAdminReceiver {
+    private static final String TAG = "IntrusionDetectionAdminReceiver";
+
+    private static NetworkLogSource sNetworkLogSource;
+
+    @Override
+    public void onNetworkLogsAvailable(
+            Context context, Intent intent, long batchToken, int networkLogsCount) {
+        if (sNetworkLogSource != null) {
+            sNetworkLogSource.onNetworkLogsAvailable(batchToken);
+        } else {
+            Slog.w(TAG, "Network log receiver is not initialized");
+        }
+    }
+
+    public void setNetworkLogEventCallback(NetworkLogSource networkLogSource) {
+        sNetworkLogSource = networkLogSource;
+    }
+}
diff --git a/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
index 82f39b3..b25656e 100644
--- a/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
@@ -60,7 +60,7 @@
         if (!bindService()) {
             return false;
         }
-        AndroidFuture<Integer> resultFuture = new AndroidFuture<>();
+        AndroidFuture<Boolean> resultFuture = new AndroidFuture<>();
         try {
             mService.initialize(resultFuture);
         } catch (RemoteException e) {
@@ -68,8 +68,8 @@
             unbindService();
             return false;
         }
-        Integer result = getFutureResult(resultFuture);
-        if (result != null && result == 0) {
+        Boolean result = getFutureResult(resultFuture);
+        if (result != null && result == true) {
             return true;
         } else {
             unbindService();
@@ -83,22 +83,22 @@
      * @return Whether the data is added to the binder service.
      */
     public boolean addData(List<IntrusionDetectionEvent> data) {
-        AndroidFuture<Integer> resultFuture = new AndroidFuture<>();
+        AndroidFuture<Boolean> resultFuture = new AndroidFuture<>();
         try {
             mService.addData(data, resultFuture);
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote Exception", e);
             return false;
         }
-        Integer result = getFutureResult(resultFuture);
-        return result != null && result == 0;
+        Boolean result = getFutureResult(resultFuture);
+        return result != null && result == true;
     }
 
     /**
      * Release the BackupTransport binder service.
      */
     public void release() {
-        AndroidFuture<Integer> resultFuture = new AndroidFuture<>();
+        AndroidFuture<Boolean> resultFuture = new AndroidFuture<>();
         try {
             mService.release(resultFuture);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java b/services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java
new file mode 100644
index 0000000..1c93d3f
--- /dev/null
+++ b/services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java
@@ -0,0 +1,134 @@
+/*
+ * 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.security.intrusiondetection;
+
+import android.app.admin.ConnectEvent;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.DnsEvent;
+import android.app.admin.NetworkEvent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
+import android.util.Slog;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class NetworkLogSource implements DataSource {
+
+    private static final String TAG = "IntrusionDetectionEvent NetworkLogSource";
+
+    private DevicePolicyManager mDpm;
+    private ComponentName mAdmin;
+    private DataAggregator mDataAggregator;
+
+    public NetworkLogSource(Context context, DataAggregator dataAggregator) {
+        mDataAggregator = dataAggregator;
+        mDpm = context.getSystemService(DevicePolicyManager.class);
+        mAdmin = new ComponentName(context, IntrusionDetectionAdminReceiver.class);
+    }
+
+    @Override
+    public boolean initialize() {
+        try {
+            if (!mDpm.isAdminActive(mAdmin)) {
+                Slog.e(TAG, "Admin " + mAdmin.flattenToString() + "is not active admin");
+                return false;
+            }
+        } catch (SecurityException e) {
+            Slog.e(TAG, "Security exception in initialize: ", e);
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public void enable() {
+        enableNetworkLog();
+    }
+
+    @Override
+    public void disable() {
+        disableNetworkLog();
+    }
+
+    private void enableNetworkLog() {
+        if (!isNetworkLogEnabled()) {
+            mDpm.setNetworkLoggingEnabled(mAdmin, true);
+        }
+    }
+
+    private void disableNetworkLog() {
+        if (isNetworkLogEnabled()) {
+            mDpm.setNetworkLoggingEnabled(mAdmin, false);
+        }
+    }
+
+    private boolean isNetworkLogEnabled() {
+        return mDpm.isNetworkLoggingEnabled(mAdmin);
+    }
+
+    /**
+     * Retrieve network logs when onNetworkLogsAvailable callback is received.
+     *
+     * @param batchToken The token representing the current batch of network logs.
+     */
+    public void onNetworkLogsAvailable(long batchToken) {
+        List<NetworkEvent> events;
+        try {
+            events = mDpm.retrieveNetworkLogs(mAdmin, batchToken);
+        } catch (SecurityException e) {
+            Slog.e(
+                    TAG,
+                    "Admin "
+                            + mAdmin.flattenToString()
+                            + "does not have permission to retrieve network logs",
+                    e);
+            return;
+        }
+        if (events == null) {
+            if (!isNetworkLogEnabled()) {
+                Slog.w(TAG, "Network logging is disabled");
+            } else {
+                Slog.e(TAG, "Invalid batch token: " + batchToken);
+            }
+            return;
+        }
+
+        List<IntrusionDetectionEvent> intrusionDetectionEvents =
+                events.stream()
+                        .filter(event -> event != null)
+                        .map(event -> toIntrusionDetectionEvent(event))
+                        .collect(Collectors.toList());
+        mDataAggregator.addBatchData(intrusionDetectionEvents);
+    }
+
+    private IntrusionDetectionEvent toIntrusionDetectionEvent(NetworkEvent event) {
+        if (event instanceof DnsEvent) {
+            DnsEvent dnsEvent = (DnsEvent) event;
+            return new IntrusionDetectionEvent(dnsEvent);
+        } else if (event instanceof ConnectEvent) {
+            ConnectEvent connectEvent = (ConnectEvent) event;
+            return new IntrusionDetectionEvent(connectEvent);
+        }
+        throw new IllegalArgumentException(
+                "Invalid event type with ID: "
+                        + event.getId()
+                        + "from package: "
+                        + event.getPackageName());
+    }
+}
diff --git a/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java b/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
index 226f9d8..c5f736e 100644
--- a/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
@@ -22,6 +22,7 @@
 import android.app.admin.SecurityLog.SecurityEvent;
 import android.content.Context;
 import android.security.intrusiondetection.IntrusionDetectionEvent;
+import android.util.Slog;
 
 import java.util.List;
 import java.util.concurrent.Executor;
@@ -33,7 +34,7 @@
 
     private static final String TAG = "IntrusionDetection SecurityLogSource";
 
-    private SecurityEventCallback mEventCallback = new SecurityEventCallback();
+    private SecurityEventCallback mEventCallback;
     private DevicePolicyManager mDpm;
     private Executor mExecutor;
     private DataAggregator mDataAggregator;
@@ -42,10 +43,27 @@
         mDataAggregator = dataAggregator;
         mDpm = context.getSystemService(DevicePolicyManager.class);
         mExecutor = Executors.newSingleThreadExecutor();
-        mEventCallback = new SecurityEventCallback();
     }
 
     @Override
+    public boolean initialize() {
+        // Confirm caller is system and the device is managed. Otherwise logs will
+        // be redacted.
+        try {
+            if (!mDpm.isDeviceManaged()) {
+                Slog.e(TAG, "Caller does not have device owner permissions");
+                return false;
+            }
+        } catch (SecurityException e) {
+            Slog.e(TAG, "Security exception in initialize: ", e);
+            return false;
+        }
+        mEventCallback = new SecurityEventCallback();
+        return true;
+    }
+
+
+    @Override
     @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING)
     public void enable() {
         enableAuditLog();
@@ -72,12 +90,8 @@
         }
     }
 
-    /**
-     * Check if security audit logging is enabled for the caller.
-     *
-     * @return Whether security audit logging is enabled.
-     */
-    public boolean isAuditLogEnabled() {
+    @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING)
+    private boolean isAuditLogEnabled() {
         return mDpm.isAuditLogEnabled();
     }
 
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 887e186..708bca7 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -2528,22 +2528,24 @@
     }
 
     private void notifyDeviceLockedListenersForUser(int userId, boolean locked) {
-        int numListeners = mDeviceLockedStateListeners.beginBroadcast();
-        try {
-            IntStream.range(0, numListeners).forEach(i -> {
-                try {
-                    Integer uid = (Integer) mDeviceLockedStateListeners.getBroadcastCookie(i);
-                    if (userId == uid.intValue()) {
-                        mDeviceLockedStateListeners.getBroadcastItem(i)
-                                .onDeviceLockedStateChanged(locked);
+        synchronized (mDeviceLockedStateListeners) {
+            int numListeners = mDeviceLockedStateListeners.beginBroadcast();
+            try {
+                IntStream.range(0, numListeners).forEach(i -> {
+                    try {
+                        Integer uid = (Integer) mDeviceLockedStateListeners.getBroadcastCookie(i);
+                        if (userId == uid.intValue()) {
+                            mDeviceLockedStateListeners.getBroadcastItem(i)
+                                    .onDeviceLockedStateChanged(locked);
+                        }
+                    } catch (RemoteException re) {
+                        Log.i(TAG, "Service died", re);
                     }
-                } catch (RemoteException re) {
-                    Log.i(TAG, "Service died", re);
-                }
-            });
+                });
 
-        } finally {
-            mDeviceLockedStateListeners.finishBroadcast();
+            } finally {
+                mDeviceLockedStateListeners.finishBroadcast();
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 4589d26..8bcf1a9 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -21,6 +21,7 @@
 import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY;
 import static android.media.tv.flags.Flags.tifUnbindInactiveTis;
 import static android.media.tv.flags.Flags.kidsModeTvdbSharing;
+import static android.media.tv.flags.Flags.hdmiControlEnhancedBehavior;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -44,8 +45,10 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.UserInfo;
 import android.graphics.Rect;
+import android.hardware.hdmi.HdmiClient;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
+import android.hardware.hdmi.HdmiTvClient;
 import android.media.AudioPresentation;
 import android.media.PlaybackParams;
 import android.media.tv.AdBuffer;
@@ -138,6 +141,8 @@
     private static final String PERMISSION_ACCESS_WATCHED_PROGRAMS =
             "com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS";
     private static final long UPDATE_HARDWARE_TIS_BINDING_DELAY_IN_MILLIS = 10 * 1000; // 10 seconds
+    private static final long SET_TV_AS_ACTIVE_SOURCE_IF_NO_REQUEST_DELAY_IN_MILLIS
+            = 10 * 1000; // 10 seconds
 
     // There are two different formats of DVB frontend devices. One is /dev/dvb%d.frontend%d,
     // another one is /dev/dvb/adapter%d/frontend%d. Followings are the patterns for selecting the
@@ -185,6 +190,8 @@
     private final HashSet<String> mExternalInputLoggingDeviceOnScreenDisplayNames =
             new HashSet<String>();
     private final List<String> mExternalInputLoggingDeviceBrandNames = new ArrayList<String>();
+    private HdmiControlManager mHdmiControlManager = null;
+    private HdmiTvClient mHdmiTvClient = null;
 
     public TvInputManagerService(Context context) {
         super(context);
@@ -197,7 +204,12 @@
         mActivityManager =
                 (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
         mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
-
+        mHdmiControlManager = mContext.getSystemService(HdmiControlManager.class);
+        if (mHdmiControlManager == null) {
+            Slog.w(TAG, "HdmiControlManager is null!");
+        } else {
+            mHdmiTvClient = mHdmiControlManager.getTvClient();
+        }
         synchronized (mLock) {
             getOrCreateUserStateLocked(mCurrentUserId);
         }
@@ -208,6 +220,42 @@
     @Override
     public void onStart() {
         publishBinderService(Context.TV_INPUT_SERVICE, new BinderService());
+
+        if (!hdmiControlEnhancedBehavior()) {
+           return;
+        }
+
+        // To ensure the TV claims CEC active source status correctly, a receiver is registered to
+        // monitor wake-up and sleep intents. Upon wake-up, this receiver sends a delayed message
+        // triggering a TIF call into a CEC API to claim TV as the active source.
+        // However, the API call is cancelled if the TV switches inputs or goes to sleep.
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_SCREEN_ON);
+        filter.addAction(Intent.ACTION_SCREEN_OFF);
+        mContext.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                switch (action) {
+                    case Intent.ACTION_SCREEN_ON:
+                        Slog.w(TAG, "The TV woke up.");
+                        mMessageHandler.removeMessages(
+                                MessageHandler.MSG_CHECK_TV_AS_ACTIVE_SOURCE);
+                        Message msg = mMessageHandler
+                                .obtainMessage(MessageHandler.MSG_CHECK_TV_AS_ACTIVE_SOURCE);
+                        mMessageHandler.sendMessageDelayed(msg,
+                                SET_TV_AS_ACTIVE_SOURCE_IF_NO_REQUEST_DELAY_IN_MILLIS);
+                        break;
+                    case Intent.ACTION_SCREEN_OFF:
+                        Slog.w(TAG, "The TV turned off.");
+                        mMessageHandler.removeMessages(
+                                MessageHandler.MSG_CHECK_TV_AS_ACTIVE_SOURCE);
+                        break;
+                    default:
+                        return;
+                }
+            }
+        }, filter);
     }
 
     @Override
@@ -4503,6 +4551,7 @@
         static final int MSG_LOG_WATCH_END = 2;
         static final int MSG_SWITCH_CONTENT_RESOLVER = 3;
         static final int MSG_UPDATE_HARDWARE_TIS_BINDING = 4;
+        static final int MSG_CHECK_TV_AS_ACTIVE_SOURCE = 5;
 
         private ContentResolver mContentResolver;
 
@@ -4575,8 +4624,27 @@
                         args.recycle();
                     }
                     break;
+                case MSG_CHECK_TV_AS_ACTIVE_SOURCE:
+                    synchronized (mLock) {
+                        if (mOnScreenInputId == null) {
+                            assertTvAsCecActiveSourceLocked();
+                            break;
+                        }
+                        // TV that switched to a different input, but not an HDMI input
+                        // (e.g. composite) can also assert active source.
+                        UserState userState = getOrCreateUserStateLocked(mCurrentUserId);
+                        TvInputState inputState = userState.inputMap.get(mOnScreenInputId);
+                        if (inputState == null) {
+                            Slog.w(TAG, "Unexpected null TvInputState.");
+                            break;
+                        }
+                        if (inputState.info.getType() != TvInputInfo.TYPE_HDMI) {
+                            assertTvAsCecActiveSourceLocked();
+                        }
+                    }
+                    break;
                 default: {
-                    Slog.w(TAG, "unhandled message code: " + msg.what);
+                    Slog.w(TAG, "Unhandled message code: " + msg.what);
                     break;
                 }
             }
@@ -4822,6 +4890,30 @@
         }
     }
 
+    @GuardedBy("mLock")
+    private void assertTvAsCecActiveSourceLocked() {
+        if (mHdmiTvClient == null) {
+            Slog.w(TAG, "HdmiTvClient is null!");
+            return;
+        }
+        mHdmiTvClient.selectDevice(HdmiDeviceInfo.DEVICE_TV,
+                mContext.getMainExecutor(),
+                new HdmiClient.OnDeviceSelectedListener() {
+                    @Override
+                    public void onDeviceSelected(int result,
+                            int logicalAddress) {
+                        if (result == HdmiControlManager.RESULT_SUCCESS) {
+                            Slog.w(TAG,
+                                    "Setting TV as the active CEC device was successful.");
+                        } else {
+                            Slog.w(TAG,
+                                    "Setting TV as the active CEC device failed with result "
+                                            + result);
+                        }
+                    }
+                });
+    }
+
     private static class SessionNotFoundException extends IllegalArgumentException {
         public SessionNotFoundException(String name) {
             super(name);
diff --git a/services/core/java/com/android/server/utils/LazyJniRegistrar.java b/services/core/java/com/android/server/utils/LazyJniRegistrar.java
index ac4a92e..6d29e9e 100644
--- a/services/core/java/com/android/server/utils/LazyJniRegistrar.java
+++ b/services/core/java/com/android/server/utils/LazyJniRegistrar.java
@@ -42,6 +42,9 @@
     /** Registers native methods for ConsumerIrService. */
     public static native void registerConsumerIrService();
 
+    /** Registers native methods for GameManagerService. */
+    public static native void registerGameManagerService();
+
     /** Registers native methods for VrManagerService. */
     public static native void registerVrManagerService();
 }
diff --git a/services/core/java/com/android/server/utils/WatchableImpl.java b/services/core/java/com/android/server/utils/WatchableImpl.java
index 8a04ccf..fec4351 100644
--- a/services/core/java/com/android/server/utils/WatchableImpl.java
+++ b/services/core/java/com/android/server/utils/WatchableImpl.java
@@ -33,6 +33,7 @@
     /**
      * The list of observers.
      */
+    @GuardedBy("mObservers")
     protected final ArrayList<Watcher> mObservers = new ArrayList<>();
 
     /**
@@ -83,7 +84,9 @@
      * @return The number of registered observers.
      */
     public int registeredObserverCount() {
-        return mObservers.size();
+        synchronized (mObservers) {
+            return mObservers.size();
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/vibrator/BasicToPwleSegmentAdapter.java b/services/core/java/com/android/server/vibrator/BasicToPwleSegmentAdapter.java
new file mode 100644
index 0000000..54ae047
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/BasicToPwleSegmentAdapter.java
@@ -0,0 +1,327 @@
+/*
+ * 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.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.hardware.vibrator.IVibrator;
+import android.os.VibratorInfo;
+import android.os.vibrator.BasicPwleSegment;
+import android.os.vibrator.Flags;
+import android.os.vibrator.PwleSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.MathUtils;
+import android.util.Pair;
+import android.util.Slog;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Adapts {@link BasicPwleSegment} instances to device-specific {@link PwleSegment}
+ * representations, considering device capabilities such as the supported frequency range
+ * (defined by the intersection points of the frequency-acceleration response curve with the
+ * minimum sensitivity threshold) and the maximum achievable sensitivity level.
+ *
+ * <p>The segments will not be changed if the device doesn't have
+ * {@link IVibrator#CAP_COMPOSE_PWLE_EFFECTS_V2}.
+ */
+final class BasicToPwleSegmentAdapter implements VibrationSegmentsAdapter {
+    private static final String TAG = "BasicToPwleSegmentAdapter";
+    private static final int MIN_REQUIRED_SENSITIVITY_DB_SL = 10;
+    /**
+     * An array of (frequency in Hz, minimum perceptible acceleration in dB) pairs.
+     * Each pair represents the minimum output level (in dB) required for a human to perceive the
+     * vibration at the corresponding frequency.
+     */
+    private static final Pair<Float, Float>[] MIN_PERCEPTIBLE_CURVE = new Pair[]{
+            Pair.create(0.4f, -97.81f), Pair.create(2.0f, -69.86f),
+            Pair.create(3.0f, -62.81f), Pair.create(4.0f, -58.81f),
+            Pair.create(5.0f, -56.69f), Pair.create(6.0f, -54.77f),
+            Pair.create(7.2f, -52.85f), Pair.create(8.0f, -51.77f),
+            Pair.create(8.64f, -50.84f), Pair.create(10.0f, -48.90f),
+            Pair.create(10.37f, -48.52f), Pair.create(12.44f, -46.50f),
+            Pair.create(14.93f, -44.43f), Pair.create(15.0f, -44.35f),
+            Pair.create(17.92f, -41.96f), Pair.create(20.0f, -40.36f),
+            Pair.create(21.5f, -39.60f), Pair.create(25.0f, -37.48f),
+            Pair.create(25.8f, -36.93f), Pair.create(30.0f, -34.31f),
+            Pair.create(35.0f, -33.13f), Pair.create(40.0f, -32.81f),
+            Pair.create(50.0f, -31.94f), Pair.create(60.0f, -31.77f),
+            Pair.create(70.0f, -31.59f), Pair.create(72.0f, -31.55f),
+            Pair.create(80.0f, -31.77f), Pair.create(86.4f, -31.94f),
+            Pair.create(90.0f, -31.73f), Pair.create(100.0f, -31.90f),
+            Pair.create(103.68f, -31.77f), Pair.create(124.42f, -31.70f),
+            Pair.create(149.3f, -31.38f), Pair.create(150.0f, -31.35f),
+            Pair.create(179.16f, -31.02f), Pair.create(200.0f, -30.86f),
+            Pair.create(215.0f, -30.35f), Pair.create(250.0f, -28.98f),
+            Pair.create(258.0f, -28.68f), Pair.create(300.0f, -26.81f),
+            Pair.create(400.0f, -19.81f)
+    };
+    private static final float[] sMinPerceptibleFrequenciesHz =
+            new float[MIN_PERCEPTIBLE_CURVE.length];
+    private static final float[] sMinPerceptibleAccelerationsDb =
+            new float[MIN_PERCEPTIBLE_CURVE.length];
+
+    BasicToPwleSegmentAdapter() {
+
+        // Sort the 'MIN_PERCEPTIBLE_LEVEL' data in ascending order based on the
+        // frequency values (first element of each pair).
+        Arrays.sort(MIN_PERCEPTIBLE_CURVE, Comparator.comparing(pair -> pair.first));
+
+        for (int i = 0; i < MIN_PERCEPTIBLE_CURVE.length; i++) {
+            sMinPerceptibleFrequenciesHz[i] = MIN_PERCEPTIBLE_CURVE[i].first;
+            sMinPerceptibleAccelerationsDb[i] = MIN_PERCEPTIBLE_CURVE[i].second;
+        }
+    }
+
+    @Override
+    public int adaptToVibrator(VibratorInfo info, List<VibrationEffectSegment> segments,
+            int repeatIndex) {
+        if (!Flags.normalizedPwleEffects()
+                || !info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+            // The vibrator does not have PWLE v2 capability, so keep the segments unchanged.
+            return repeatIndex;
+        }
+
+        VibratorInfo.FrequencyProfile frequencyProfile = info.getFrequencyProfile();
+        float[] frequenciesHz = frequencyProfile.getFrequenciesHz();
+        float[] accelerationsGs = frequencyProfile.getOutputAccelerationsGs();
+
+        Pair<Float, Float> frequencyRangeHz = calculateFrequencyRangeHz(
+                Objects.requireNonNull(frequenciesHz), Objects.requireNonNull(accelerationsGs));
+
+        if (frequencyRangeHz == null) {
+            // Failed to retrieve frequency range, so keep the segments unchanged.
+            return repeatIndex;
+        }
+        float minFrequencyHz = frequencyRangeHz.first;
+        float maxFrequencyHz = frequencyRangeHz.second;
+        float maxSensitivityLevel = getMaxSensitivityLevel(frequenciesHz, accelerationsGs,
+                minFrequencyHz, maxFrequencyHz);
+
+        for (int i = 0; i < segments.size(); i++) {
+            VibrationEffectSegment segment = segments.get(i);
+            if (segment instanceof BasicPwleSegment basicPwleSegment) {
+                PwleSegment pwleSegment = convertBasicToPwleSegment(frequencyProfile,
+                        basicPwleSegment, minFrequencyHz, maxFrequencyHz,
+                        maxSensitivityLevel);
+                segments.set(i, pwleSegment);
+            }
+        }
+
+        return repeatIndex;
+    }
+
+    /**
+     * Returns the supported frequency range within which {@link BasicPwleSegment}s are created.
+     * This range, also referred to as the "sharpness range", is defined by the
+     * minimum and maximum frequencies where the actuator's output acceleration exceeds the minimum
+     * required sensitivity level.
+     *
+     * <p>The minimum frequency is the first point where the actuator's frequency to output
+     * acceleration response curve intersects the minimum sensitivity threshold. The maximum
+     * frequency is determined by the second intersection point, or the maximum available
+     * frequency if no second intersection exists.
+     *
+     * @return The supported frequency range, or null if the minimum frequency cannot be determined.
+     */
+    @Nullable
+    private static Pair<Float, Float> calculateFrequencyRangeHz(@NonNull float[] frequenciesHz,
+            @NonNull float[] accelerationsGs) {
+        float minFrequencyHz = Float.NaN;
+        float maxFrequencyHz = Float.NaN;
+
+        for (int i = 0; i < frequenciesHz.length; i++) {
+            float minAcceptableOutputAcceleration = convertSensitivityLevelToAccelerationGs(
+                    MIN_REQUIRED_SENSITIVITY_DB_SL, frequenciesHz[i]);
+
+            if (Float.isNaN(minFrequencyHz)
+                    && minAcceptableOutputAcceleration <= accelerationsGs[i]) {
+                if (i == 0) {
+                    minFrequencyHz = frequenciesHz[0];
+                } else {
+                    minFrequencyHz = MathUtils.constrainedMap(
+                            frequenciesHz[i - 1], frequenciesHz[i],
+                            accelerationsGs[i - 1], accelerationsGs[i],
+                            minAcceptableOutputAcceleration);
+                } // Found the lower bound
+            } else if (!Float.isNaN(minFrequencyHz)
+                    && minAcceptableOutputAcceleration >= accelerationsGs[i]) {
+                maxFrequencyHz = MathUtils.constrainedMap(
+                        frequenciesHz[i - 1], frequenciesHz[i],
+                        accelerationsGs[i - 1], accelerationsGs[i],
+                        minAcceptableOutputAcceleration); // Found the upper bound
+                return new Pair<>(minFrequencyHz, maxFrequencyHz);
+            }
+        }
+
+        if (Float.isNaN(minFrequencyHz)) {
+            // Lower bound was not found
+            Slog.e(TAG,
+                    "Failed to retrieve frequency range. A valid frequency range must be "
+                            + "available to create envelope vibration effects.");
+            return null;
+        }
+
+        // If only the lower bound was found, set the upper bound to the maximum frequency.
+        maxFrequencyHz = frequenciesHz[frequenciesHz.length - 1];
+
+        return new Pair<>(minFrequencyHz, maxFrequencyHz);
+    }
+
+    /**
+     * Converts the {@link BasicPwleSegment} to its equivalent {@link PwleSegment} based on the
+     * devices capabilities.
+     */
+    private static PwleSegment convertBasicToPwleSegment(
+            @NonNull VibratorInfo.FrequencyProfile frequencyProfile,
+            @NonNull BasicPwleSegment basicPwleSegment, float minFrequencyHz, float maxFrequencyHz,
+            float maxSensitivityLevel) {
+
+        float startFrequency = convertSharpnessToFrequencyHz(basicPwleSegment.getStartSharpness(),
+                minFrequencyHz, maxFrequencyHz);
+        float endFrequency = convertSharpnessToFrequencyHz(basicPwleSegment.getEndSharpness(),
+                minFrequencyHz, maxFrequencyHz);
+
+        float startAmplitude = convertIntensityToAmplitude(frequencyProfile,
+                basicPwleSegment.getStartIntensity(), startFrequency, maxSensitivityLevel);
+        float endAmplitude = convertIntensityToAmplitude(frequencyProfile,
+                basicPwleSegment.getEndIntensity(), endFrequency, maxSensitivityLevel);
+
+        return new PwleSegment(startAmplitude, endAmplitude, startFrequency, endFrequency,
+                basicPwleSegment.getDuration());
+    }
+
+    /**
+     * Calculates the amplitude for the vibrator, ranging [0.0, 1.0], based on the desired
+     * intensity and the vibrator's capabilities at the specified frequency.
+     *
+     * <p>This method first converts the desired intensity to an equivalent acceleration value
+     * based on the maximum sensitivity level within the sharpness range. It then compares this
+     * desired acceleration to the maximum acceleration the vibrator can produce at the given
+     * frequency.
+     *
+     * <p>If the desired acceleration exceeds the vibrator's capability, the method returns
+     * 1.0 (maximum amplitude). Otherwise, it returns a normalized amplitude value, calculated as
+     * the ratio of the desired acceleration to the maximum available acceleration at the given
+     * frequency.
+     */
+    private static float convertIntensityToAmplitude(VibratorInfo.FrequencyProfile frequencyProfile,
+            float intensity, float frequencyHz, float maxSensitivityLevel) {
+        if (intensity == 0) {
+            // Zero intensity should map to zero amplitude (i.e. vibrator off)
+            // instead of 0 db SL (i.e. the minimum perceivable output).
+            // This is for consistency with waveform envelopes, to ensure effects
+            // are able to ramp from/to the vibrator off state.
+            return 0;
+        }
+
+        float desiredAcceleration = convertIntensityToAccelerationGs(intensity, frequencyHz,
+                maxSensitivityLevel);
+        float availableAcceleration = frequencyProfile.getOutputAccelerationGs(
+                frequencyHz);
+        return desiredAcceleration >= availableAcceleration ? 1.0f
+                : desiredAcceleration / availableAcceleration;
+    }
+
+    private static float getMaxSensitivityLevel(float[] frequenciesHz, float[] accelerationsGs,
+            float minFrequencyHz, float maxFrequencyHz) {
+        float maxAccelerationGs = Float.MIN_VALUE;
+        int maxAccelerationIndex = -1;
+        for (int i = 0; i < frequenciesHz.length; i++) {
+            float frequency = frequenciesHz[i];
+            if (frequency < minFrequencyHz) {
+                continue;
+            }
+            if (frequency > maxFrequencyHz) {
+                break;
+            }
+            if (accelerationsGs[i] > maxAccelerationGs) {
+                maxAccelerationGs = accelerationsGs[i];
+                maxAccelerationIndex = i;
+            }
+        }
+
+        return convertDecibelToSensitivityLevel(convertAccelerationToDecibel(maxAccelerationGs),
+                frequenciesHz[maxAccelerationIndex]);
+    }
+
+    private static float convertSharpnessToFrequencyHz(float sharpness, float minFrequencyHz,
+            float maxFrequencyHz) {
+        return minFrequencyHz + sharpness * (maxFrequencyHz - minFrequencyHz);
+    }
+
+    private static float convertIntensityToAccelerationGs(float intensity, float frequencyHz,
+            float maxSensitivityLevel) {
+        return convertSensitivityLevelToAccelerationGs(intensity * maxSensitivityLevel,
+                frequencyHz);
+    }
+
+    private static float convertSensitivityLevelToAccelerationGs(float sensitivityLevel,
+            float frequencyHz) {
+        return convertDecibelToAccelerationGs(
+                convertSensitivityLevelToDecibel(sensitivityLevel, frequencyHz));
+    }
+
+    private static float convertDecibelToAccelerationGs(float db) {
+        return (float) Math.pow(10, db / 20);
+    }
+
+    private static float convertSensitivityLevelToDecibel(float sensitivityLevel,
+            float frequencyHz) {
+        float minPerceptibleDbAtFrequency = getMinPerceptibleAccelerationDb(frequencyHz);
+        return sensitivityLevel + minPerceptibleDbAtFrequency;
+    }
+
+    private static float convertAccelerationToDecibel(float accelerationGs) {
+        return (float) (20 * Math.log10(accelerationGs));
+    }
+
+    private static float convertDecibelToSensitivityLevel(float db, float frequencyHz) {
+        float minPerceptibleDbAtFrequency = getMinPerceptibleAccelerationDb(frequencyHz);
+        return db - minPerceptibleDbAtFrequency;
+    }
+
+    /**
+     * Retrieves the minimum perceptible acceleration, in dB, for the specified frequency (hz).
+     */
+    private static float getMinPerceptibleAccelerationDb(float frequencyHz) {
+
+        if (frequencyHz <= sMinPerceptibleFrequenciesHz[0]) {
+            return sMinPerceptibleAccelerationsDb[0];
+        }
+        if (frequencyHz >= sMinPerceptibleFrequenciesHz[sMinPerceptibleFrequenciesHz.length - 1]) {
+            return sMinPerceptibleAccelerationsDb[sMinPerceptibleAccelerationsDb.length - 1];
+        }
+
+        int idx = Arrays.binarySearch(sMinPerceptibleFrequenciesHz, frequencyHz);
+        if (idx >= 0) {
+            return sMinPerceptibleAccelerationsDb[idx];
+        }
+        // This indicates that the value was not found in the list. Adjust index of the
+        // insertion point to be at the lower bound.
+        idx = -idx - 2;
+
+        return MathUtils.constrainedMap(
+                sMinPerceptibleAccelerationsDb[idx],
+                sMinPerceptibleAccelerationsDb[idx + 1],
+                sMinPerceptibleFrequenciesHz[idx], sMinPerceptibleFrequenciesHz[idx + 1],
+                frequencyHz);
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/DeviceAdapter.java b/services/core/java/com/android/server/vibrator/DeviceAdapter.java
index 370f212..e4542b3 100644
--- a/services/core/java/com/android/server/vibrator/DeviceAdapter.java
+++ b/services/core/java/com/android/server/vibrator/DeviceAdapter.java
@@ -67,6 +67,8 @@
                 new SplitSegmentsAdapter(),
                 // Clip amplitudes and frequencies of final segments based on device bandwidth curve
                 new ClippingAmplitudeAndFrequencyAdapter(),
+                // Convert BasicPwleSegments to PwleSegments based on device capabilities
+                new BasicToPwleSegmentAdapter(),
                 // Split Pwle segments based on their duration and device supported limits
                 new SplitPwleSegmentsAdapter()
         );
diff --git a/services/core/java/com/android/server/vibrator/PwleSegmentsValidator.java b/services/core/java/com/android/server/vibrator/PwleSegmentsValidator.java
index 87369aa..85ba38d 100644
--- a/services/core/java/com/android/server/vibrator/PwleSegmentsValidator.java
+++ b/services/core/java/com/android/server/vibrator/PwleSegmentsValidator.java
@@ -18,20 +18,30 @@
 
 import android.hardware.vibrator.IVibrator;
 import android.os.VibratorInfo;
+import android.os.vibrator.BasicPwleSegment;
 import android.os.vibrator.PwleSegment;
 import android.os.vibrator.VibrationEffectSegment;
 
 import java.util.List;
 
 /**
- * Validates Pwle segments to ensure they are compatible with the device's capabilities
- * and adhere to frequency constraints.
+ * Validates {@link PwleSegment} and {@link BasicPwleSegment} instances to ensure they are
+ * compatible with the device's capabilities.
  *
- * <p>The validator verifies that each segment's start and end frequencies fall within
- * the supported range.
- *
- * <p>The segments will be considered invalid of the device does not have
- * {@link IVibrator#CAP_COMPOSE_PWLE_EFFECTS_V2}.
+ * <p>This validator performs the following checks:
+ * <ul>
+ *   <li>For {@link PwleSegment}:
+ *     <ul>
+ *       <li>Verifies that the device supports {@link IVibrator#CAP_COMPOSE_PWLE_EFFECTS_V2}.
+ *       <li>Verifies that each segment's start and end frequencies fall within the supported range.
+ *     </ul>
+ *   </li>
+ *   <li>For {@link BasicPwleSegment}:
+ *     <ul>
+ *       <li>Verifies that the device supports {@link IVibrator#CAP_COMPOSE_PWLE_EFFECTS_V2}.
+ *     </ul>
+ *   </li>
+ * </ul>
  */
 final class PwleSegmentsValidator implements VibrationSegmentsValidator {
 
@@ -43,16 +53,17 @@
         float maxFrequency = info.getFrequencyProfile().getMaxFrequencyHz();
 
         for (VibrationEffectSegment segment : segments) {
-            if (!(segment instanceof PwleSegment pwleSegment)) {
-                continue;
-            }
-
-            if (!hasPwleCapability || pwleSegment.getStartFrequencyHz() < minFrequency
-                    || pwleSegment.getStartFrequencyHz() > maxFrequency
-                    || pwleSegment.getEndFrequencyHz() < minFrequency
-                    || pwleSegment.getEndFrequencyHz() > maxFrequency) {
+            if (segment instanceof BasicPwleSegment && !hasPwleCapability) {
                 return false;
             }
+            if (segment instanceof PwleSegment pwleSegment) {
+                if (!hasPwleCapability || pwleSegment.getStartFrequencyHz() < minFrequency
+                        || pwleSegment.getStartFrequencyHz() > maxFrequency
+                        || pwleSegment.getEndFrequencyHz() < minFrequency
+                        || pwleSegment.getEndFrequencyHz() > maxFrequency) {
+                    return false;
+                }
+            }
         }
 
         return true;
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 9cb8c1a..797a350 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -617,11 +617,11 @@
 
     private void updateRingerMode() {
         synchronized (mLock) {
-            // If audio manager was not loaded yet then assume most restrictive mode.
-            // This will be loaded again as soon as the audio manager is loaded in onSystemReady.
-            mRingerMode = (mAudioManager == null)
-                    ? AudioManager.RINGER_MODE_SILENT
-                    : mAudioManager.getRingerModeInternal();
+            if (mAudioManager == null) {
+                // Service not ready yet or audio service not available, skip this update request.
+                return;
+            }
+            mRingerMode = mAudioManager.getRingerModeInternal();
         }
     }
 
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
index 17a254a..ba0262a 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -194,12 +194,8 @@
                 wallpaper.cropHint.set(0, 0, 0, 0);
                 wpdData.mPadding.set(0, 0, 0, 0);
                 wallpaper.name = "";
-                if (liveWallpaperContentHandling()) {
-                    wallpaper.setDescription(new WallpaperDescription.Builder().setComponent(
-                            mImageWallpaper).build());
-                } else {
-                    wallpaper.setComponent(mImageWallpaper);
-                }
+                // TODO (b/379936272) Find a safe value for wallpaper component. mImageComponent
+                // does not work at least on some platforms.
             } else {
                 if (wallpaper.wallpaperId <= 0) {
                     wallpaper.wallpaperId = makeWallpaperIdLocked();
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index d019516..bbef578 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1513,11 +1513,15 @@
             }
             if (wallpaper.getComponent() != null
                     && isPackageModified(wallpaper.getComponent().getPackageName())) {
+                ServiceInfo serviceInfo = null;
                 try {
-                    mContext.getPackageManager().getServiceInfo(wallpaper.getComponent(),
-                            PackageManager.MATCH_DIRECT_BOOT_AWARE
-                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
-                } catch (NameNotFoundException e) {
+                    serviceInfo = mIPackageManager.getServiceInfo(
+                            wallpaper.getComponent(), PackageManager.MATCH_DIRECT_BOOT_AWARE
+                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, wallpaper.userId);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to call IPackageManager.getServiceInfo", e);
+                }
+                if (serviceInfo == null) {
                     Slog.e(TAG, "Wallpaper component gone, removing: "
                             + wallpaper.getComponent());
                     clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, false, null);
@@ -3177,7 +3181,7 @@
                     throw new IllegalArgumentException("Invalid crop rect supplied: " + crop);
                 }
                 int orientation = screenOrientations[i];
-                if (orientation == ORIENTATION_UNKNOWN && cropMap.size() > 1) {
+                if (orientation == ORIENTATION_UNKNOWN && crops.size() > 1) {
                     throw new IllegalArgumentException("Invalid crops supplied: the UNKNOWN"
                             + "screen orientation should only be used in a singleton map");
                 }
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 7cbacd6..dd76917 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -22,11 +22,9 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS;
 
-import static com.android.internal.util.DumpUtils.dumpSparseArray;
 import static com.android.internal.util.DumpUtils.dumpSparseArrayValues;
 import static com.android.server.accessibility.AccessibilityTraceFileProto.ENTRY;
 import static com.android.server.accessibility.AccessibilityTraceFileProto.MAGIC_NUMBER;
@@ -50,23 +48,15 @@
 import static com.android.server.wm.WindowTracingLegacy.WINSCOPE_EXT;
 
 import android.accessibilityservice.AccessibilityTrace;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Application;
 import android.content.Context;
 import android.content.pm.PackageManagerInternal;
-import android.graphics.BLASTBufferQueue;
-import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Insets;
 import android.graphics.Matrix;
-import android.graphics.Paint;
 import android.graphics.Path;
-import android.graphics.PixelFormat;
 import android.graphics.Point;
-import android.graphics.PorterDuff.Mode;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region;
@@ -84,25 +74,16 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
-import android.util.TypedValue;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
 import android.view.MagnificationSpec;
 import android.view.Surface;
-import android.view.Surface.OutOfResourcesException;
-import android.view.SurfaceControl;
 import android.view.ViewConfiguration;
 import android.view.WindowInfo;
 import android.view.WindowManager;
 import android.view.WindowManager.TransitionFlags;
 import android.view.WindowManager.TransitionType;
-import android.view.WindowManagerPolicyConstants;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
 
-import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.TraceBuffer;
 import com.android.internal.util.function.pooled.PooledLambda;
@@ -112,7 +93,6 @@
 import com.android.server.wm.WindowManagerInternal.AccessibilityControllerInternal;
 import com.android.server.wm.WindowManagerInternal.MagnificationCallbacks;
 import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback;
-import com.android.window.flags.Flags;
 
 import java.io.File;
 import java.io.IOException;
@@ -302,36 +282,6 @@
         }
     }
 
-    /** It is only used by unit test. */
-    @VisibleForTesting
-    Surface forceShowMagnifierSurface(int displayId) {
-        final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
-        if (displayMagnifier != null) {
-            displayMagnifier.mMagnifiedViewport.mWindow.setAlpha(DisplayMagnifier.MagnifiedViewport
-                    .ViewportWindow.AnimationController.MAX_ALPHA);
-            return displayMagnifier.mMagnifiedViewport.mWindow.mSurface;
-        }
-        return null;
-    }
-
-    void onWindowLayersChanged(int displayId) {
-        if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK
-                | FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK)) {
-            mAccessibilityTracing.logTrace(TAG + ".onWindowLayersChanged",
-                    FLAGS_MAGNIFICATION_CALLBACK | FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK,
-                    "displayId=" + displayId);
-        }
-        final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
-        if (displayMagnifier != null) {
-            displayMagnifier.onWindowLayersChanged();
-        }
-        final WindowsForAccessibilityObserver windowsForA11yObserver =
-                mWindowsForAccessibilityObserver.get(displayId);
-        if (windowsForA11yObserver != null) {
-            windowsForA11yObserver.scheduleComputeChangedWindows();
-        }
-    }
-
     void onDisplaySizeChanged(DisplayContent displayContent) {
 
         if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK
@@ -564,9 +514,6 @@
     }
 
     void dump(PrintWriter pw, String prefix) {
-        dumpSparseArray(pw, prefix, mDisplayMagnifiers, "magnification display",
-                (index, key) -> pw.printf("%sDisplay #%d:", prefix + "  ", key),
-                dm -> dm.dump(pw, ""));
         dumpSparseArrayValues(pw, prefix, mWindowsForAccessibilityObserver,
                 "windows for accessibility observer");
         mAccessibilityWindowsPopulator.dump(pw, prefix);
@@ -624,7 +571,6 @@
 
         private final Context mDisplayContext;
         private final WindowManagerService mService;
-        private final MagnifiedViewport mMagnifiedViewport;
         private final Handler mHandler;
         private final DisplayContent mDisplayContent;
         private final Display mDisplay;
@@ -661,8 +607,6 @@
             mDisplay = display;
             mHandler = new MyHandler(mService.mH.getLooper());
             mUserContextChangedNotifier = new UserContextChangedNotifier(mHandler);
-            mMagnifiedViewport = Flags.alwaysDrawMagnificationFullscreenBorder()
-                    ? null : new MagnifiedViewport();
             mAccessibilityTracing =
                     AccessibilityController.getAccessibilityControllerInternal(mService);
             mLongAnimationDuration = mDisplayContext.getResources().getInteger(
@@ -704,10 +648,6 @@
             } else {
                 mMagnificationSpec.clear();
             }
-
-            if (!Flags.alwaysDrawMagnificationFullscreenBorder()) {
-                mMagnifiedViewport.setShowMagnifiedBorderIfNeeded();
-            }
         }
 
         void setFullscreenMagnificationActivated(boolean activated) {
@@ -716,10 +656,6 @@
                         FLAGS_MAGNIFICATION_CALLBACK, "activated=" + activated);
             }
             mIsFullscreenMagnificationActivated = activated;
-            if (!Flags.alwaysDrawMagnificationFullscreenBorder()) {
-                mMagnifiedViewport.setMagnifiedRegionBorderShown(activated, true);
-                mMagnifiedViewport.showMagnificationBoundsIfNeeded();
-            }
         }
 
         boolean isFullscreenMagnificationActivated() {
@@ -730,18 +666,6 @@
             return mIsFullscreenMagnificationActivated;
         }
 
-        void onWindowLayersChanged() {
-            if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
-                mAccessibilityTracing.logTrace(
-                        LOG_TAG + ".onWindowLayersChanged", FLAGS_MAGNIFICATION_CALLBACK);
-            }
-            if (DEBUG_LAYERS) {
-                Slog.i(LOG_TAG, "Layers changed.");
-            }
-            recomputeBounds();
-            mService.scheduleAnimationLocked();
-        }
-
         void onDisplaySizeChanged(DisplayContent displayContent) {
             if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
                 mAccessibilityTracing.logTrace(LOG_TAG + ".onDisplaySizeChanged",
@@ -754,9 +678,6 @@
             }
 
             recomputeBounds();
-            if (!Flags.alwaysDrawMagnificationFullscreenBorder()) {
-                mMagnifiedViewport.onDisplaySizeChanged();
-            }
             mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_DISPLAY_SIZE_CHANGED);
         }
 
@@ -927,10 +848,6 @@
             if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
                 mAccessibilityTracing.logTrace(LOG_TAG + ".destroy", FLAGS_MAGNIFICATION_CALLBACK);
             }
-
-            if (!Flags.alwaysDrawMagnificationFullscreenBorder()) {
-                mMagnifiedViewport.destroyWindow();
-            }
         }
 
         void recomputeMagnifiedRegionAndDrawMagnifiedRegionBorderIfNeeded() {
@@ -940,10 +857,6 @@
                         FLAGS_MAGNIFICATION_CALLBACK);
             }
             recomputeBounds();
-
-            if (!Flags.alwaysDrawMagnificationFullscreenBorder()) {
-                mMagnifiedViewport.drawWindowIfNeeded();
-            }
         }
 
         void recomputeBounds() {
@@ -1051,16 +964,9 @@
             }
             visibleWindows.clear();
 
-            if (!Flags.alwaysDrawMagnificationFullscreenBorder()) {
-                mMagnifiedViewport.intersectWithDrawBorderInset(screenWidth, screenHeight);
-            }
-
             final boolean magnifiedChanged =
                     !mOldMagnificationRegion.equals(mMagnificationRegion);
             if (magnifiedChanged) {
-                if (!Flags.alwaysDrawMagnificationFullscreenBorder()) {
-                    mMagnifiedViewport.updateBorderDrawingStatus(screenWidth, screenHeight);
-                }
                 mOldMagnificationRegion.set(mMagnificationRegion);
                 final SomeArgs args = SomeArgs.obtain();
                 args.arg1 = Region.obtain(mMagnificationRegion);
@@ -1140,420 +1046,11 @@
             outSize.set(bounds.width(), bounds.height());
         }
 
-        void dump(PrintWriter pw, String prefix) {
-            if (!Flags.alwaysDrawMagnificationFullscreenBorder()) {
-                mMagnifiedViewport.dump(pw, prefix);
-            }
-        }
-
-        private final class MagnifiedViewport {
-
-            private final float mBorderWidth;
-            private final int mHalfBorderWidth;
-            private final int mDrawBorderInset;
-
-            @Nullable private final ViewportWindow mWindow;
-
-            private boolean mFullRedrawNeeded;
-
-            MagnifiedViewport() {
-                mBorderWidth = mDisplayContext.getResources().getDimension(
-                        com.android.internal.R.dimen.accessibility_magnification_indicator_width);
-                mHalfBorderWidth = (int) Math.ceil(mBorderWidth / 2);
-                mDrawBorderInset = (int) mBorderWidth / 2;
-                mWindow = new ViewportWindow(mDisplayContext);
-            }
-
-            void updateBorderDrawingStatus(int screenWidth, int screenHeight) {
-                mWindow.setBounds(mMagnificationRegion);
-                final Rect dirtyRect = mTempRect1;
-                if (mFullRedrawNeeded) {
-                    mFullRedrawNeeded = false;
-                    dirtyRect.set(mDrawBorderInset, mDrawBorderInset,
-                            screenWidth - mDrawBorderInset,
-                            screenHeight - mDrawBorderInset);
-                    mWindow.invalidate(dirtyRect);
-                } else {
-                    final Region dirtyRegion = mTempRegion3;
-                    dirtyRegion.set(mMagnificationRegion);
-                    dirtyRegion.op(mOldMagnificationRegion, Region.Op.XOR);
-                    dirtyRegion.getBounds(dirtyRect);
-                    mWindow.invalidate(dirtyRect);
-                }
-            }
-
-            void setShowMagnifiedBorderIfNeeded() {
-                // If this message is pending, we are in a rotation animation and do not want
-                // to show the border. We will do so when the pending message is handled.
-                if (!mHandler.hasMessages(
-                        MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED)) {
-                    setMagnifiedRegionBorderShown(
-                            isFullscreenMagnificationActivated(), true);
-                }
-            }
-
-            // Can be called outside of a surface transaction
-            void showMagnificationBoundsIfNeeded() {
-                if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
-                    mAccessibilityTracing.logTrace(LOG_TAG + ".showMagnificationBoundsIfNeeded",
-                            FLAGS_MAGNIFICATION_CALLBACK);
-                }
-                mHandler.obtainMessage(MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED)
-                        .sendToTarget();
-            }
-
-            void intersectWithDrawBorderInset(int screenWidth, int screenHeight) {
-                mMagnificationRegion.op(mDrawBorderInset, mDrawBorderInset,
-                        screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset,
-                        Region.Op.INTERSECT);
-            }
-
-            void onDisplaySizeChanged() {
-                // If fullscreen magnification is activated, hide the border immediately so
-                // the user does not see strange artifacts during display size changed caused by
-                // rotation or folding/unfolding the device. In the rotation case, the
-                // screenshot used for rotation already has the border. After the rotation is
-                // completed we will show the border.
-                if (isFullscreenMagnificationActivated()) {
-                    setMagnifiedRegionBorderShown(false, false);
-                    final long delay = (long) (mLongAnimationDuration
-                            * mService.getWindowAnimationScaleLocked());
-                    Message message = mHandler.obtainMessage(
-                            MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED);
-                    mHandler.sendMessageDelayed(message, delay);
-                }
-                mWindow.updateSize();
-            }
-
-            void setMagnifiedRegionBorderShown(boolean shown, boolean animate) {
-                if (mWindow.setShown(shown, animate)) {
-                    mFullRedrawNeeded = true;
-                    // Clear the old region, so recomputeBounds will refresh the current region.
-                    mOldMagnificationRegion.set(0, 0, 0, 0);
-                }
-            }
-
-            void drawWindowIfNeeded() {
-                mWindow.postDrawIfNeeded();
-            }
-
-            void destroyWindow() {
-                mWindow.releaseSurface();
-            }
-
-            void dump(PrintWriter pw, String prefix) {
-                mWindow.dump(pw, prefix);
-            }
-
-            // TODO(291891390): Remove this class when we clean up the flag
-            //  alwaysDrawMagnificationFullscreenBorder
-            private final class ViewportWindow implements Runnable {
-                private static final String SURFACE_TITLE = "Magnification Overlay";
-
-                private final Region mBounds = new Region();
-                private final Rect mDirtyRect = new Rect();
-                private final Paint mPaint = new Paint();
-
-                private final SurfaceControl mSurfaceControl;
-                /** After initialization, it should only be accessed from animation thread. */
-                private final SurfaceControl.Transaction mTransaction;
-                private final BLASTBufferQueue mBlastBufferQueue;
-                private final Surface mSurface;
-
-                private final AnimationController mAnimationController;
-
-                private boolean mShown;
-                private boolean mLastSurfaceShown;
-                private int mAlpha;
-                private int mPreviousAlpha;
-
-                private volatile boolean mInvalidated;
-
-                ViewportWindow(Context context) {
-                    SurfaceControl surfaceControl = null;
-                    try {
-                        surfaceControl = mDisplayContent
-                                .makeOverlay()
-                                .setName(SURFACE_TITLE)
-                                .setBLASTLayer()
-                                .setFormat(PixelFormat.TRANSLUCENT)
-                                .setCallsite("ViewportWindow")
-                                .build();
-                    } catch (OutOfResourcesException oore) {
-                        /* ignore */
-                    }
-                    mSurfaceControl = surfaceControl;
-                    mDisplay.getRealSize(mScreenSize);
-                    mBlastBufferQueue = new BLASTBufferQueue(SURFACE_TITLE, mSurfaceControl,
-                            mScreenSize.x, mScreenSize.y, PixelFormat.RGBA_8888);
-
-                    final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
-                    final int layer =
-                            mService.mPolicy.getWindowLayerFromTypeLw(TYPE_MAGNIFICATION_OVERLAY) *
-                                    WindowManagerPolicyConstants.TYPE_LAYER_MULTIPLIER;
-                    t.setLayer(mSurfaceControl, layer).setPosition(mSurfaceControl, 0, 0);
-                    InputMonitor.setTrustedOverlayInputInfo(mSurfaceControl, t,
-                            mDisplayContent.getDisplayId(), "Magnification Overlay");
-                    t.apply();
-                    mTransaction = t;
-                    mSurface = mBlastBufferQueue.createSurface();
-
-                    mAnimationController = new AnimationController(context,
-                            mService.mH.getLooper());
-
-                    TypedValue typedValue = new TypedValue();
-                    context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight,
-                            typedValue, true);
-                    final int borderColor = context.getColor(typedValue.resourceId);
-
-                    mPaint.setStyle(Paint.Style.STROKE);
-                    mPaint.setStrokeWidth(mBorderWidth);
-                    mPaint.setColor(borderColor);
-
-                    mInvalidated = true;
-                }
-
-                /** Returns {@code true} if the state is changed to shown. */
-                boolean setShown(boolean shown, boolean animate) {
-                    synchronized (mService.mGlobalLock) {
-                        if (mShown == shown) {
-                            return false;
-                        }
-                        mShown = shown;
-                        mAnimationController.onFrameShownStateChanged(shown, animate);
-                        if (DEBUG_VIEWPORT_WINDOW) {
-                            Slog.i(LOG_TAG, "ViewportWindow shown: " + mShown);
-                        }
-                    }
-                    return shown;
-                }
-
-                @SuppressWarnings("unused")
-                // Called reflectively from an animator.
-                int getAlpha() {
-                    synchronized (mService.mGlobalLock) {
-                        return mAlpha;
-                    }
-                }
-
-                void setAlpha(int alpha) {
-                    synchronized (mService.mGlobalLock) {
-                        if (mAlpha == alpha) {
-                            return;
-                        }
-                        mAlpha = alpha;
-                        invalidate(null);
-                        if (DEBUG_VIEWPORT_WINDOW) {
-                            Slog.i(LOG_TAG, "ViewportWindow set alpha: " + alpha);
-                        }
-                    }
-                }
-
-                void setBounds(Region bounds) {
-                    synchronized (mService.mGlobalLock) {
-                        if (mBounds.equals(bounds)) {
-                            return;
-                        }
-                        mBounds.set(bounds);
-                        invalidate(mDirtyRect);
-                        if (DEBUG_VIEWPORT_WINDOW) {
-                            Slog.i(LOG_TAG, "ViewportWindow set bounds: " + bounds);
-                        }
-                    }
-                }
-
-                void updateSize() {
-                    synchronized (mService.mGlobalLock) {
-                        getDisplaySizeLocked(mScreenSize);
-                        mBlastBufferQueue.update(mSurfaceControl, mScreenSize.x, mScreenSize.y,
-                                PixelFormat.RGBA_8888);
-                        invalidate(mDirtyRect);
-                    }
-                }
-
-                void invalidate(Rect dirtyRect) {
-                    if (dirtyRect != null) {
-                        mDirtyRect.set(dirtyRect);
-                    } else {
-                        mDirtyRect.setEmpty();
-                    }
-                    mInvalidated = true;
-                    mService.scheduleAnimationLocked();
-                }
-
-                void postDrawIfNeeded() {
-                    if (mInvalidated) {
-                        mService.mAnimationHandler.post(this);
-                    }
-                }
-
-                @Override
-                public void run() {
-                    drawOrRemoveIfNeeded();
-                }
-
-                /**
-                 * This method must only be called by animation handler directly to make sure
-                 * thread safe and there is no lock held outside.
-                 */
-                private void drawOrRemoveIfNeeded() {
-                    // Drawing variables (alpha, dirty rect, and bounds) access is synchronized
-                    // using WindowManagerGlobalLock. Grab copies of these values before
-                    // drawing on the canvas so that drawing can be performed outside of the lock.
-                    int alpha;
-                    boolean redrawBounds;
-                    Rect drawingRect = null;
-                    Region drawingBounds = null;
-                    synchronized (mService.mGlobalLock) {
-                        if (mBlastBufferQueue.mNativeObject == 0) {
-                            // Complete removal since releaseSurface has been called.
-                            if (mSurface.isValid()) {
-                                mTransaction.remove(mSurfaceControl).apply();
-                                mSurface.release();
-                            }
-                            return;
-                        }
-                        if (!mInvalidated) {
-                            return;
-                        }
-                        mInvalidated = false;
-
-                        alpha = mAlpha;
-                        // For b/325863281, we should ensure the drawn border path is cleared when
-                        // alpha = 0. Therefore, we cache the last used alpha when drawing as
-                        // mPreviousAlpha and check it here. If mPreviousAlpha > 0, which means
-                        // the border is showing now, then we should still redraw the clear path
-                        // on the canvas so the border is cleared.
-                        redrawBounds = mAlpha > 0 || mPreviousAlpha > 0;
-                        if (redrawBounds) {
-                            drawingBounds = new Region(mBounds);
-                            // Empty dirty rectangle means unspecified.
-                            if (mDirtyRect.isEmpty()) {
-                                mBounds.getBounds(mDirtyRect);
-                            }
-                            mDirtyRect.inset(-mHalfBorderWidth, -mHalfBorderWidth);
-                            drawingRect = new Rect(mDirtyRect);
-                            if (DEBUG_VIEWPORT_WINDOW) {
-                                Slog.i(LOG_TAG, "ViewportWindow bounds: " + mBounds);
-                                Slog.i(LOG_TAG, "ViewportWindow dirty rect: " + mDirtyRect);
-                            }
-                        }
-                    }
-
-                    final boolean showSurface;
-                    // Draw without holding WindowManagerGlobalLock.
-                    if (redrawBounds) {
-                        Canvas canvas = null;
-                        try {
-                            canvas = mSurface.lockCanvas(drawingRect);
-                        } catch (IllegalArgumentException | OutOfResourcesException e) {
-                            /* ignore */
-                        }
-                        if (canvas == null) {
-                            return;
-                        }
-                        canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
-                        mPaint.setAlpha(alpha);
-                        canvas.drawPath(drawingBounds.getBoundaryPath(), mPaint);
-                        mSurface.unlockCanvasAndPost(canvas);
-                        mPreviousAlpha = alpha;
-                    }
-
-                    showSurface = alpha > 0;
-
-                    if (showSurface && !mLastSurfaceShown) {
-                        mTransaction.show(mSurfaceControl).apply();
-                        mLastSurfaceShown = true;
-                    } else if (!showSurface && mLastSurfaceShown) {
-                        mTransaction.hide(mSurfaceControl).apply();
-                        mLastSurfaceShown = false;
-                    }
-                }
-
-                @GuardedBy("mService.mGlobalLock")
-                void releaseSurface() {
-                    mBlastBufferQueue.destroy();
-                    // Post to perform cleanup on the thread which handles mSurface.
-                    mService.mAnimationHandler.post(this);
-                }
-
-                void dump(PrintWriter pw, String prefix) {
-                    pw.println(prefix
-                            + " mBounds= " + mBounds
-                            + " mDirtyRect= " + mDirtyRect
-                            + " mWidth= " + mScreenSize.x
-                            + " mHeight= " + mScreenSize.y);
-                }
-
-                private final class AnimationController extends Handler {
-                    private static final String PROPERTY_NAME_ALPHA = "alpha";
-
-                    private static final int MIN_ALPHA = 0;
-                    private static final int MAX_ALPHA = 255;
-
-                    private static final int MSG_FRAME_SHOWN_STATE_CHANGED = 1;
-
-                    private final ValueAnimator mShowHideFrameAnimator;
-
-                    AnimationController(Context context, Looper looper) {
-                        super(looper);
-                        mShowHideFrameAnimator = ObjectAnimator.ofInt(ViewportWindow.this,
-                                PROPERTY_NAME_ALPHA, MIN_ALPHA, MAX_ALPHA);
-
-                        Interpolator interpolator = new DecelerateInterpolator(2.5f);
-                        final long longAnimationDuration = context.getResources().getInteger(
-                                com.android.internal.R.integer.config_longAnimTime);
-
-                        mShowHideFrameAnimator.setInterpolator(interpolator);
-                        mShowHideFrameAnimator.setDuration(longAnimationDuration);
-                    }
-
-                    void onFrameShownStateChanged(boolean shown, boolean animate) {
-                        obtainMessage(MSG_FRAME_SHOWN_STATE_CHANGED,
-                                shown ? 1 : 0, animate ? 1 : 0).sendToTarget();
-                    }
-
-                    @Override
-                    public void handleMessage(Message message) {
-                        switch (message.what) {
-                            case MSG_FRAME_SHOWN_STATE_CHANGED: {
-                                final boolean shown = message.arg1 == 1;
-                                final boolean animate = message.arg2 == 1;
-
-                                if (animate) {
-                                    if (mShowHideFrameAnimator.isRunning()) {
-                                        mShowHideFrameAnimator.reverse();
-                                    } else {
-                                        if (shown) {
-                                            mShowHideFrameAnimator.start();
-                                        } else {
-                                            mShowHideFrameAnimator.reverse();
-                                        }
-                                    }
-                                } else {
-                                    mShowHideFrameAnimator.cancel();
-                                    if (shown) {
-                                        setAlpha(MAX_ALPHA);
-                                    } else {
-                                        setAlpha(MIN_ALPHA);
-                                    }
-                                }
-                            } break;
-                        }
-                    }
-                }
-            }
-        }
-
         private class MyHandler extends Handler {
             public static final int MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED = 1;
             public static final int MESSAGE_NOTIFY_USER_CONTEXT_CHANGED = 3;
             public static final int MESSAGE_NOTIFY_DISPLAY_SIZE_CHANGED = 4;
-
-            // TODO(291891390): Remove this field when we clean up the flag
-            //  alwaysDrawMagnificationFullscreenBorder
-            public static final int MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED = 5;
-            public static final int MESSAGE_NOTIFY_IME_WINDOW_VISIBILITY_CHANGED = 6;
+            public static final int MESSAGE_NOTIFY_IME_WINDOW_VISIBILITY_CHANGED = 5;
 
             MyHandler(Looper looper) {
                 super(looper);
@@ -1577,17 +1074,6 @@
                         mCallbacks.onDisplaySizeChanged();
                     } break;
 
-                    case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : {
-                        synchronized (mService.mGlobalLock) {
-                            if (isFullscreenMagnificationActivated()) {
-                                if (!Flags.alwaysDrawMagnificationFullscreenBorder()) {
-                                    mMagnifiedViewport.setMagnifiedRegionBorderShown(true, true);
-                                }
-                                mService.scheduleAnimationLocked();
-                            }
-                        }
-                    } break;
-
                     case MESSAGE_NOTIFY_IME_WINDOW_VISIBILITY_CHANGED: {
                         final boolean shown = message.arg1 == 1;
                         mCallbacks.onImeWindowVisibilityChanged(shown);
@@ -1784,22 +1270,13 @@
                 mA11yWindowsPopulator.populateVisibleWindowsOnScreenLocked(
                         mDisplayId, visibleWindows);
 
-                if (!com.android.server.accessibility.Flags.computeWindowChangesOnA11yV2()) {
-                    windows = buildWindowInfoListLocked(visibleWindows, screenSize);
-                }
-
                 // Gets the top focused display Id and window token for supporting multi-display.
                 topFocusedDisplayId = mService.mRoot.getTopFocusedDisplayContent().getDisplayId();
                 topFocusedWindowToken = topFocusedWindowState.mClient.asBinder();
             }
 
-            if (com.android.server.accessibility.Flags.computeWindowChangesOnA11yV2()) {
-                mCallback.onAccessibilityWindowsChanged(forceSend, topFocusedDisplayId,
-                        topFocusedWindowToken, screenSize, visibleWindows);
-            } else {
-                mCallback.onWindowsForAccessibilityChanged(forceSend, topFocusedDisplayId,
-                        topFocusedWindowToken, windows);
-            }
+            mCallback.onAccessibilityWindowsChanged(forceSend, topFocusedDisplayId,
+                    topFocusedWindowToken, screenSize, visibleWindows);
 
             // Recycle the windows as we do not need them.
             for (final AccessibilityWindowsPopulator.AccessibilityWindow window : visibleWindows) {
@@ -1808,166 +1285,6 @@
             mInitialized = true;
         }
 
-        // Here are old code paths, called when computeWindowChangesOnA11yV2 flag is disabled.
-        // LINT.IfChange
-
-        /**
-         * From a list of windows, decides windows to be exposed to accessibility based on touchable
-         * region in the screen.
-         */
-        private List<WindowInfo> buildWindowInfoListLocked(List<AccessibilityWindow> visibleWindows,
-                Point screenSize) {
-            final List<WindowInfo> windows = new ArrayList<>();
-            final Set<IBinder> addedWindows = mTempBinderSet;
-            addedWindows.clear();
-
-            boolean focusedWindowAdded = false;
-
-            final int visibleWindowCount = visibleWindows.size();
-
-            Region unaccountedSpace = mTempRegion;
-            unaccountedSpace.set(0, 0, screenSize.x, screenSize.y);
-
-            // Iterate until we figure out what is touchable for the entire screen.
-            for (int i = 0; i < visibleWindowCount; i++) {
-                final AccessibilityWindow a11yWindow = visibleWindows.get(i);
-                final Region regionInWindow = new Region();
-                a11yWindow.getTouchableRegionInWindow(regionInWindow);
-                if (windowMattersToAccessibility(a11yWindow, regionInWindow, unaccountedSpace)) {
-                    addPopulatedWindowInfo(a11yWindow, regionInWindow, windows, addedWindows);
-                    if (windowMattersToUnaccountedSpaceComputation(a11yWindow)) {
-                        updateUnaccountedSpace(a11yWindow, unaccountedSpace);
-                    }
-                    focusedWindowAdded |= a11yWindow.isFocused();
-                } else if (a11yWindow.isUntouchableNavigationBar()) {
-                    // If this widow is navigation bar without touchable region, accounting the
-                    // region of navigation bar inset because all touch events from this region
-                    // would be received by launcher, i.e. this region is a un-touchable one
-                    // for the application.
-                    unaccountedSpace.op(
-                            getSystemBarInsetsFrame(
-                                    mService.mWindowMap.get(a11yWindow.getWindowInfo().token)),
-                            unaccountedSpace,
-                            Region.Op.REVERSE_DIFFERENCE);
-                }
-
-                if (unaccountedSpace.isEmpty() && focusedWindowAdded) {
-                    break;
-                }
-            }
-
-            // Remove child/parent references to windows that were not added.
-            final int windowCount = windows.size();
-            for (int i = 0; i < windowCount; i++) {
-                WindowInfo window = windows.get(i);
-                if (!addedWindows.contains(window.parentToken)) {
-                    window.parentToken = null;
-                }
-                if (window.childTokens != null) {
-                    final int childTokenCount = window.childTokens.size();
-                    for (int j = childTokenCount - 1; j >= 0; j--) {
-                        if (!addedWindows.contains(window.childTokens.get(j))) {
-                            window.childTokens.remove(j);
-                        }
-                    }
-                    // Leave the child token list if empty.
-                }
-            }
-
-            addedWindows.clear();
-
-            return windows;
-        }
-
-        // Some windows should be excluded from unaccounted space computation, though they still
-        // should be reported
-        private boolean windowMattersToUnaccountedSpaceComputation(AccessibilityWindow a11yWindow) {
-            // Do not account space of trusted non-touchable windows, except the split-screen
-            // divider.
-            // If it's not trusted, touch events are not sent to the windows behind it.
-            if (!a11yWindow.isTouchable()
-                    && (a11yWindow.getType() != TYPE_DOCK_DIVIDER)
-                    && a11yWindow.isTrustedOverlay()) {
-                return false;
-            }
-
-            if (a11yWindow.getType() == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
-                return false;
-            }
-            return true;
-        }
-
-        private boolean windowMattersToAccessibility(AccessibilityWindow a11yWindow,
-                Region regionInScreen, Region unaccountedSpace) {
-            if (a11yWindow.isFocused()) {
-                return true;
-            }
-
-            // Ignore non-touchable windows, except the split-screen divider, which is
-            // occasionally non-touchable but still useful for identifying split-screen
-            // mode and the PIP menu.
-            if (!a11yWindow.isTouchable()
-                    && (a11yWindow.getType() != TYPE_DOCK_DIVIDER
-                    && !a11yWindow.isPIPMenu())) {
-                return false;
-            }
-
-            // If the window is completely covered by other windows - ignore.
-            if (unaccountedSpace.quickReject(regionInScreen)) {
-                return false;
-            }
-
-            // Add windows of certain types not covered by modal windows.
-            if (isReportedWindowType(a11yWindow.getType())) {
-                return true;
-            }
-
-            return false;
-        }
-
-        private void updateUnaccountedSpace(AccessibilityWindow a11yWindow,
-                Region unaccountedSpace) {
-            if (a11yWindow.getType()
-                    != WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
-                // Account for the space this window takes if the window
-                // is not an accessibility overlay which does not change
-                // the reported windows.
-                final Region touchableRegion = mTempRegion2;
-                a11yWindow.getTouchableRegionInScreen(touchableRegion);
-                unaccountedSpace.op(touchableRegion, unaccountedSpace,
-                        Region.Op.REVERSE_DIFFERENCE);
-            }
-        }
-
-        private static void addPopulatedWindowInfo(AccessibilityWindow a11yWindow,
-                Region regionInScreen, List<WindowInfo> out, Set<IBinder> tokenOut) {
-            final WindowInfo window = a11yWindow.getWindowInfo();
-            if (window.token == null) {
-                // The window was used in calculating visible windows but does not have an
-                // associated IWindow token, so exclude it from the list returned to accessibility.
-                return;
-            }
-            window.regionInScreen.set(regionInScreen);
-            window.layer = tokenOut.size();
-            out.add(window);
-            tokenOut.add(window.token);
-        }
-
-        private static boolean isReportedWindowType(int windowType) {
-            return (windowType != WindowManager.LayoutParams.TYPE_WALLPAPER
-                    && windowType != WindowManager.LayoutParams.TYPE_BOOT_PROGRESS
-                    && windowType != WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY
-                    && windowType != WindowManager.LayoutParams.TYPE_DRAG
-                    && windowType != WindowManager.LayoutParams.TYPE_INPUT_CONSUMER
-                    && windowType != WindowManager.LayoutParams.TYPE_POINTER
-                    && windowType != TYPE_MAGNIFICATION_OVERLAY
-                    && windowType != WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
-                    && windowType != WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY
-                    && windowType != WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
-        }
-
-        // LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java)
-
         private WindowState getTopFocusWindow() {
             return mService.mRoot.getTopFocusedDisplayContent().mCurrentFocus;
         }
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index fd2a909..7fc11e6 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -724,8 +724,7 @@
             }
 
             // Compute system bar insets frame if needed.
-            if (com.android.server.accessibility.Flags.computeWindowChangesOnA11yV2()
-                    && windowState != null && instance.isUntouchableNavigationBar()) {
+            if (windowState != null && instance.isUntouchableNavigationBar()) {
                 final InsetsSourceProvider provider =
                         windowState.getControllableInsetProvider();
                 if (provider != null) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f70dec1..d2546e4 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3230,8 +3230,8 @@
             return false;
         }
         // If the user preference respects aspect ratio, then it becomes non-resizable.
-        return !mAppCompatController.getAppCompatOverrides().getAppCompatAspectRatioOverrides()
-                .shouldApplyUserMinAspectRatioOverride();
+        return mAppCompatController.getAppCompatOverrides().getAppCompatAspectRatioOverrides()
+                .userPreferenceCompatibleWithNonResizability();
     }
 
     boolean isResizeable() {
@@ -4575,10 +4575,22 @@
                 // at #postWindowRemoveCleanupLocked
                 return false;
             }
+
+            // Link the fixed rotation transform to this activity since we are transferring the
+            // starting window.
+            if (fromActivity.hasFixedRotationTransform()) {
+                mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(this,
+                        false /* checkOpening */);
+            }
             // Do not transfer if the orientation doesn't match, redraw starting window while it is
             // on top will cause flicker.
-            if (fromActivity.getRequestedConfigurationOrientation()
-                    != getRequestedConfigurationOrientation()) {
+            final int fromOrientation = fromActivity.getConfiguration().orientation;
+            final int requestedOrientation = getRequestedConfigurationOrientation();
+            if (requestedOrientation == ORIENTATION_UNDEFINED) {
+                if (fromOrientation != getConfiguration().orientation) {
+                    return false;
+                }
+            } else if (fromOrientation != requestedOrientation) {
                 return false;
             }
             // In this case, the starting icon has already been displayed, so start
@@ -4592,13 +4604,6 @@
 
             final long origId = Binder.clearCallingIdentity();
             try {
-                // Link the fixed rotation transform to this activity since we are transferring the
-                // starting window.
-                if (fromActivity.hasFixedRotationTransform()) {
-                    mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(this,
-                            false /* checkOpening */);
-                }
-
                 // Transfer the starting window over to the new token.
                 mStartingData = fromActivity.mStartingData;
                 mStartingSurface = fromActivity.mStartingSurface;
diff --git a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
index 90c0866..086b11c 100644
--- a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
@@ -135,6 +135,12 @@
                 && aspectRatio != USER_MIN_ASPECT_RATIO_FULLSCREEN;
     }
 
+    boolean userPreferenceCompatibleWithNonResizability() {
+        final int aspectRatio = getUserMinAspectRatioOverrideCode();
+        return aspectRatio == USER_MIN_ASPECT_RATIO_UNSET
+                || aspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN;
+    }
+
     boolean shouldApplyUserFullscreenOverride() {
         if (isUserFullscreenOverrideEnabled()) {
             final int aspectRatio = getUserMinAspectRatioOverrideCode();
diff --git a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
index 9754595..47d30c9 100644
--- a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
@@ -164,12 +164,14 @@
      * <p>The treatment is enabled when the following conditions are met:
      * <ul>
      * <li>Feature flag gating the camera compatibility free-form treatment is enabled.
-     * <li>Activity is opted in by the device manufacturer with override.
+     * <li>Activity is opted-in using per-app override, or the treatment is enabled for all apps.
      * </ul>
      */
     boolean shouldApplyFreeformTreatmentForCameraCompat() {
-        return Flags.enableCameraCompatForDesktopWindowing() && isChangeEnabled(mActivityRecord,
-                OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT);
+        return Flags.enableCameraCompatForDesktopWindowing() && (isChangeEnabled(mActivityRecord,
+                OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT)
+                || mActivityRecord.mWmService.mAppCompatConfiguration
+                    .isCameraCompatFreeformWindowingTreatmentEnabled());
     }
 
     boolean isOverrideOrientationOnlyForCameraEnabled() {
diff --git a/services/core/java/com/android/server/wm/AppCompatConfiguration.java b/services/core/java/com/android/server/wm/AppCompatConfiguration.java
index 38c6de1..9a15c4a 100644
--- a/services/core/java/com/android/server/wm/AppCompatConfiguration.java
+++ b/services/core/java/com/android/server/wm/AppCompatConfiguration.java
@@ -304,6 +304,11 @@
     // See RefreshCallbackItem for context.
     private boolean mIsCameraCompatRefreshCycleThroughStopEnabled = true;
 
+    // Whether camera compat freeform treatment should be enabled for all eligible activities.
+    // This has the same effect as enabling the per-app override
+    // ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT for every app.
+    private boolean mIsCameraCompatFreeformWindowingTreatmentEnabled = false;
+
     // Whether should ignore app requested orientation in response to an app
     // calling Activity#setRequestedOrientation. See
     // LetterboxUiController#shouldIgnoreRequestedOrientation for details.
@@ -1351,6 +1356,30 @@
     }
 
     /**
+     * Sets whether the camera compatibility treatment in freeform windowing mode is enabled for
+     * all fixed-orientation apps when using camera.
+     */
+    void setIsCameraCompatFreeformWindowingTreatmentEnabled(boolean enabled) {
+        mIsCameraCompatFreeformWindowingTreatmentEnabled = enabled;
+    }
+
+    /**
+     * Whether the camera compatibility treatment in freeform windowing mode is enabled for all
+     * fixed-orientation apps when using camera.
+     */
+    boolean isCameraCompatFreeformWindowingTreatmentEnabled() {
+        return mIsCameraCompatFreeformWindowingTreatmentEnabled;
+    }
+
+    /**
+     * Resets whether the camera compatibility treatment in freeform windowing mode is enabled for
+     * all fixed-orientation apps when using camera.
+     */
+    void resetIsCameraCompatFreeformWindowingTreatmentEnabled() {
+        mIsCameraCompatFreeformWindowingTreatmentEnabled = false;
+    }
+
+    /**
      * Checks whether rotation compat policy for immersive apps that prevents auto rotation
      * into non-optimal screen orientation while in fullscreen is enabled at build time. This is
      * used when we need to safely initialize a component before the {@link DeviceConfig} flag
diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java
index 145a376..203932d 100644
--- a/services/core/java/com/android/server/wm/AppCompatController.java
+++ b/services/core/java/com/android/server/wm/AppCompatController.java
@@ -76,6 +76,16 @@
         mAppCompatSizeCompatModePolicy = new AppCompatSizeCompatModePolicy(mActivityRecord,
                 mAppCompatOverrides);
         mAllowRestrictedResizability = AppCompatUtils.asLazy(() -> {
+            // Application level.
+            try {
+                if (packageManager.getProperty(PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY,
+                        mActivityRecord.packageName).getBoolean()) {
+                    return true;
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                // Fall through.
+            }
+            // Activity level.
             try {
                 return packageManager.getPropertyAsUser(
                         PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY,
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index bce8c2b..852a0ac 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -1016,7 +1016,8 @@
         }
         if (state.mCallingUidHasNonAppVisibleWindow) {
             return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW,
-                    /*background*/ false, "callingUid has non-app visible window");
+                    /*background*/ false, "callingUid has non-app visible window "
+                    + mService.mActiveUids.getNonAppVisibleWindowDetails(state.mCallingUid));
         }
         // Don't abort if the callerApp or other processes of that uid are considered to be in the
         // foreground.
@@ -1142,7 +1143,8 @@
         }
         if (state.mRealCallingUidHasNonAppVisibleWindow) {
             return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW,
-                    /*background*/ false, "realCallingUid has non-app visible window");
+                    /*background*/ false, "realCallingUid has non-app visible window "
+                    + mService.mActiveUids.getNonAppVisibleWindowDetails(state.mRealCallingUid));
         }
 
         // Don't abort if the realCallerApp or other processes of that uid are considered to be in
@@ -1894,20 +1896,8 @@
                             (state.mOriginatingPendingIntent != null));
         }
 
-        if (finalVerdict.getRawCode() == BAL_ALLOW_GRACE_PERIOD) {
-            if (state.realCallerExplicitOptInOrAutoOptIn()
-                    && state.mResultForRealCaller.allows()
-                    && state.mResultForRealCaller.getRawCode() != BAL_ALLOW_GRACE_PERIOD) {
-                // real caller could allow with a different exemption
-            } else if (state.callerExplicitOptInOrAutoOptIn() && state.mResultForCaller.allows()
-                    && state.mResultForCaller.getRawCode() != BAL_ALLOW_GRACE_PERIOD) {
-                // caller could allow with a different exemption
-            } else {
-                // log to determine grace period length distribution
-                Slog.wtf(TAG, "Activity start ONLY allowed by BAL_ALLOW_GRACE_PERIOD "
-                        + finalVerdict.mMessage + ": " + state);
-            }
-        }
+        logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_GRACE_PERIOD);
+        logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_NON_APP_VISIBLE_WINDOW);
 
         if (balImprovedMetrics()) {
             if (shouldLogStats(finalVerdict, state)) {
@@ -1946,6 +1936,30 @@
         return finalVerdict;
     }
 
+    /**
+     * Logs details about the activity starts if the only reason it is allowed is the provided
+     * {@code balCode}.
+     */
+    private static void logIfOnlyAllowedBy(BalVerdict finalVerdict, BalState state, int balCode) {
+        if (finalVerdict.getRawCode() == balCode) {
+            if (state.realCallerExplicitOptInOrAutoOptIn()
+                    && state.mResultForRealCaller != null
+                    && state.mResultForRealCaller.allows()
+                    && state.mResultForRealCaller.getRawCode() != balCode) {
+                // real caller could allow with a different exemption
+            } else if (state.callerExplicitOptInOrAutoOptIn()
+                    && state.mResultForCaller != null
+                    && state.mResultForCaller.allows()
+                    && state.mResultForCaller.getRawCode() != balCode) {
+                // caller could allow with a different exemption
+            } else {
+                // log to determine grace period length distribution
+                Slog.wtf(TAG, "Activity start ONLY allowed by " + balCodeToString(balCode) + " "
+                        + finalVerdict.mMessage + ": " + state);
+            }
+        }
+    }
+
     @VisibleForTesting
     boolean shouldLogStats(BalVerdict finalVerdict, BalState state) {
         if (finalVerdict.getRawCode() == BAL_ALLOW_VISIBLE_WINDOW) {
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 0b5872b..93ccd74 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -32,6 +32,7 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.media.projection.IMediaProjectionManager;
+import android.media.projection.StopReason;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -226,6 +227,7 @@
                                 + "size %s",
                         mDisplayContent.getDisplayId(), recordedContentBounds,
                         recordedContentOrientation, surfaceSize);
+
                 updateMirroredSurface(mRecordedWindowContainer.getSyncTransaction(),
                         recordedContentBounds, surfaceSize);
             } else {
@@ -295,12 +297,12 @@
      * Ensure recording does not fall back to the display stack; ensure the recording is stopped
      * and the client notified by tearing down the virtual display.
      */
-    private void stopMediaProjection() {
+    private void stopMediaProjection(@StopReason int stopReason) {
         ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
                 "Content Recording: Stop MediaProjection on virtual display %d",
                 mDisplayContent.getDisplayId());
         if (mMediaProjectionManager != null) {
-            mMediaProjectionManager.stopActiveProjection();
+            mMediaProjectionManager.stopActiveProjection(stopReason);
         }
     }
 
@@ -507,7 +509,7 @@
         if (shouldExitTaskRecording) {
             // Clean up the cached session first to ensure recording doesn't re-start, since
             // tearing down the display will generate display events which will trickle back here.
-            stopMediaProjection();
+            stopMediaProjection(StopReason.STOP_ERROR);
         }
     }
 
@@ -599,9 +601,13 @@
         mLastRecordedBounds = new Rect(recordedContentBounds);
         mLastConsumingSurfaceSize.x = surfaceSize.x;
         mLastConsumingSurfaceSize.y = surfaceSize.y;
-        // Request to notify the client about the resize.
-        mMediaProjectionManager.notifyActiveProjectionCapturedContentResized(
-                mLastRecordedBounds.width(), mLastRecordedBounds.height());
+
+        // Request to notify the client about the updated bounds.
+        mMediaProjectionManager.notifyCaptureBoundsChanged(
+                mContentRecordingSession.getContentToRecord(),
+                mContentRecordingSession.getTargetUid(),
+                mLastRecordedBounds
+        );
     }
 
     /**
@@ -641,7 +647,7 @@
         clearContentRecordingSession();
         // Clean up the cached session first to ensure recording doesn't re-start, since
         // tearing down the display will generate display events which will trickle back here.
-        stopMediaProjection();
+        stopMediaProjection(StopReason.STOP_TARGET_REMOVED);
     }
 
     // WindowContainerListener
@@ -674,10 +680,10 @@
     }
 
     @VisibleForTesting interface MediaProjectionManagerWrapper {
-        void stopActiveProjection();
-        void notifyActiveProjectionCapturedContentResized(int width, int height);
+        void stopActiveProjection(@StopReason int stopReason);
         void notifyActiveProjectionCapturedContentVisibilityChanged(boolean isVisible);
         void notifyWindowingModeChanged(int contentToRecord, int targetUid, int windowingMode);
+        void notifyCaptureBoundsChanged(int contentToRecord, int targetUid, Rect captureBounds);
     }
 
     private static final class RemoteMediaProjectionManagerWrapper implements
@@ -691,7 +697,7 @@
         }
 
         @Override
-        public void stopActiveProjection() {
+        public void stopActiveProjection(@StopReason int stopReason) {
             fetchMediaProjectionManager();
             if (mIMediaProjectionManager == null) {
                 return;
@@ -700,7 +706,7 @@
                 ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
                         "Content Recording: stopping active projection for display %d",
                         mDisplayId);
-                mIMediaProjectionManager.stopActiveProjection();
+                mIMediaProjectionManager.stopActiveProjection(stopReason);
             } catch (RemoteException e) {
                 ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
                         "Content Recording: Unable to tell MediaProjectionManagerService to stop "
@@ -710,23 +716,6 @@
         }
 
         @Override
-        public void notifyActiveProjectionCapturedContentResized(int width, int height) {
-            fetchMediaProjectionManager();
-            if (mIMediaProjectionManager == null) {
-                return;
-            }
-            try {
-                mIMediaProjectionManager.notifyActiveProjectionCapturedContentResized(width,
-                        height);
-            } catch (RemoteException e) {
-                ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
-                        "Content Recording: Unable to tell MediaProjectionManagerService about "
-                                + "resizing the active projection: %s",
-                        e);
-            }
-        }
-
-        @Override
         public void notifyActiveProjectionCapturedContentVisibilityChanged(boolean isVisible) {
             fetchMediaProjectionManager();
             if (mIMediaProjectionManager == null) {
@@ -759,6 +748,22 @@
             }
         }
 
+        @Override
+        public void notifyCaptureBoundsChanged(int contentToRecord, int targetUid,
+                Rect captureBounds) {
+            fetchMediaProjectionManager();
+            if (mIMediaProjectionManager == null) {
+                return;
+            }
+            try {
+                mIMediaProjectionManager.notifyCaptureBoundsChanged(
+                        contentToRecord, targetUid, captureBounds);
+            } catch (RemoteException e) {
+                ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
+                        "Content Recording: Unable to tell log bounds change: %s", e);
+            }
+        }
+
         private void fetchMediaProjectionManager() {
             if (mIMediaProjectionManager != null) {
                 return;
diff --git a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
index 6f8c17a..4e79e37 100644
--- a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
+++ b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
@@ -403,6 +403,7 @@
                 || first.renderFrameRate != second.renderFrameRate
                 || first.hasArrSupport != second.hasArrSupport
                 || !Objects.equals(first.frameRateCategoryRate, second.frameRateCategoryRate)
+                || !Arrays.equals(first.supportedRefreshRates, second.supportedRefreshRates)
                 || first.defaultModeId != second.defaultModeId
                 || first.userPreferredModeId != second.userPreferredModeId
                 || !Arrays.equals(first.supportedModes, second.supportedModes)
diff --git a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
index c8cb621..43855aa 100644
--- a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
+++ b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
@@ -196,10 +196,11 @@
 
         if (!aspectRatioOverrides.shouldOverrideMinAspectRatio()
                 && !AppCompatCameraPolicy.shouldOverrideMinAspectRatioForCamera(mActivityRecord)) {
-            if (mActivityRecord.isUniversalResizeable()) {
+            final float minAspectRatio = info.getMinAspectRatio();
+            if (minAspectRatio == 0 || mActivityRecord.isUniversalResizeable()) {
                 return 0;
             }
-            return info.getMinAspectRatio();
+            return minAspectRatio;
         }
 
         if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY)
@@ -242,10 +243,11 @@
         if (mTransparentPolicy.isRunning()) {
             return mTransparentPolicy.getInheritedMaxAspectRatio();
         }
-        if (mActivityRecord.isUniversalResizeable()) {
+        final float maxAspectRatio = mActivityRecord.info.getMaxAspectRatio();
+        if (maxAspectRatio == 0 || mActivityRecord.isUniversalResizeable()) {
             return 0;
         }
-        return mActivityRecord.info.getMaxAspectRatio();
+        return maxAspectRatio;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e9e550e..9a33df1 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5502,14 +5502,18 @@
             // Attach the SystemUiContext to this DisplayContent the get latest configuration.
             // Note that the SystemUiContext will be removed automatically if this DisplayContent
             // is detached.
-            final WindowProcessController wpc = mAtmService.getProcessController(
-                    getDisplayUiContext().getIApplicationThread());
-            mWmService.mWindowContextListenerController.registerWindowContainerListener(
-                    wpc, getDisplayUiContext().getWindowContextToken(), this,
-                    INVALID_WINDOW_TYPE, null /* options */);
+            registerSystemUiContext();
         }
     }
 
+    private void registerSystemUiContext() {
+        final WindowProcessController wpc = mAtmService.getProcessController(
+                getDisplayUiContext().getIApplicationThread());
+        mWmService.mWindowContextListenerController.registerWindowContainerListener(
+                wpc, getDisplayUiContext().getWindowContextToken(), this,
+                INVALID_WINDOW_TYPE, null /* options */);
+    }
+
     @Override
     void assignChildLayers(SurfaceControl.Transaction t) {
         assignRelativeLayerForIme(t, false /* forceUpdate */);
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 4cf1fb4..df209ff 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -485,6 +485,9 @@
             if (isDefaultDisplay) {
                 updateOrientationListenerLw();
             }
+        } else if (mCompatPolicyForImmersiveApps != null
+                && mCompatPolicyForImmersiveApps.deferOrientationUpdate()) {
+            return false;
         }
         return updateRotationUnchecked(forceUpdate);
     }
diff --git a/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java
index 094434d..046ed61 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java
@@ -17,10 +17,13 @@
 package com.android.server.wm;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
 
+import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.res.Configuration.Orientation;
@@ -66,6 +69,37 @@
     }
 
     /**
+     * Returns {@code true} if the orientation update should be skipped and it will update when
+     * transition is done. This is to keep the orientation which was preserved by
+     * {@link #isRotationLockEnforced} from being changed by a transient launch (i.e. recents).
+     */
+    boolean deferOrientationUpdate() {
+        if (mDisplayRotation.getUserRotation() != USER_ROTATION_FREE
+                || mDisplayRotation.getLastOrientation() != SCREEN_ORIENTATION_UNSPECIFIED) {
+            return false;
+        }
+        final WindowOrientationListener orientationListener =
+                mDisplayRotation.getOrientationListener();
+        if (orientationListener == null
+                || orientationListener.getProposedRotation() == mDisplayRotation.getRotation()) {
+            return false;
+        }
+        // The above conditions mean that isRotationLockEnforced might have taken effect:
+        // Auto-rotation is enabled and the proposed rotation is not applied.
+        // Then the update should defer until the transition idle to avoid disturbing animation.
+        if (!mDisplayContent.mTransitionController.hasTransientLaunch(mDisplayContent)) {
+            return false;
+        }
+        mDisplayContent.mTransitionController.mStateValidators.add(() -> {
+            if (!isRotationLockEnforcedLocked(orientationListener.getProposedRotation())) {
+                mDisplayContent.mWmService.updateRotation(false /* alwaysSendConfiguration */,
+                        false /* forceRelayout */);
+            }
+        });
+        return true;
+    }
+
+    /**
      * Decides whether it is necessary to lock screen rotation, preventing auto rotation, based on
      * the top activity configuration and proposed screen rotation.
      *
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 49f717e..48e1c06 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -346,12 +346,15 @@
                 ImeTracker.forLogging().onProgress(statsToken,
                         ImeTracker.PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY);
                 controlTarget.setImeInputTargetRequestedVisibility(imeVisible);
+                // not all virtual displays have an ImeInsetsSourceProvider, so it is not
+                // guaranteed that the IME will be started when the control target reports its
+                // requested visibility back. Thus, invoking the listener here.
+                invokeOnImeRequestedChangedListener(imeInsetsTarget, statsToken);
             } else {
                 ImeTracker.forLogging().onFailed(statsToken,
                         ImeTracker.PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY);
             }
         }
-        invokeOnImeRequestedChangedListener(imeInsetsTarget, statsToken);
     }
 
     // TODO(b/353463205) check callers to see if we can make statsToken @NonNull
diff --git a/services/core/java/com/android/server/wm/MirrorActiveUids.java b/services/core/java/com/android/server/wm/MirrorActiveUids.java
index b9aa959..b7bf162 100644
--- a/services/core/java/com/android/server/wm/MirrorActiveUids.java
+++ b/services/core/java/com/android/server/wm/MirrorActiveUids.java
@@ -19,6 +19,7 @@
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 
 import android.app.ActivityManager.ProcessState;
+import android.util.SparseArray;
 import android.util.SparseIntArray;
 
 import java.io.PrintWriter;
@@ -34,6 +35,8 @@
 
     /** Uid -> number of non-app visible windows belong to the uid. */
     private final SparseIntArray mNumNonAppVisibleWindowMap = new SparseIntArray();
+    /** Type -> Uid -> number of non-app visible windows for type/uid. */
+    private final SparseArray<SparseIntArray> mNumNonAppVisibleWindowMapByType = new SparseArray();
 
     synchronized void onUidActive(int uid, int procState) {
         mUidStates.put(uid, procState);
@@ -55,17 +58,31 @@
     }
 
     /** Called when the surface of non-application (exclude toast) window is shown or hidden. */
-    synchronized void onNonAppSurfaceVisibilityChanged(int uid, boolean visible) {
-        final int index = mNumNonAppVisibleWindowMap.indexOfKey(uid);
+    synchronized void onNonAppSurfaceVisibilityChanged(int uid, int type, boolean visible) {
+        updateCount(uid, visible, mNumNonAppVisibleWindowMap);
+        updateCount(uid, visible, getNumNonAppVisibleWindowMapByType(type));
+    }
+
+    private SparseIntArray getNumNonAppVisibleWindowMapByType(int type) {
+        SparseIntArray result = mNumNonAppVisibleWindowMapByType.get(type);
+        if (result == null) {
+            result = new SparseIntArray();
+            mNumNonAppVisibleWindowMapByType.append(type, result);
+        }
+        return result;
+    }
+
+    private void updateCount(int uid, boolean visible, SparseIntArray numNonAppVisibleWindowMap) {
+        final int index = numNonAppVisibleWindowMap.indexOfKey(uid);
         if (index >= 0) {
-            final int num = mNumNonAppVisibleWindowMap.valueAt(index) + (visible ? 1 : -1);
+            final int num = numNonAppVisibleWindowMap.valueAt(index) + (visible ? 1 : -1);
             if (num > 0) {
-                mNumNonAppVisibleWindowMap.setValueAt(index, num);
+                numNonAppVisibleWindowMap.setValueAt(index, num);
             } else {
-                mNumNonAppVisibleWindowMap.removeAt(index);
+                numNonAppVisibleWindowMap.removeAt(index);
             }
         } else if (visible) {
-            mNumNonAppVisibleWindowMap.append(uid, 1);
+            numNonAppVisibleWindowMap.append(uid, 1);
         }
     }
 
@@ -78,6 +95,24 @@
         return mNumNonAppVisibleWindowMap.get(uid) > 0;
     }
 
+    /**
+     * Returns details about the windows that contribute to the result of
+     * {@link #hasNonAppVisibleWindow(int)}.
+     *
+     * @return a map of window type to count
+     */
+    synchronized SparseIntArray getNonAppVisibleWindowDetails(int uid) {
+        SparseIntArray result = new SparseIntArray();
+        for (int i = 0; i < mNumNonAppVisibleWindowMapByType.size(); i++) {
+            SparseIntArray numNonAppVisibleWindowMap = mNumNonAppVisibleWindowMapByType.valueAt(i);
+            int count = numNonAppVisibleWindowMap.get(uid);
+            if (count > 0) {
+                result.append(mNumNonAppVisibleWindowMapByType.keyAt(i), count);
+            }
+        }
+        return result;
+    }
+
     synchronized void dump(PrintWriter pw, String prefix) {
         pw.print(prefix + "NumNonAppVisibleWindowUidMap:[");
         for (int i = mNumNonAppVisibleWindowMap.size() - 1; i >= 0; i--) {
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 2401f90..c7667b4 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -19,6 +19,7 @@
 wilsonshih@google.com
 jiamingliu@google.com
 pdwilliams@google.com
+charlesccchen@google.com
 
 # Files related to background activity launches
 per-file Background*Start* = set noparent
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index f0e12fe..27f82d9 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -495,11 +495,18 @@
         mTaskNotificationController.notifyTaskListUpdated();
     }
 
-    private void notifyTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess) {
+    private void notifyTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess,
+            boolean removedForAddTask) {
         for (int i = 0; i < mCallbacks.size(); i++) {
             mCallbacks.get(i).onRecentTaskRemoved(task, wasTrimmed, killProcess);
         }
         mTaskNotificationController.notifyTaskListUpdated();
+        if (removedForAddTask) {
+            mTaskNotificationController.notifyRecentTaskRemovedForAddTask(task.mTaskId);
+        }
+    }
+    private void notifyTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess) {
+        notifyTaskRemoved(task, wasTrimmed, killProcess, false /* removedForAddTask */);
     }
 
     /**
@@ -1635,7 +1642,8 @@
                 // from becoming dangling.
                 mHiddenTasks.add(0, removedTask);
             }
-            notifyTaskRemoved(removedTask, false /* wasTrimmed */, false /* killProcess */);
+            notifyTaskRemoved(removedTask, false /* wasTrimmed */, false /* killProcess */,
+                    true /* removedForAddTask */);
             if (DEBUG_RECENTS_TRIM_TASKS) {
                 Slog.d(TAG, "Trimming task=" + removedTask
                         + " for addition of task=" + task);
diff --git a/services/core/java/com/android/server/wm/RefreshRatePolicy.java b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
index e4c34ed..5ce8a32 100644
--- a/services/core/java/com/android/server/wm/RefreshRatePolicy.java
+++ b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
@@ -234,6 +234,12 @@
             return w.mFrameRateVote.reset();
         }
 
+        // If insets animation is running, do not convey the preferred app refresh rate to let VRI
+        // to control the refresh rate.
+        if (w.isInsetsAnimationRunning()) {
+            return w.mFrameRateVote.reset();
+        }
+
         // If the app set a preferredDisplayModeId, the preferred refresh rate is the refresh rate
         // of that mode id.
         if (refreshRateSwitchingType != SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY) {
@@ -272,7 +278,7 @@
     float getPreferredMinRefreshRate(WindowState w) {
         // If app is animating, it's not able to control refresh rate because we want the animation
         // to run in default refresh rate.
-        if (w.isAnimationRunningSelfOrParent()) {
+        if (w.isAnimationRunningSelfOrParent() || w.isInsetsAnimationRunning()) {
             return 0;
         }
 
@@ -295,7 +301,7 @@
     float getPreferredMaxRefreshRate(WindowState w) {
         // If app is animating, it's not able to control refresh rate because we want the animation
         // to run in default refresh rate.
-        if (w.isAnimationRunningSelfOrParent()) {
+        if (w.isAnimationRunningSelfOrParent() || w.isInsetsAnimationRunning()) {
             return 0;
         }
 
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index 70b214c..88e5343 100644
--- a/services/core/java/com/android/server/wm/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java
@@ -361,10 +361,13 @@
         }
 
         // If launched from bubble is specified, then ensure that the caller is system or sysui.
-        if (options.getLaunchedFromBubble() && !isSystemOrSystemUI(callingPid, callingUid)) {
+        if ((options.getLaunchedFromBubble() || options.getTaskAlwaysOnTop())
+                && !isSystemOrSystemUI(callingPid, callingUid)) {
             final String msg = "Permission Denial: starting " + getIntentString(intent)
                     + " from " + callerApp + " (pid=" + callingPid
-                    + ", uid=" + callingUid + ") with launchedFromBubble=true";
+                    + ", uid=" + callingUid + ") with"
+                    + (options.getLaunchedFromBubble() ? " launchedFromBubble=true" : "")
+                    + (options.getTaskAlwaysOnTop() ? " taskAlwaysOnTop=true" : "");
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 0f66b93..07de489 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -1012,4 +1012,15 @@
             }
         }
     }
+
+    @Override
+    public void notifyInsetsAnimationRunningStateChanged(IWindow window, boolean running) {
+        synchronized (mService.mGlobalLock) {
+            final WindowState win = mService.windowForClientLocked(this, window,
+                    false /* throwOnError */);
+            if (win != null) {
+                win.notifyInsetsAnimationRunningStateChanged(running);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 586f3c3..c3649fe 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -62,6 +62,8 @@
     private static final int NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG = 27;
     private static final int NOTIFY_LOCK_TASK_MODE_CHANGED_MSG = 28;
     private static final int NOTIFY_TASK_SNAPSHOT_INVALIDATED_LISTENERS_MSG = 29;
+    private static final int NOTIFY_RECENT_TASK_REMOVED_FOR_ADD_TASK_LISTENERS_MSG = 30;
+
 
     // Delay in notifying task stack change listeners (in millis)
     private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -167,6 +169,10 @@
         l.onRecentTaskListFrozenChanged(m.arg1 != 0);
     };
 
+    private final TaskStackConsumer mNotifyRecentTaskRemovedForAddTask = (l, m) -> {
+        l.onRecentTaskRemovedForAddTask(m.arg1);
+    };
+
     private final TaskStackConsumer mNotifyTaskFocusChanged = (l, m) -> {
         l.onTaskFocusChanged(m.arg1, m.arg2 != 0);
     };
@@ -261,6 +267,9 @@
                 case NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG:
                     forAllRemoteListeners(mNotifyTaskListFrozen, msg);
                     break;
+                case NOTIFY_RECENT_TASK_REMOVED_FOR_ADD_TASK_LISTENERS_MSG:
+                    forAllRemoteListeners(mNotifyRecentTaskRemovedForAddTask, msg);
+                    break;
                 case NOTIFY_TASK_FOCUS_CHANGED_MSG:
                     forAllRemoteListeners(mNotifyTaskFocusChanged, msg);
                     break;
@@ -541,6 +550,15 @@
         msg.sendToTarget();
     }
 
+    /** Called when a task is removed from the recent tasks list. */
+    void notifyRecentTaskRemovedForAddTask(int taskId) {
+        final Message msg = mHandler.obtainMessage(
+                NOTIFY_RECENT_TASK_REMOVED_FOR_ADD_TASK_LISTENERS_MSG, taskId,
+                0 /* unused */);
+        forAllLocalListeners(mNotifyRecentTaskRemovedForAddTask, msg);
+        msg.sendToTarget();
+    }
+
     /** @see ITaskStackListener#onTaskFocusChanged(int, boolean) */
     void notifyTaskFocusChanged(int taskId, boolean focused) {
         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_FOCUS_CHANGED_MSG,
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index ce032b4..c77b1d9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -46,7 +46,6 @@
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost;
-import android.view.WindowInfo;
 import android.view.WindowManager.DisplayImePolicy;
 import android.view.inputmethod.ImeTracker;
 import android.window.ScreenCapture;
@@ -158,26 +157,8 @@
      * accessibility changed.
      */
     public interface WindowsForAccessibilityCallback {
-
         /**
-         * Called when the windows for accessibility changed. This is called if
-         * {@link com.android.server.accessibility.Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2} is
-         * false.
-         *
-         * @param forceSend Send the windows for accessibility even if they haven't changed.
-         * @param topFocusedDisplayId The display Id which has the top focused window.
-         * @param topFocusedWindowToken The window token of top focused window.
-         * @param windows The windows for accessibility.
-         */
-        void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
-                IBinder topFocusedWindowToken, @NonNull List<WindowInfo> windows);
-
-        /**
-         * Called when the windows for accessibility changed. This is called if
-         * {@link com.android.server.accessibility.Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2} is
-         * true.
-         * TODO(b/322444245): Remove screenSize parameter by getting it from
-         *  DisplayManager#getDisplay(int).getRealSize() on the a11y side.
+         * Called when the windows for accessibility changed.
          *
          * @param forceSend Send the windows for accessibility even if they haven't changed.
          * @param topFocusedDisplayId The display Id which has the top focused window.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8268cae..a0c0b98 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3030,8 +3030,8 @@
 
                 mWindowContextListenerController.unregisterWindowContainerListener(clientToken);
 
-                final WindowToken token = wc.asWindowToken();
-                if (token != null && token.isFromClient()) {
+                final WindowToken token = wc != null ? wc.asWindowToken() : null;
+                if (token != null && token.isFromClient() && token.getDisplayContent() != null) {
                     removeWindowToken(token.token, token.getDisplayContent().getDisplayId());
                 }
             }
@@ -10314,7 +10314,7 @@
             mH.post(() -> {
                 Toast.makeText(mContext, Looper.getMainLooper(),
                                 mContext.getString(R.string.screen_not_shared_sensitive_content),
-                                Toast.LENGTH_SHORT)
+                                Toast.LENGTH_LONG)
                         .show();
             });
             // If blocked due to notification protection (null window token) log protection applied
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index fe2bcc7..44f5f51 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -1166,6 +1166,10 @@
                 case "--cameraCompatAspectRatio":
                     runSetCameraCompatAspectRatio(pw);
                     break;
+                case "--isCameraCompatFreeformWindowingTreatmentEnabled":
+                    runSetBooleanFlag(pw, mAppCompatConfiguration
+                            ::setIsCameraCompatFreeformWindowingTreatmentEnabled);
+                    break;
                 default:
                     getErrPrintWriter().println(
                             "Error: Unrecognized letterbox style option: " + arg);
@@ -1260,6 +1264,10 @@
                     case "cameraCompatAspectRatio":
                         mAppCompatConfiguration.resetCameraCompatAspectRatio();
                         break;
+                    case "isCameraCompatFreeformWindowingTreatmentEnabled":
+                        mAppCompatConfiguration
+                                .resetIsCameraCompatFreeformWindowingTreatmentEnabled();
+                        break;
                     default:
                         getErrPrintWriter().println(
                                 "Error: Unrecognized letterbox style option: " + arg);
@@ -1371,6 +1379,7 @@
             mAppCompatConfiguration.resetCameraCompatRefreshEnabled();
             mAppCompatConfiguration.resetCameraCompatRefreshCycleThroughStopEnabled();
             mAppCompatConfiguration.resetCameraCompatAspectRatio();
+            mAppCompatConfiguration.resetIsCameraCompatFreeformWindowingTreatmentEnabled();
         }
     }
 
@@ -1445,6 +1454,10 @@
                     + mAppCompatConfiguration.isUserAppAspectRatioSettingsEnabled());
             pw.println("Is the fullscreen option in user aspect ratio settings enabled: "
                     + mAppCompatConfiguration.isUserAppAspectRatioFullscreenEnabled());
+            pw.println("Default aspect ratio for camera compat freeform: "
+                    + mAppCompatConfiguration.getCameraCompatAspectRatio());
+            pw.println("Is camera compatibility freeform treatment enabled for all apps: "
+                    + mAppCompatConfiguration.isCameraCompatFreeformWindowingTreatmentEnabled());
         }
         return 0;
     }
@@ -1701,10 +1714,13 @@
         pw.println("        happen using the \"stopped -> resumed\" cycle rather than");
         pw.println("        \"paused -> resumed\" cycle.");
         pw.println("      --cameraCompatAspectRatio aspectRatio");
-        pw.println("        Aspect ratio of letterbox for fixed-orientation camera apps, during ");
+        pw.println("        Aspect ratio of letterbox for fixed-orientation camera apps, during");
         pw.println("        freeform camera compat mode. If aspectRatio <= "
                 + AppCompatConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO);
         pw.println("        it will be ignored.");
+        pw.println("      --isCameraCompatFreeformWindowingTreatmentEnabled [true|1|false|0]");
+        pw.println("        Whether camera compat treatment is enabled in freeform mode for all");
+        pw.println("        eligible apps.");
         pw.println("  reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
         pw.println("      |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
         pw.println("      |horizontalPositionMultiplier|verticalPositionMultiplier");
@@ -1714,7 +1730,8 @@
         pw.println("      |persistentPositionMultiplierForHorizontalReachability");
         pw.println("      |persistentPositionMultiplierForVerticalReachability");
         pw.println("      |defaultPositionMultiplierForVerticalReachability");
-        pw.println("      |cameraCompatAspectRatio]");
+        pw.println("      |cameraCompatAspectRatio");
+        pw.println("      |isCameraCompatFreeformWindowingTreatmentEnabled]");
         pw.println("    Resets overrides to default values for specified properties separated");
         pw.println("    by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
         pw.println("    If no arguments provided, all values will be reset.");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 6009848..8294737 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -212,6 +212,7 @@
 import android.os.Trace;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.MergedConfiguration;
@@ -792,6 +793,16 @@
     }
     private final List<DrawHandler> mDrawHandlers = new ArrayList<>();
 
+    /**
+     * Indicates whether inset animations are currently running within the Window.
+     * This value is used by (@link com.android.server.wm.RefreshRatePolicy.java)
+     * to omit setting a frame rate on the WindowState. Insets Animation is unique in that
+     * sense that an app might drive an insets animation for a Window owned by a different
+     * app (such as IME). In that case, we need the app that drives the insets animation
+     * to be able to vote for high refresh rate from VRI.
+     */
+    private boolean mInsetsAnimationRunning;
+
     private final Consumer<SurfaceControl.Transaction> mSeamlessRotationFinishedConsumer = t -> {
         finishSeamlessRotation(t);
         updateSurfacePosition(t);
@@ -3425,7 +3436,8 @@
                 && mAttrs.type != TYPE_PRIVATE_PRESENTATION
                 && !(mAttrs.type == TYPE_PRESENTATION && isOnVirtualDisplay())
         ) {
-            mWmService.mAtmService.mActiveUids.onNonAppSurfaceVisibilityChanged(mOwnerUid, shown);
+            mWmService.mAtmService.mActiveUids.onNonAppSurfaceVisibilityChanged(mOwnerUid,
+                    mAttrs.type, shown);
         }
     }
 
@@ -6180,4 +6192,19 @@
         }
         mWmService.scheduleAnimationLocked();
     }
+
+    void notifyInsetsAnimationRunningStateChanged(boolean running) {
+        if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
+            Trace.instant(TRACE_TAG_WINDOW_MANAGER,
+                    TextUtils.formatSimple("%s: notifyInsetsAnimationRunningStateChanged(%s)",
+                    getName(),
+                    Boolean.toString(running)));
+        }
+        mInsetsAnimationRunning = running;
+        mWmService.scheduleAnimationLocked();
+    }
+
+    boolean isInsetsAnimationRunning() {
+        return mInsetsAnimationRunning;
+    }
 }
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index eaa3a37..4c0cee4 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -38,7 +38,6 @@
         "com_android_server_adb_AdbDebuggingManager.cpp",
         "com_android_server_am_BatteryStatsService.cpp",
         "com_android_server_biometrics_SurfaceToNativeHandleConverter.cpp",
-        "com_android_server_ConsumerIrService.cpp",
         "com_android_server_companion_virtual_InputController.cpp",
         "com_android_server_companion_virtual_VirtualDeviceImpl.cpp",
         "com_android_server_devicepolicy_CryptoTestHelper.cpp",
@@ -63,7 +62,6 @@
         "com_android_server_SystemServer.cpp",
         "com_android_server_tv_TvUinputBridge.cpp",
         "com_android_server_tv_TvInputHal.cpp",
-        "com_android_server_vr_VrManagerService.cpp",
         "com_android_server_UsbAlsaJackDetector.cpp",
         "com_android_server_UsbAlsaMidiDevice.cpp",
         "com_android_server_UsbDeviceManager.cpp",
@@ -75,14 +73,13 @@
         "com_android_server_am_LowMemDetector.cpp",
         "com_android_server_pm_PackageManagerShellCommandDataLoader.cpp",
         "com_android_server_sensor_SensorService.cpp",
-        "com_android_server_utils_LazyJniRegistrar.cpp",
         "com_android_server_wm_TaskFpsCallbackController.cpp",
         "onload.cpp",
         ":lib_cachedAppOptimizer_native",
         ":lib_freezer_native",
-        ":lib_gameManagerService_native",
         ":lib_oomConnection_native",
         ":lib_anrTimer_native",
+        ":lib_lazilyRegisteredServices_native",
     ],
 
     include_dirs: [
@@ -248,13 +245,6 @@
 }
 
 filegroup {
-    name: "lib_gameManagerService_native",
-    srcs: [
-        "com_android_server_app_GameManagerService.cpp",
-    ],
-}
-
-filegroup {
     name: "lib_oomConnection_native",
     srcs: ["com_android_server_am_OomConnection.cpp"],
 }
@@ -265,3 +255,13 @@
         "com_android_server_utils_AnrTimer.cpp",
     ],
 }
+
+filegroup {
+    name: "lib_lazilyRegisteredServices_native",
+    srcs: [
+        "com_android_server_ConsumerIrService.cpp",
+        "com_android_server_app_GameManagerService.cpp",
+        "com_android_server_utils_LazyJniRegistrar.cpp",
+        "com_android_server_vr_VrManagerService.cpp",
+    ],
+}
diff --git a/services/core/jni/com_android_server_utils_LazyJniRegistrar.cpp b/services/core/jni/com_android_server_utils_LazyJniRegistrar.cpp
index ad7781e..0c0f8b0 100644
--- a/services/core/jni/com_android_server_utils_LazyJniRegistrar.cpp
+++ b/services/core/jni/com_android_server_utils_LazyJniRegistrar.cpp
@@ -22,6 +22,7 @@
 
 // Forward declared per-class registration methods.
 int register_android_server_ConsumerIrService(JNIEnv* env);
+int register_android_server_app_GameManagerService(JNIEnv* env);
 int register_android_server_vr_VrManagerService(JNIEnv* env);
 
 namespace {
@@ -33,12 +34,17 @@
     register_android_server_ConsumerIrService(env);
 }
 
+void registerGameManagerService(JNIEnv* env, jclass) {
+    register_android_server_app_GameManagerService(env);
+}
+
 void registerVrManagerService(JNIEnv* env, jclass) {
     register_android_server_vr_VrManagerService(env);
 }
 
 static const JNINativeMethod sJniRegistrarMethods[] = {
         {"registerConsumerIrService", "()V", (void*)registerConsumerIrService},
+        {"registerGameManagerService", "()V", (void*)registerGameManagerService},
         {"registerVrManagerService", "()V", (void*)registerVrManagerService},
 };
 
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index c170ae9..df37ec3 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -65,7 +65,6 @@
 int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env);
 int register_android_server_companion_virtual_InputController(JNIEnv* env);
 int register_android_server_companion_virtual_VirtualDeviceImpl(JNIEnv* env);
-int register_android_server_app_GameManagerService(JNIEnv* env);
 int register_com_android_server_wm_TaskFpsCallbackController(JNIEnv* env);
 int register_com_android_server_display_DisplayControl(JNIEnv* env);
 int register_com_android_server_SystemClockTime(JNIEnv* env);
@@ -131,7 +130,6 @@
     register_android_server_sensor_SensorService(vm, env);
     register_android_server_companion_virtual_InputController(env);
     register_android_server_companion_virtual_VirtualDeviceImpl(env);
-    register_android_server_app_GameManagerService(env);
     register_com_android_server_wm_TaskFpsCallbackController(env);
     register_com_android_server_display_DisplayControl(env);
     register_com_android_server_SystemClockTime(env);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6292cbf..6f0d26a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -19245,21 +19245,23 @@
         }
     }
 
-    private boolean isAnyResetPasswordTokenActiveForUser(int userId) {
+    private boolean isAnyResetPasswordTokenActiveForUserLocked(int userId) {
         return mDevicePolicyEngine
                 .getLocalPoliciesSetByAdmins(PolicyDefinition.RESET_PASSWORD_TOKEN, userId)
-                .values()
+                .entrySet()
                 .stream()
-                .anyMatch((p) -> isResetPasswordTokenActiveForUserLocked(p.getValue(), userId));
+                .anyMatch((e) -> {
+                    EnforcingAdmin admin = e.getKey();
+                    PolicyValue<Long> policyValue = e.getValue();
+                    return isResetPasswordTokenActiveForUserLocked(policyValue.getValue(), userId)
+                              && isEncryptionAware(admin.getPackageName(), userId);
+                });
     }
 
     private boolean isResetPasswordTokenActiveForUserLocked(
             long passwordTokenHandle, int userHandle) {
-        if (passwordTokenHandle != 0) {
-            return mInjector.binderWithCleanCallingIdentity(() ->
+        return passwordTokenHandle != 0 && mInjector.binderWithCleanCallingIdentity(() ->
                     mLockPatternUtils.isEscrowTokenActive(passwordTokenHandle, userHandle));
-        }
-        return false;
     }
 
     @Override
@@ -21108,10 +21110,10 @@
         Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
                 String.format(NOT_SYSTEM_CALLER_MSG,
                         "call canProfileOwnerResetPasswordWhenLocked"));
-        if (Flags.resetPasswordWithTokenCoexistence()) {
-            return isAnyResetPasswordTokenActiveForUser(userId);
-        }
         synchronized (getLockObject()) {
+            if (Flags.resetPasswordWithTokenCoexistence()) {
+                return isAnyResetPasswordTokenActiveForUserLocked(userId);
+            }
             final ActiveAdmin poAdmin = getProfileOwnerAdminLocked(userId);
             DevicePolicyData policy = getUserData(userId);
             if (poAdmin == null
@@ -21120,26 +21122,29 @@
                             policy.mPasswordTokenHandle, userId)) {
                 return false;
             }
-            final ApplicationInfo poAppInfo;
-            try {
-                poAppInfo = mIPackageManager.getApplicationInfo(
-                        poAdmin.info.getPackageName(), 0 /* flags */, userId);
-            } catch (RemoteException e) {
-                Slogf.e(LOG_TAG, "Failed to query PO app info", e);
-                return false;
-            }
-            if (poAppInfo == null) {
-                Slogf.wtf(LOG_TAG, "Cannot find AppInfo for profile owner");
-                return false;
-            }
-            if (!poAppInfo.isEncryptionAware()) {
-                return false;
-            }
-            Slogf.d(LOG_TAG, "PO should be able to reset password from direct boot");
-            return true;
+            return isEncryptionAware(poAdmin.info.getPackageName(), userId);
         }
     }
 
+    private boolean isEncryptionAware(String packageName, int userId) {
+        final ApplicationInfo poAppInfo;
+        try {
+            poAppInfo = mIPackageManager.getApplicationInfo(packageName, 0 /* flags */, userId);
+        } catch (RemoteException e) {
+            Slogf.e(LOG_TAG, "Failed to query PO / role holder's app info", e);
+            return false;
+        }
+        if (poAppInfo == null) {
+            Slogf.wtf(LOG_TAG, "Cannot find AppInfo for PO / role holder");
+            return false;
+        }
+        if (!poAppInfo.isEncryptionAware()) {
+            return false;
+        }
+        Slogf.d(LOG_TAG, "PO / role holder should be able to reset password from direct boot");
+        return true;
+    }
+
     @Override
     public String getEnrollmentSpecificId(String callerPackage) {
         if (!mHasFeature) {
@@ -23173,6 +23178,10 @@
                 MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
         CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_KEYGUARD,
                 MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
+        if (Flags.lockNowCoexistence()) {
+            CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK,
+                    MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
+        }
         CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
                 MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
 
@@ -23247,8 +23256,10 @@
                 MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
         CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCATION,
                 MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
-        CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK,
-                MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
+        if (!Flags.lockNowCoexistence()) {
+            CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK,
+                    MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
+        }
         CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK_TASK,
                 MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
         CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_MODIFY_USERS,
@@ -23703,24 +23714,7 @@
     }
 
     public void setMtePolicy(int flags, String callerPackageName) {
-        final Set<Integer> allowedModes =
-                Set.of(
-                        DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY,
-                        DevicePolicyManager.MTE_DISABLED,
-                        DevicePolicyManager.MTE_ENABLED);
-        Preconditions.checkArgument(
-                allowedModes.contains(flags), "Provided mode is not one of the allowed values.");
-        // In general, this API should be available when "bootctl_settings_toggle" is set, which
-        // signals that there is a control for MTE in the user settings and this API fundamentally
-        // is a way for the device admin to override that setting.
-        // Allow bootctl_device_policy_manager as an override, e.g. to offer the
-        // DevicePolicyManager only without a visible user setting.
-        if (!mInjector.systemPropertiesGetBoolean(
-                "ro.arm64.memtag.bootctl_device_policy_manager",
-                mInjector.systemPropertiesGetBoolean(
-                        "ro.arm64.memtag.bootctl_settings_toggle", false))) {
-            throw new UnsupportedOperationException("device does not support MTE");
-        }
+        checkMteSupportedAndAllowedPolicy(flags);
         final CallerIdentity caller = getCallerIdentity(callerPackageName);
         // For now we continue to restrict the DISABLED setting to device owner - we might need
         // another permission for this in future.
@@ -23778,6 +23772,53 @@
     }
 
     @Override
+    public void setMtePolicyBySystem(
+            @NonNull String systemEntity, int policy) {
+        Objects.requireNonNull(systemEntity);
+        checkMteSupportedAndAllowedPolicy(policy);
+
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only system services can call setMtePolicyBySystem");
+
+        if (!Flags.setMtePolicyCoexistence()) {
+            throw new UnsupportedOperationException("System can not set MTE policy only");
+        }
+
+        EnforcingAdmin admin = EnforcingAdmin.createSystemEnforcingAdmin(systemEntity);
+        if (policy != DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY) {
+            mDevicePolicyEngine.setGlobalPolicy(
+                    PolicyDefinition.MEMORY_TAGGING,
+                    admin,
+                    new IntegerPolicyValue(policy));
+        } else {
+            mDevicePolicyEngine.removeGlobalPolicy(
+                    PolicyDefinition.MEMORY_TAGGING,
+                    admin);
+        }
+    }
+
+    private void checkMteSupportedAndAllowedPolicy(int policy) {
+        final Set<Integer> allowedModes =
+                Set.of(
+                        DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY,
+                        DevicePolicyManager.MTE_DISABLED,
+                        DevicePolicyManager.MTE_ENABLED);
+        Preconditions.checkArgument(
+                allowedModes.contains(policy), "Provided mode is not one of the allowed values.");
+        // In general, this API should be available when "bootctl_settings_toggle" is set, which
+        // signals that there is a control for MTE in the user settings and this API fundamentally
+        // is a way for the device admin to override that setting.
+        // Allow bootctl_device_policy_manager as an override, e.g. to offer the
+        // DevicePolicyManager only without a visible user setting.
+        if (!mInjector.systemPropertiesGetBoolean(
+                "ro.arm64.memtag.bootctl_device_policy_manager",
+                mInjector.systemPropertiesGetBoolean(
+                        "ro.arm64.memtag.bootctl_settings_toggle", false))) {
+            throw new UnsupportedOperationException("device does not support MTE");
+        }
+    }
+
+    @Override
     public int getMtePolicy(String callerPackageName) {
         final CallerIdentity caller = getCallerIdentity(callerPackageName);
         if (Flags.setMtePolicyCoexistence()) {
@@ -24156,6 +24197,7 @@
         String supervisionBackupId = "36.2.supervision-support";
         boolean supervisionMigrated = maybeMigrateResetPasswordTokenLocked(supervisionBackupId);
         supervisionMigrated |= maybeMigrateSuspendedPackagesLocked(supervisionBackupId);
+        supervisionMigrated |= maybeMigrateSetKeyguardDisabledFeatures(supervisionBackupId);
         if (supervisionMigrated) {
             Slogf.i(LOG_TAG, "Backup made: " + supervisionBackupId);
         }
@@ -24169,6 +24211,38 @@
         // Additional migration steps should repeat the pattern above with a new backupId.
     }
 
+    @GuardedBy("getLockObject()")
+    private boolean maybeMigrateSetKeyguardDisabledFeatures(String backupId) {
+        Slog.i(LOG_TAG, "Migrating set keyguard disabled features to policy engine");
+        if (!Flags.setKeyguardDisabledFeaturesCoexistence()) {
+            return false;
+        }
+        if (mOwners.isSetKeyguardDisabledFeaturesMigrated()) {
+            return false;
+        }
+        // Create backup if none exists
+        mDevicePolicyEngine.createBackup(backupId);
+        try {
+            iterateThroughDpcAdminsLocked((admin, enforcingAdmin) -> {
+                if (admin.disabledKeyguardFeatures == 0) {
+                    return;
+                }
+                int userId = enforcingAdmin.getUserId();
+                mDevicePolicyEngine.setLocalPolicy(
+                        PolicyDefinition.KEYGUARD_DISABLED_FEATURES,
+                        enforcingAdmin,
+                        new IntegerPolicyValue(admin.disabledKeyguardFeatures),
+                        userId);
+            });
+        } catch (Exception e) {
+            Slog.wtf(LOG_TAG, "Failed to migrate set keyguard disabled to policy engine", e);
+        }
+
+        Slog.i(LOG_TAG, "Marking set keyguard disabled features migration complete");
+        mOwners.markSetKeyguardDisabledFeaturesMigrated();
+        return true;
+    }
+
     private void migratePermissionGrantStatePolicies() {
         Slogf.i(LOG_TAG, "Migrating PERMISSION_GRANT policy to device policy engine.");
         for (UserInfo userInfo : mUserManager.getUsers()) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index be4eea4..1c75f2f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -695,6 +695,19 @@
         }
     }
 
+    void markSetKeyguardDisabledFeaturesMigrated() {
+        synchronized (mData) {
+            mData.mSetKeyguardDisabledFeaturesMigrated = true;
+            mData.writeDeviceOwner();
+        }
+    }
+
+    boolean isSetKeyguardDisabledFeaturesMigrated() {
+        synchronized (mData) {
+            return mData.mSetKeyguardDisabledFeaturesMigrated;
+        }
+    }
+
     @GuardedBy("mData")
     void pushToAppOpsLocked() {
         if (!mSystemReady) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
index 1cae924..caaf096 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
@@ -95,6 +95,8 @@
             "resetPasswordWithTokenMigrated";
     private static final String ATTR_MEMORY_TAGGING_MIGRATED =
             "memoryTaggingMigrated";
+    private static final String ATTR_SET_KEYGUARD_DISABLED_FEATURES_MIGRATED =
+            "setKeyguardDisabledFeaturesMigrated";
 
     private static final String ATTR_MIGRATED_POST_UPGRADE = "migratedPostUpgrade";
 
@@ -129,6 +131,7 @@
     boolean mSuspendedPackagesMigrated = false;
     boolean mResetPasswordWithTokenMigrated = false;
     boolean mMemoryTaggingMigrated = false;
+    boolean mSetKeyguardDisabledFeaturesMigrated = false;
 
     boolean mPoliciesMigratedPostUpdate = false;
 
@@ -434,6 +437,10 @@
                 out.attributeBoolean(null, ATTR_MEMORY_TAGGING_MIGRATED,
                         mMemoryTaggingMigrated);
             }
+            if (Flags.setKeyguardDisabledFeaturesCoexistence()) {
+                out.attributeBoolean(null, ATTR_SET_KEYGUARD_DISABLED_FEATURES_MIGRATED,
+                        mSetKeyguardDisabledFeaturesMigrated);
+            }
             out.endTag(null, TAG_POLICY_ENGINE_MIGRATION);
 
         }
@@ -510,6 +517,10 @@
                     mMemoryTaggingMigrated = Flags.setMtePolicyCoexistence()
                             && parser.getAttributeBoolean(null,
                             ATTR_MEMORY_TAGGING_MIGRATED, false);
+                    mSetKeyguardDisabledFeaturesMigrated =
+                            Flags.setKeyguardDisabledFeaturesCoexistence()
+                                    && parser.getAttributeBoolean(null,
+                                    ATTR_SET_KEYGUARD_DISABLED_FEATURES_MIGRATED, false);
                     break;
                 default:
                     Slog.e(TAG, "Unexpected tag: " + tag);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 980fcac..112414e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -27,6 +27,7 @@
 import static android.system.OsConstants.O_RDONLY;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.hardware.input.Flags.inputManagerLifecycleSupport;
 import static com.android.server.utils.TimingsTraceAndSlog.SYSTEM_SERVER_TIMING_TAG;
 import static com.android.tradeinmode.flags.Flags.enableTradeInMode;
 
@@ -421,6 +422,8 @@
             "com.android.server.wifi.aware.WifiAwareService";
     private static final String WIFI_P2P_SERVICE_CLASS =
             "com.android.server.wifi.p2p.WifiP2pService";
+    private static final String WIFI_USD_SERVICE_CLASS =
+            "com.android.server.wifi.usd.UsdService";
     private static final String CONNECTIVITY_SERVICE_APEX_PATH =
             "/apex/com.android.tethering/javalib/service-connectivity.jar";
     private static final String CONNECTIVITY_SERVICE_INITIALIZER_CLASS =
@@ -1654,7 +1657,12 @@
             t.traceEnd();
 
             t.traceBegin("StartInputManagerService");
-            inputManager = new InputManagerService(context);
+            if (inputManagerLifecycleSupport()) {
+                inputManager = mSystemServiceManager.startService(
+                        InputManagerService.Lifecycle.class).getService();
+            } else {
+                inputManager = new InputManagerService(context);
+            }
             t.traceEnd();
 
             t.traceBegin("DeviceStateManagerService");
@@ -1675,8 +1683,10 @@
             ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
                     DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
                             | DUMP_FLAG_PROTO);
-            ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
-                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
+            if (!inputManagerLifecycleSupport()) {
+                ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
+                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
+            }
             t.traceEnd();
 
             t.traceBegin("SetWindowManagerService");
@@ -2137,6 +2147,13 @@
                 mSystemServiceManager.startServiceFromJar(
                         WIFI_SCANNING_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                 t.traceEnd();
+                // Start USD service
+                if (android.net.wifi.flags.Flags.usd()) {
+                    t.traceBegin("StartUsd");
+                    mSystemServiceManager.startServiceFromJar(
+                            WIFI_USD_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
+                    t.traceEnd();
+                }
             }
 
             if (context.getPackageManager().hasSystemFeature(
@@ -3350,16 +3367,18 @@
                 reportWtf("Notifying NetworkTimeService running", e);
             }
             t.traceEnd();
-            t.traceBegin("MakeInputManagerServiceReady");
-            try {
-                // TODO(BT) Pass parameter to input manager
-                if (inputManagerF != null) {
-                    inputManagerF.systemRunning();
+            if (!inputManagerLifecycleSupport()) {
+                t.traceBegin("MakeInputManagerServiceReady");
+                try {
+                    // TODO(BT) Pass parameter to input manager
+                    if (inputManagerF != null) {
+                        inputManagerF.systemRunning();
+                    }
+                } catch (Throwable e) {
+                    reportWtf("Notifying InputManagerService running", e);
                 }
-            } catch (Throwable e) {
-                reportWtf("Notifying InputManagerService running", e);
+                t.traceEnd();
             }
-            t.traceEnd();
             t.traceBegin("MakeTelephonyRegistryReady");
             try {
                 if (telephonyRegistryF != null) {
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index e307e52..228e32e 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -70,6 +70,7 @@
     private int mUsageSetting;
     private boolean mUploadEnabled;
 
+    private static boolean sVerityEnforced;
     private boolean mAdbActive;
 
     private IProfCollectd mIProfcollect;
@@ -117,6 +118,13 @@
             mUsageSetting = -1;
         }
 
+        // Check verity, disable profile upload if not enforced.
+        final String verityMode = SystemProperties.get("ro.boot.veritymode");
+        sVerityEnforced = verityMode.equals("enforcing");
+        if (!sVerityEnforced) {
+            Log.d(LOG_TAG, "verity is not enforced: " + verityMode);
+        }
+
         mUploadEnabled =
             context.getResources().getBoolean(R.bool.config_profcollectReportUploaderEnabled);
 
@@ -373,6 +381,10 @@
                 Log.i(LOG_TAG, "Upload is not enabled.");
                 return;
             }
+            if (!sVerityEnforced) {
+                Log.i(LOG_TAG, "Verity is not enforced.");
+                return;
+            }
             Intent intent = new Intent()
                     .setPackage("com.android.shell")
                     .setAction("com.android.shell.action.PROFCOLLECT_UPLOAD")
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt
index 5a59c57..14dce10 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt
@@ -21,8 +21,6 @@
 import android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_DEFAULT
 import android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_DENIED
 import android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED
-import android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED
-import android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_OPEN
 import android.content.pm.PackageManager
 import android.content.pm.verify.domain.DomainSet
 import android.os.Parcel
@@ -32,14 +30,8 @@
 import android.util.Slog
 import android.util.Xml
 import com.android.internal.os.BackgroundThread
-import com.android.server.pm.verify.pkg.VerifierController
 import com.android.server.testutils.whenever
 import com.google.common.truth.Truth.assertThat
-import java.io.File
-import java.io.FileInputStream
-import java.io.FileNotFoundException
-import java.io.FileOutputStream
-import java.io.IOException
 import libcore.io.IoUtils
 import org.junit.Before
 import org.junit.Rule
@@ -53,6 +45,11 @@
 import org.mockito.MockitoAnnotations
 import org.xmlpull.v1.XmlPullParser
 import org.xmlpull.v1.XmlPullParserException
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileNotFoundException
+import java.io.FileOutputStream
+import java.io.IOException
 
 @Presubmit
 class PackageInstallerSessionTest {
@@ -199,9 +196,6 @@
             /* stagedSessionErrorCode */ PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
             /* stagedSessionErrorMessage */ "some error",
             /* preVerifiedDomains */ DomainSet(setOf("com.foo", "com.bar")),
-            /* VerifierController */ mock(VerifierController::class.java),
-            /* initialVerificationPolicy */ VERIFICATION_POLICY_BLOCK_FAIL_OPEN,
-            /* currentVerificationPolicy */ VERIFICATION_POLICY_BLOCK_FAIL_CLOSED,
             /* installDependencyHelper */ null
         )
     }
@@ -257,7 +251,6 @@
                                 mTmpDir,
                                 mock(PackageSessionProvider::class.java),
                                 mock(SilentUpdatePolicy::class.java),
-                                mock(VerifierController::class.java),
                                 mock(InstallDependencyHelper::class.java)
                             )
                             ret.add(session)
@@ -295,7 +288,6 @@
         assertThat(expected.installerPackageName).isEqualTo(actual.installerPackageName)
         assertThat(expected.isMultiPackage).isEqualTo(actual.isMultiPackage)
         assertThat(expected.isStaged).isEqualTo(actual.isStaged)
-        assertThat(expected.forceVerification).isEqualTo(actual.forceVerification)
     }
 
     private fun assertEquals(
@@ -346,8 +338,6 @@
         assertThat(expected.childSessionIds).asList()
             .containsExactlyElementsIn(actual.childSessionIds.toList())
         assertThat(expected.preVerifiedDomains).isEqualTo(actual.preVerifiedDomains)
-        assertThat(expected.initialVerificationPolicy).isEqualTo(actual.initialVerificationPolicy)
-        assertThat(expected.currentVerificationPolicy).isEqualTo(actual.currentVerificationPolicy)
     }
 
     private fun assertInstallSourcesEquivalent(expected: InstallSource, actual: InstallSource) {
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java
index 5da202f..f5c0de0 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java
@@ -20,6 +20,7 @@
 import static android.content.UriRelativeFilter.FRAGMENT;
 import static android.content.UriRelativeFilterGroup.ACTION_ALLOW;
 import static android.content.UriRelativeFilterGroup.ACTION_BLOCK;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS;
 import static android.os.PatternMatcher.PATTERN_ADVANCED_GLOB;
 import static android.os.PatternMatcher.PATTERN_LITERAL;
 import static android.os.PatternMatcher.PATTERN_PREFIX;
@@ -111,6 +112,8 @@
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageUserStateInternal;
 
+import com.google.android.collect.Sets;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -212,6 +215,30 @@
     }
 
     @Test
+    public void testParse_withCache_hiddenApiAllowlist() throws Exception {
+        CachePackageNameParser pp = new CachePackageNameParser(null);
+
+        pp.setCacheDir(mTmpDir);
+        // The first parse will write this package to the cache.
+        pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);
+
+        // Now attempt to parse the package again, should return the
+        // cached result.
+        ParsedPackage pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
+                true /* useCaches */);
+        assertEquals("cache_android", pkg.getPackageName());
+
+        // Create application info
+        pkg.hideAsFinal();
+        ApplicationInfo aInfo = PackageInfoUtils.generateApplicationInfo(pkg, 0,
+                PackageUserStateInternal.DEFAULT, 0, mockPkgSetting(pkg));
+
+        // verify ext flag for hidden APIs allowlist
+        assertEquals(PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS,
+                aInfo.privateFlagsExt & PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS);
+    }
+
+    @Test
     public void test_serializePackage() throws Exception {
         try (PackageParser2 pp = PackageParserUtils.forParsingFileWithDefaults()) {
             AndroidPackage pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
@@ -856,35 +883,37 @@
      */
     public static class CachePackageNameParser extends PackageParser2 {
 
+        private static final Callback CALLBACK = new Callback() {
+            @Override
+            public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) {
+                return true;
+            }
+
+            @Override
+            public boolean hasFeature(String feature) {
+                return false;
+            }
+
+            @Override
+            public Set<String> getHiddenApiWhitelistedApps() {
+                return Sets.newArraySet("cache_android");
+            }
+
+            @Override
+            public Set<String> getInstallConstraintsAllowlist() {
+                return new ArraySet<>();
+            }
+        };
+
         CachePackageNameParser(@Nullable File cacheDir) {
-            super(null, null, null, new Callback() {
-                @Override
-                public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) {
-                    return true;
-                }
-
-                @Override
-                public boolean hasFeature(String feature) {
-                    return false;
-                }
-
-                @Override
-                public Set<String> getHiddenApiWhitelistedApps() {
-                    return new ArraySet<>();
-                }
-
-                @Override
-                public Set<String> getInstallConstraintsAllowlist() {
-                    return new ArraySet<>();
-                }
-            });
+            super(null, null, null, CALLBACK);
             if (cacheDir != null) {
                 setCacheDir(cacheDir);
             }
         }
 
         void setCacheDir(@NonNull File cacheDir) {
-            this.mCacher = new PackageCacher(cacheDir) {
+            this.mCacher = new PackageCacher(cacheDir, CALLBACK) {
                 @Override
                 public ParsedPackage fromCacheEntry(byte[] cacheEntry) {
                     ParsedPackage parsed = super.fromCacheEntry(cacheEntry);
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerificationStatusTrackerTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerificationStatusTrackerTest.java
deleted file mode 100644
index 787fb5a..0000000
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerificationStatusTrackerTest.java
+++ /dev/null
@@ -1,113 +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.server.pm.verify.pkg;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.concurrent.TimeUnit;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerificationStatusTrackerTest {
-    private static final String TEST_PACKAGE_NAME = "com.foo";
-    private static final long TEST_REQUEST_START_TIME = 100L;
-    private static final long TEST_TIMEOUT_DURATION_MILLIS = TimeUnit.MINUTES.toMillis(1);
-    private static final long TEST_TIMEOUT_EXTENDED_MILLIS = TimeUnit.MINUTES.toMillis(2);
-    private static final long TEST_MAX_TIMEOUT_DURATION_MILLIS =
-            TimeUnit.MINUTES.toMillis(10);
-
-    @Mock
-    VerifierController.Injector mInjector;
-    private VerificationStatusTracker mTracker;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mInjector.getVerificationRequestTimeoutMillis()).thenReturn(
-                TEST_TIMEOUT_DURATION_MILLIS);
-        when(mInjector.getMaxVerificationExtendedTimeoutMillis()).thenReturn(
-                TEST_MAX_TIMEOUT_DURATION_MILLIS);
-        // Mock time forward as the code continues to check for the current time
-        when(mInjector.getCurrentTimeMillis())
-                .thenReturn(TEST_REQUEST_START_TIME)
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 1)
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS)
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_MAX_TIMEOUT_DURATION_MILLIS - 100)
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_MAX_TIMEOUT_DURATION_MILLIS);
-        mTracker = new VerificationStatusTracker(TEST_TIMEOUT_DURATION_MILLIS,
-                TEST_MAX_TIMEOUT_DURATION_MILLIS, mInjector);
-    }
-
-    @Test
-    public void testTimeout() {
-        assertThat(mTracker.getTimeoutTime()).isEqualTo(
-                TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS);
-        // It takes two calls to set the timeout, because the timeout time hasn't been reached for
-        // the first calls
-        assertThat(mTracker.isTimeout()).isFalse();
-        assertThat(mTracker.isTimeout()).isTrue();
-    }
-
-    @Test
-    public void testTimeoutExtended() {
-        assertThat(mTracker.getTimeoutTime()).isEqualTo(
-                TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS);
-        assertThat(mTracker.extendTimeRemaining(TEST_TIMEOUT_EXTENDED_MILLIS))
-                .isEqualTo(TEST_TIMEOUT_EXTENDED_MILLIS);
-        assertThat(mTracker.getTimeoutTime()).isEqualTo(
-                TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS
-                        + TEST_TIMEOUT_EXTENDED_MILLIS);
-
-        // It would take 3 calls to set the timeout, because the timeout time hasn't been reached
-        // for the first 2 time checks, but querying the remaining time also does a time check.
-        assertThat(mTracker.isTimeout()).isFalse();
-        assertThat(mTracker.getRemainingTime()).isGreaterThan(0);
-        assertThat(mTracker.isTimeout()).isTrue();
-        assertThat(mTracker.getRemainingTime()).isEqualTo(0);
-    }
-
-    @Test
-    public void testTimeoutExtendedExceedsMax() {
-        assertThat(mTracker.getTimeoutTime()).isEqualTo(
-                TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS);
-        assertThat(mTracker.extendTimeRemaining(TEST_MAX_TIMEOUT_DURATION_MILLIS))
-                .isEqualTo(TEST_MAX_TIMEOUT_DURATION_MILLIS - TEST_TIMEOUT_DURATION_MILLIS);
-        assertThat(mTracker.getTimeoutTime()).isEqualTo(
-                TEST_REQUEST_START_TIME + TEST_MAX_TIMEOUT_DURATION_MILLIS);
-        // It takes 4 calls to set the timeout, because the timeout time hasn't been reached for
-        // the first 3 calls
-        assertThat(mTracker.isTimeout()).isFalse();
-        assertThat(mTracker.isTimeout()).isFalse();
-        assertThat(mTracker.isTimeout()).isFalse();
-        assertThat(mTracker.isTimeout()).isTrue();
-        assertThat(mTracker.getRemainingTime()).isEqualTo(0);
-    }
-}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerifierControllerTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerifierControllerTest.java
deleted file mode 100644
index 3046d4b..0000000
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerifierControllerTest.java
+++ /dev/null
@@ -1,535 +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.server.pm.verify.pkg;
-
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_OPEN;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.expectThrows;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningInfo;
-import android.content.pm.VersionedPackage;
-import android.content.pm.verify.pkg.IVerifierService;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.platform.test.annotations.Presubmit;
-import android.util.Pair;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.internal.infra.AndroidFuture;
-import com.android.internal.infra.ServiceConnector;
-import com.android.server.pm.Computer;
-import com.android.server.pm.PackageInstallerSession;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerifierControllerTest {
-    private static final int TEST_ID = 100;
-    private static final String TEST_PACKAGE_NAME = "com.foo";
-    private static final ComponentName TEST_VERIFIER_COMPONENT_NAME =
-            new ComponentName("com.verifier", "com.verifier.Service");
-    private static final Uri TEST_PACKAGE_URI = Uri.parse("test://test");
-    private static final SigningInfo TEST_SIGNING_INFO = new SigningInfo();
-    private static final SharedLibraryInfo TEST_SHARED_LIBRARY_INFO1 =
-            new SharedLibraryInfo("sharedLibPath1", TEST_PACKAGE_NAME,
-                    Collections.singletonList("path1"), "sharedLib1", 101,
-                    SharedLibraryInfo.TYPE_DYNAMIC, new VersionedPackage(TEST_PACKAGE_NAME, 1),
-                    null, null, false);
-    private static final SharedLibraryInfo TEST_SHARED_LIBRARY_INFO2 =
-            new SharedLibraryInfo("sharedLibPath2", TEST_PACKAGE_NAME,
-                    Collections.singletonList("path2"), "sharedLib2", 102,
-                    SharedLibraryInfo.TYPE_DYNAMIC,
-                    new VersionedPackage(TEST_PACKAGE_NAME, 2), null, null, false);
-    private static final String TEST_KEY = "test key";
-    private static final String TEST_VALUE = "test value";
-    private static final String TEST_FAILURE_MESSAGE = "verification failed!";
-    private static final long TEST_REQUEST_START_TIME = 0L;
-    private static final long TEST_TIMEOUT_DURATION_MILLIS = TimeUnit.MINUTES.toMillis(1);
-    private static final long TEST_MAX_TIMEOUT_DURATION_MILLIS =
-            TimeUnit.MINUTES.toMillis(10);
-    private static final long TEST_VERIFIER_CONNECTION_TIMEOUT_DURATION_MILLIS =
-            TimeUnit.SECONDS.toMillis(10);
-    private static final int TEST_POLICY = VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-
-    private final ArrayList<SharedLibraryInfo> mTestDeclaredLibraries = new ArrayList<>();
-    private final PersistableBundle mTestExtensionParams = new PersistableBundle();
-    @Mock
-    Context mContext;
-    @Mock
-    Handler mHandler;
-    @Mock
-    VerifierController.Injector mInjector;
-    @Mock
-    ServiceConnector<IVerifierService> mMockServiceConnector;
-    @Mock
-    IVerifierService mMockService;
-    @Mock
-    Computer mSnapshot;
-    Supplier<Computer> mSnapshotSupplier = () -> mSnapshot;
-    @Mock
-    PackageInstallerSession.VerifierCallback mSessionCallback;
-
-    private VerifierController mVerifierController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        // Mock that the UID of this test becomes the UID of the verifier
-        when(mSnapshot.getPackageUidInternal(anyString(), anyLong(), anyInt(), anyInt()))
-                .thenReturn(InstrumentationRegistry.getInstrumentation().getContext()
-                        .getApplicationInfo().uid);
-        when(mInjector.getVerifierPackageName(any(Computer.class), anyInt())).thenReturn(
-                TEST_VERIFIER_COMPONENT_NAME.getPackageName());
-        when(mInjector.getRemoteService(
-                any(Computer.class), any(Context.class), anyInt(), any(Handler.class)
-        )).thenReturn(new Pair<>(mMockServiceConnector, TEST_VERIFIER_COMPONENT_NAME));
-        when(mInjector.getVerificationRequestTimeoutMillis()).thenReturn(
-                TEST_TIMEOUT_DURATION_MILLIS);
-        when(mInjector.getMaxVerificationExtendedTimeoutMillis()).thenReturn(
-                TEST_MAX_TIMEOUT_DURATION_MILLIS);
-        when(mInjector.getVerifierConnectionTimeoutMillis()).thenReturn(
-                TEST_VERIFIER_CONNECTION_TIMEOUT_DURATION_MILLIS
-        );
-        // Mock time forward as the code continues to check for the current time
-        when(mInjector.getCurrentTimeMillis())
-                .thenReturn(TEST_REQUEST_START_TIME)
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS + 1);
-        when(mMockServiceConnector.post(any(ServiceConnector.VoidJob.class)))
-                .thenAnswer(
-                        i -> {
-                            ((ServiceConnector.VoidJob) i.getArguments()[0]).run(mMockService);
-                            return new AndroidFuture<>();
-                        });
-        when(mMockServiceConnector.run(any(ServiceConnector.VoidJob.class)))
-                .thenAnswer(
-                        i -> {
-                            ((ServiceConnector.VoidJob) i.getArguments()[0]).run(mMockService);
-                            return true;
-                        });
-
-        mTestDeclaredLibraries.add(TEST_SHARED_LIBRARY_INFO1);
-        mTestDeclaredLibraries.add(TEST_SHARED_LIBRARY_INFO2);
-        mTestExtensionParams.putString(TEST_KEY, TEST_VALUE);
-
-        mVerifierController = new VerifierController(mContext, mHandler, mInjector);
-    }
-
-    @Test
-    public void testVerifierNotInstalled() {
-        when(mInjector.getVerifierPackageName(any(Computer.class), anyInt())).thenReturn(null);
-        when(mInjector.getRemoteService(
-                any(Computer.class), any(Context.class), anyInt(), any(Handler.class)
-        )).thenReturn(null);
-        assertThat(mVerifierController.getVerifierPackageName(mSnapshotSupplier, 0)).isNull();
-        assertThat(mVerifierController.bindToVerifierServiceIfNeeded(mSnapshotSupplier, 0))
-                .isFalse();
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isFalse();
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ true)).isFalse();
-        verifyZeroInteractions(mSessionCallback);
-    }
-
-    @Test
-    public void testRebindService() {
-        assertThat(mVerifierController.bindToVerifierServiceIfNeeded(mSnapshotSupplier, 0))
-                .isTrue();
-    }
-
-    @Test
-    public void testVerifierAvailableButNotConnected() {
-        assertThat(mVerifierController.getVerifierPackageName(mSnapshotSupplier, 0)).isNotNull();
-        when(mInjector.getRemoteService(
-                any(Computer.class), any(Context.class), anyInt(), any(Handler.class)
-        )).thenReturn(null);
-        assertThat(mVerifierController.bindToVerifierServiceIfNeeded(mSnapshotSupplier, 0))
-                .isFalse();
-        // Test that nothing crashes if the verifier is available even though there's no bound
-        mVerifierController.notifyPackageNameAvailable(TEST_PACKAGE_NAME);
-        mVerifierController.notifyVerificationCancelled(TEST_PACKAGE_NAME);
-        mVerifierController.notifyVerificationTimeout(-1);
-        // Since there was no bound, no call is made to the verifier
-        verifyZeroInteractions(mMockService);
-    }
-
-    @Test
-    public void testUnbindService() throws Exception {
-        ArgumentCaptor<ServiceConnector.ServiceLifecycleCallbacks> captor = ArgumentCaptor.forClass(
-                ServiceConnector.ServiceLifecycleCallbacks.class);
-        assertThat(mVerifierController.bindToVerifierServiceIfNeeded(mSnapshotSupplier, 0))
-                .isTrue();
-        verify(mMockServiceConnector).setServiceLifecycleCallbacks(captor.capture());
-        ServiceConnector.ServiceLifecycleCallbacks<IVerifierService> callbacks = captor.getValue();
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        verify(mMockService, times(1)).onVerificationRequired(any(VerificationSession.class));
-        callbacks.onBinderDied();
-        // Test that nothing crashes if the service connection is lost
-        assertThat(mVerifierController.getVerifierPackageName(mSnapshotSupplier, 0)).isNotNull();
-        mVerifierController.notifyPackageNameAvailable(TEST_PACKAGE_NAME);
-        mVerifierController.notifyVerificationCancelled(TEST_PACKAGE_NAME);
-        mVerifierController.notifyVerificationTimeout(TEST_ID);
-        verifyNoMoreInteractions(mMockService);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ true)).isTrue();
-        mVerifierController.notifyVerificationTimeout(TEST_ID);
-        verify(mMockService, times(1)).onVerificationTimeout(eq(TEST_ID));
-    }
-
-    @Test
-    public void testNotifyPackageNameAvailable() throws Exception {
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        mVerifierController.notifyPackageNameAvailable(TEST_PACKAGE_NAME);
-        verify(mMockService).onPackageNameAvailable(eq(TEST_PACKAGE_NAME));
-    }
-
-    @Test
-    public void testNotifyVerificationCancelled() throws Exception {
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        mVerifierController.notifyVerificationCancelled(TEST_PACKAGE_NAME);
-        verify(mMockService).onVerificationCancelled(eq(TEST_PACKAGE_NAME));
-    }
-
-    @Test
-    public void testStartVerificationSession() throws Exception {
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        verify(mMockService).onVerificationRequired(captor.capture());
-        VerificationSession session = captor.getValue();
-        assertThat(session.getId()).isEqualTo(TEST_ID);
-        assertThat(session.getInstallSessionId()).isEqualTo(TEST_ID);
-        assertThat(session.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
-        assertThat(session.getStagedPackageUri()).isEqualTo(TEST_PACKAGE_URI);
-        assertThat(session.getSigningInfo().getSigningDetails())
-                .isEqualTo(TEST_SIGNING_INFO.getSigningDetails());
-        List<SharedLibraryInfo> declaredLibraries = session.getDeclaredLibraries();
-        // SharedLibraryInfo doesn't have a "equals" method, so we have to check it indirectly
-        assertThat(declaredLibraries.getFirst().toString())
-                .isEqualTo(TEST_SHARED_LIBRARY_INFO1.toString());
-        assertThat(declaredLibraries.get(1).toString())
-                .isEqualTo(TEST_SHARED_LIBRARY_INFO2.toString());
-        // We can't directly test with PersistableBundle.equals() because the parceled bundle's
-        // structure is different, but all the key/value pairs should be preserved as before.
-        assertThat(session.getExtensionParams().getString(TEST_KEY))
-                .isEqualTo(mTestExtensionParams.getString(TEST_KEY));
-    }
-
-    @Test
-    public void testNotifyVerificationRetry() throws Exception {
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ true)).isTrue();
-        verify(mMockService).onVerificationRetry(captor.capture());
-        VerificationSession session = captor.getValue();
-        assertThat(session.getId()).isEqualTo(TEST_ID);
-        assertThat(session.getInstallSessionId()).isEqualTo(TEST_ID);
-        assertThat(session.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
-        assertThat(session.getStagedPackageUri()).isEqualTo(TEST_PACKAGE_URI);
-        assertThat(session.getSigningInfo().getSigningDetails())
-                .isEqualTo(TEST_SIGNING_INFO.getSigningDetails());
-        List<SharedLibraryInfo> declaredLibraries = session.getDeclaredLibraries();
-        // SharedLibraryInfo doesn't have a "equals" method, so we have to check it indirectly
-        assertThat(declaredLibraries.getFirst().toString())
-                .isEqualTo(TEST_SHARED_LIBRARY_INFO1.toString());
-        assertThat(declaredLibraries.get(1).toString())
-                .isEqualTo(TEST_SHARED_LIBRARY_INFO2.toString());
-        // We can't directly test with PersistableBundle.equals() because the parceled bundle's
-        // structure is different, but all the key/value pairs should be preserved as before.
-        assertThat(session.getExtensionParams().getString(TEST_KEY))
-                .isEqualTo(mTestExtensionParams.getString(TEST_KEY));
-    }
-
-    @Test
-    public void testNotifyVerificationTimeout() throws Exception {
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ true)).isTrue();
-        mVerifierController.notifyVerificationTimeout(TEST_ID);
-        verify(mMockService).onVerificationTimeout(eq(TEST_ID));
-    }
-
-    @Test
-    public void testRequestTimeout() {
-        // Let the mock handler set request to TIMEOUT, immediately after the request is sent.
-        // We can't mock postDelayed because it's final, but we can mock the method it calls.
-        when(mHandler.sendMessageAtTime(any(Message.class), anyLong())).thenAnswer(
-                i -> {
-                    ((Message) i.getArguments()[0]).getCallback().run();
-                    return true;
-                });
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        verify(mHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
-        verify(mSessionCallback, times(1)).onTimeout();
-        verify(mInjector, times(2)).getCurrentTimeMillis();
-        verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
-    }
-
-    @Test
-    public void testRequestTimeoutWithRetryPass() throws Exception {
-        // Only let the first request timeout and let the second one pass
-        when(mHandler.sendMessageAtTime(any(Message.class), anyLong())).thenAnswer(
-                        i -> {
-                            ((Message) i.getArguments()[0]).getCallback().run();
-                            return true;
-                        })
-                .thenAnswer(i -> true);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        verify(mHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
-        verify(mSessionCallback, times(1)).onTimeout();
-        verify(mInjector, times(2)).getCurrentTimeMillis();
-        verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
-        // Then retry
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ true)).isTrue();
-        verify(mMockService).onVerificationRetry(captor.capture());
-        VerificationSession session = captor.getValue();
-        VerificationStatus status = new VerificationStatus.Builder().setVerified(true).build();
-        session.reportVerificationComplete(status);
-        verify(mSessionCallback, times(1)).onVerificationCompleteReceived(
-                eq(status), eq(null));
-        verify(mInjector, times(2)).stopTimeoutCountdown(eq(mHandler), any());
-    }
-
-    @Test
-    public void testRequestIncomplete() throws Exception {
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        verify(mMockService).onVerificationRequired(captor.capture());
-        VerificationSession session = captor.getValue();
-        session.reportVerificationIncomplete(VerificationSession.VERIFICATION_INCOMPLETE_UNKNOWN);
-        verify(mSessionCallback, times(1)).onVerificationIncompleteReceived(
-                eq(VerificationSession.VERIFICATION_INCOMPLETE_UNKNOWN));
-        verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
-    }
-
-    @Test
-    public void testRequestCompleteWithSuccessWithExtensionResponse() throws Exception {
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        verify(mMockService).onVerificationRequired(captor.capture());
-        VerificationSession session = captor.getValue();
-        VerificationStatus status = new VerificationStatus.Builder().setVerified(true).build();
-        PersistableBundle bundle = new PersistableBundle();
-        session.reportVerificationComplete(status, bundle);
-        verify(mSessionCallback, times(1)).onVerificationCompleteReceived(
-                eq(status), eq(bundle));
-        verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
-    }
-
-    @Test
-    public void testRequestCompleteWithFailure() throws Exception {
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        verify(mMockService).onVerificationRequired(captor.capture());
-        VerificationSession session = captor.getValue();
-        VerificationStatus status = new VerificationStatus.Builder()
-                .setVerified(false)
-                .setFailureMessage(TEST_FAILURE_MESSAGE)
-                .build();
-        session.reportVerificationComplete(status);
-        verify(mSessionCallback, times(1)).onVerificationCompleteReceived(
-                eq(status), eq(null));
-        verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
-    }
-
-    @Test
-    public void testRepeatedRequestCompleteShouldThrow() throws Exception {
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        assertThat(mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false)).isTrue();
-        verify(mMockService).onVerificationRequired(captor.capture());
-        VerificationSession session = captor.getValue();
-        VerificationStatus status = new VerificationStatus.Builder().setVerified(true).build();
-        session.reportVerificationComplete(status);
-        // getters should throw after the report
-        expectThrows(IllegalStateException.class, () -> session.getTimeoutTime());
-        // Report again should fail with exception
-        expectThrows(IllegalStateException.class, () -> session.reportVerificationComplete(status));
-    }
-
-    @Test
-    public void testExtendTimeRemaining() throws Exception {
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false);
-        verify(mMockService).onVerificationRequired(captor.capture());
-        VerificationSession session = captor.getValue();
-        final long initialTimeoutTime = TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS;
-        assertThat(session.getTimeoutTime()).isEqualTo(initialTimeoutTime);
-        final long extendTimeMillis = TEST_TIMEOUT_DURATION_MILLIS;
-        assertThat(session.extendTimeRemaining(extendTimeMillis)).isEqualTo(extendTimeMillis);
-        assertThat(session.getTimeoutTime()).isEqualTo(initialTimeoutTime + extendTimeMillis);
-    }
-
-    @Test
-    public void testExtendTimeExceedsMax() throws Exception {
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false);
-        verify(mMockService).onVerificationRequired(captor.capture());
-        VerificationSession session = captor.getValue();
-        final long initialTimeoutTime = TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS;
-        final long maxTimeoutTime = TEST_REQUEST_START_TIME + TEST_MAX_TIMEOUT_DURATION_MILLIS;
-        assertThat(session.getTimeoutTime()).isEqualTo(initialTimeoutTime);
-        final long extendTimeMillis = TEST_MAX_TIMEOUT_DURATION_MILLIS;
-        assertThat(session.extendTimeRemaining(extendTimeMillis)).isEqualTo(
-                TEST_MAX_TIMEOUT_DURATION_MILLIS - TEST_TIMEOUT_DURATION_MILLIS);
-        assertThat(session.getTimeoutTime()).isEqualTo(maxTimeoutTime);
-    }
-
-    @Test
-    public void testTimeoutChecksMultipleTimes() {
-        // Mock message handling
-        when(mHandler.sendMessageAtTime(any(Message.class), anyLong())).thenAnswer(
-                        i -> {
-                            ((Message) i.getArguments()[0]).getCallback().run();
-                            return true;
-                        });
-        // Mock time forward as the code continues to check for the current time
-        when(mInjector.getCurrentTimeMillis())
-                // First called when the tracker is created
-                .thenReturn(TEST_REQUEST_START_TIME)
-                // Then mock the first timeout check when the timeout time isn't reached yet
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 1000)
-                // Then mock the same time used to check the remaining time
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 1000)
-                // Then mock the second timeout check when the timeout time isn't reached yet
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 100)
-                // Then mock the same time used to check the remaining time
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 100)
-                // Then mock the third timeout check when the timeout time has been reached
-                .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS + 1);
-        mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false);
-        verify(mHandler, times(3)).sendMessageAtTime(any(Message.class), anyLong());
-        verify(mInjector, times(6)).getCurrentTimeMillis();
-        verify(mSessionCallback, times(1)).onTimeout();
-    }
-
-    @Test
-    public void testPolicyOverride() throws Exception {
-        ArgumentCaptor<VerificationSession> captor =
-                ArgumentCaptor.forClass(VerificationSession.class);
-        mVerifierController.startVerificationSession(
-                mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
-                TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
-                mSessionCallback, /* retry= */ false);
-        verify(mMockService).onVerificationRequired(captor.capture());
-        VerificationSession session = captor.getValue();
-        final int policy = VERIFICATION_POLICY_BLOCK_FAIL_OPEN;
-        when(mSessionCallback.setVerificationPolicy(eq(policy))).thenReturn(true);
-        assertThat(session.setVerificationPolicy(policy)).isTrue();
-        assertThat(session.getVerificationPolicy()).isEqualTo(policy);
-        verify(mSessionCallback, times(1)).setVerificationPolicy(eq(policy));
-    }
-}
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
index 3fdb53f..31f0370 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
@@ -289,6 +289,7 @@
         AndroidPackage::getEmergencyInstaller,
         AndroidPackage::isAllowCrossUidActivitySwitchFromBelow,
         AndroidPackage::getIntentMatchingFlags,
+        AndroidPackage::getPageSizeAppCompatFlags,
     )
 
     override fun extraParams() = listOf(
diff --git a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index 312df43..0e9dfed 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -1118,7 +1118,8 @@
     @Test
     public void testAutoBrightnessInDoze_useNormalBrightnessForDozeFalse_scaleScreenOn()
             throws Exception {
-        when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+        when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)).thenReturn(
+                true);
 
         ArgumentCaptor<SensorEventListener> listenerCaptor =
                 ArgumentCaptor.forClass(SensorEventListener.class);
@@ -1154,7 +1155,8 @@
     @Test
     public void testAutoBrightnessInDoze_useNormalBrightnessForDozeTrue_notScaleScreenOn()
             throws Exception {
-        when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+        when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)).thenReturn(
+                true);
 
         ArgumentCaptor<SensorEventListener> listenerCaptor =
                 ArgumentCaptor.forClass(SensorEventListener.class);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 759976f..47e96d3 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -17,6 +17,7 @@
 package com.android.server.display;
 
 import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY;
+import static android.Manifest.permission.ADD_MIRROR_DISPLAY;
 import static android.Manifest.permission.ADD_TRUSTED_DISPLAY;
 import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT;
 import static android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS;
@@ -122,6 +123,7 @@
 import android.os.SystemProperties;
 import android.os.UserManager;
 import android.os.test.FakePermissionEnforcer;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
@@ -1388,6 +1390,7 @@
      * Tests that it's not allowed to create an auto-mirror virtual display without
      * CAPTURE_VIDEO_OUTPUT permission or a virtual device that can mirror displays
      */
+    @EnableFlags(android.companion.virtualdevice.flags.Flags.FLAG_ENABLE_LIMITED_VDM_ROLE)
     @Test
     public void createAutoMirrorDisplay_withoutPermissionOrAllowedVirtualDevice_throwsException()
             throws Exception {
@@ -1397,7 +1400,8 @@
         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
         IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
         when(virtualDevice.getDeviceId()).thenReturn(1);
-        when(virtualDevice.canCreateMirrorDisplays()).thenReturn(false);
+        when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+                .thenReturn(PackageManager.PERMISSION_DENIED);
         when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
         when(mContext.checkCallingPermission(CAPTURE_VIDEO_OUTPUT)).thenReturn(
                 PackageManager.PERMISSION_DENIED);
@@ -1428,7 +1432,8 @@
         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
         IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
         when(virtualDevice.getDeviceId()).thenReturn(1);
-        when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true);
+        when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
         when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
 
         // Create an auto-mirror virtual display using a virtual device.
@@ -1461,7 +1466,8 @@
         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
         IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
         when(virtualDevice.getDeviceId()).thenReturn(1);
-        when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true);
+        when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
         when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
 
         // Create an auto-mirror virtual display using a virtual device.
@@ -1528,7 +1534,8 @@
         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
         IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
         when(virtualDevice.getDeviceId()).thenReturn(1);
-        when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true);
+        when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
         when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
         when(mContext.checkCallingPermission(ADD_ALWAYS_UNLOCKED_DISPLAY))
                 .thenReturn(PackageManager.PERMISSION_GRANTED);
@@ -1564,7 +1571,8 @@
         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
         IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
         when(virtualDevice.getDeviceId()).thenReturn(1);
-        when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true);
+        when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
         when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
 
         // Create an auto-mirror virtual display using a virtual device.
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index c996339..91f1aaf 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -2119,7 +2119,8 @@
     @Test
     public void testManualBrightness_stateOnPolicyDozeUseNormalBrightnessForDozeFalse_brightnessDoze() {
         when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
-        when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+        when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled(
+                mContext)).thenReturn(true);
         mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
         Settings.System.putInt(mContext.getContentResolver(),
                 Settings.System.SCREEN_BRIGHTNESS_MODE,
@@ -2154,7 +2155,8 @@
     @Test
     public void testManualBrightness_stateOnPolicyDozeUseNormalBrightnessForDozeTrue_brightnessNormal() {
         when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
-        when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+        when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled(
+                mContext)).thenReturn(true);
         mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
         Settings.System.putInt(mContext.getContentResolver(),
                 Settings.System.SCREEN_BRIGHTNESS_MODE,
@@ -2188,7 +2190,8 @@
     @Test
     public void testManualBrightness_stateDozePolicyOnUseNormalBrightnessForDozeTrue_brightnessDoze() {
         when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
-        when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+        when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled(
+                mContext)).thenReturn(true);
         mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
         Settings.System.putInt(mContext.getContentResolver(),
                 Settings.System.SCREEN_BRIGHTNESS_MODE,
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
index ff652a2..ad30f22 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -17,6 +17,7 @@
 package com.android.server.display;
 
 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
+import static android.hardware.devicestate.feature.flags.Flags.FLAG_DEVICE_STATE_PROPERTY_MIGRATION;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.DEFAULT_DISPLAY_GROUP;
 import static android.view.Display.FLAG_REAR;
@@ -77,6 +78,9 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.test.TestLooper;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.view.Display;
 import android.view.DisplayAddress;
 import android.view.DisplayInfo;
@@ -144,6 +148,9 @@
 
     @Rule
     public LocalServiceKeeperRule mLocalServiceKeeperRule = new LocalServiceKeeperRule();
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
 
     @Mock LogicalDisplayMapper.Listener mListenerMock;
     @Mock Context mContextMock;
@@ -691,6 +698,7 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(FLAG_DEVICE_STATE_PROPERTY_MIGRATION)
     public void testDeviceShouldNotBeWokenWhenExitingEmulatedState() {
         assertFalse(mLogicalDisplayMapper.shouldDeviceBeWoken(DEVICE_STATE_OPEN,
                 DEVICE_STATE_EMULATED,
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
index a647691..2ebb6c2a3 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
@@ -207,7 +207,8 @@
 
     @Test
     public void selectStrategyWhenValid_useNormalBrightnessForDozeTrue_doNotSelectsDozeStrategy() {
-        when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+        when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)).thenReturn(
+                true);
         DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
                 DisplayManagerInternal.DisplayPowerRequest.class);
         displayPowerRequest.policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
index 65f8ea7..4be96c2 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
@@ -31,6 +31,7 @@
 
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.res.Resources;
 import android.hardware.display.BrightnessConfiguration;
 import android.hardware.display.DisplayManagerInternal;
 import android.os.PowerManager;
@@ -76,6 +77,9 @@
     @Mock
     private DisplayManagerFlags mDisplayManagerFlags;
 
+    @Mock
+    private Resources mMockResources;
+
     private BrightnessConfiguration mBrightnessConfiguration;
     private float mDefaultScreenAutoBrightnessAdjustment;
     private Context mContext;
@@ -378,7 +382,8 @@
 
         reset(mAutomaticBrightnessController);
         when(mAutomaticBrightnessController.isInIdleMode()).thenReturn(false);
-        when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+        when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)).thenReturn(
+                true);
         policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
 
         // Validate interaction when automaticBrightnessController is in non-idle mode, display
diff --git a/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginManagerTest.kt b/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginManagerTest.kt
new file mode 100644
index 0000000..01061f1
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginManagerTest.kt
@@ -0,0 +1,97 @@
+/*
+ * 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.display.plugin
+
+import android.content.Context
+import androidx.test.filters.SmallTest
+import com.android.server.display.feature.DisplayManagerFlags
+import com.android.server.display.plugin.PluginManager.PluginChangeListener
+
+import org.junit.Test
+
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+private val TEST_PLUGIN_TYPE = PluginType(Int::class.java, "test_type")
+
+@SmallTest
+class PluginManagerTest {
+
+    private val mockContext = mock<Context>()
+    private val mockFlags = mock<DisplayManagerFlags>()
+    private val mockListener = mock<PluginChangeListener<Int>>()
+    private val testInjector = TestInjector()
+
+    @Test
+    fun testBootCompleted_enabledPluginManager() {
+        val pluginManager = createPluginManager()
+
+        pluginManager.onBootCompleted()
+
+        verify(testInjector.mockPlugin1).onBootCompleted()
+        verify(testInjector.mockPlugin2).onBootCompleted()
+    }
+
+    @Test
+    fun testBootCompleted_disabledPluginManager() {
+        val pluginManager = createPluginManager(false)
+
+        pluginManager.onBootCompleted()
+
+        verify(testInjector.mockPlugin1, never()).onBootCompleted()
+        verify(testInjector.mockPlugin2, never()).onBootCompleted()
+    }
+
+    @Test
+    fun testSubscribe() {
+        val pluginManager = createPluginManager()
+
+        pluginManager.subscribe(TEST_PLUGIN_TYPE, mockListener)
+
+        verify(testInjector.mockStorage).addListener(TEST_PLUGIN_TYPE, mockListener)
+    }
+
+    @Test
+    fun testUnsubscribe() {
+        val pluginManager = createPluginManager()
+
+        pluginManager.unsubscribe(TEST_PLUGIN_TYPE, mockListener)
+
+        verify(testInjector.mockStorage).removeListener(TEST_PLUGIN_TYPE, mockListener)
+    }
+
+    private fun createPluginManager(enabled: Boolean = true): PluginManager {
+        whenever(mockFlags.isPluginManagerEnabled).thenReturn(enabled)
+        return PluginManager(mockContext, mockFlags, testInjector)
+    }
+
+    private class TestInjector : PluginManager.Injector() {
+        val mockStorage = mock<PluginStorage>()
+        val mockPlugin1 = mock<Plugin>()
+        val mockPlugin2 = mock<Plugin>()
+
+        override fun getPluginStorage(): PluginStorage {
+            return mockStorage
+        }
+
+        override fun loadPlugins(context: Context?, storage: PluginStorage?): List<Plugin> {
+            return listOf(mockPlugin1, mockPlugin2)
+        }
+    }
+}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginStorageTest.kt b/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginStorageTest.kt
new file mode 100644
index 0000000..218e341
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginStorageTest.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.display.plugin
+
+import androidx.test.filters.SmallTest
+import com.android.server.display.plugin.PluginManager.PluginChangeListener
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+private val TEST_PLUGIN_TYPE1 = PluginType(String::class.java, "test_type1")
+private val TEST_PLUGIN_TYPE2 = PluginType(String::class.java, "test_type2")
+
+@SmallTest
+class PluginStorageTest {
+
+    val storage = PluginStorage()
+
+    @Test
+    fun testUpdateValue() {
+        val type1Value = "value1"
+        val testChangeListener = TestPluginChangeListener<String>()
+        storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener)
+
+        storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+
+        assertThat(testChangeListener.receivedValue).isEqualTo(type1Value)
+    }
+
+    @Test
+    fun testAddListener() {
+        val type1Value = "value1"
+        val testChangeListener = TestPluginChangeListener<String>()
+        storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+
+        storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener)
+
+        assertThat(testChangeListener.receivedValue).isEqualTo(type1Value)
+    }
+
+    @Test
+    fun testRemoveListener() {
+        val type1Value = "value1"
+        val testChangeListener = TestPluginChangeListener<String>()
+        storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener)
+        storage.removeListener(TEST_PLUGIN_TYPE1, testChangeListener)
+
+        storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+
+        assertThat(testChangeListener.receivedValue).isNull()
+    }
+
+    @Test
+    fun testAddListener_multipleValues() {
+        val type1Value = "value1"
+        val type2Value = "value2"
+        val testChangeListener = TestPluginChangeListener<String>()
+        storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+        storage.updateValue(TEST_PLUGIN_TYPE2, type2Value)
+
+        storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener)
+
+        assertThat(testChangeListener.receivedValue).isEqualTo(type1Value)
+    }
+
+    @Test
+    fun testUpdateValue_multipleListeners() {
+        val type1Value = "value1"
+        val testChangeListener1 = TestPluginChangeListener<String>()
+        val testChangeListener2 = TestPluginChangeListener<String>()
+        storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener1)
+        storage.addListener(TEST_PLUGIN_TYPE2, testChangeListener2)
+
+        storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+
+        assertThat(testChangeListener1.receivedValue).isEqualTo(type1Value)
+        assertThat(testChangeListener2.receivedValue).isNull()
+    }
+
+    private class TestPluginChangeListener<T> : PluginChangeListener<T> {
+        var receivedValue: T? = null
+
+        override fun onChanged(value: T?) {
+            receivedValue = value
+        }
+    }
+}
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 993569f..0d25426 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -392,3 +392,10 @@
     ],
     include_filters: ["com.android.server.StorageManagerServiceTest"],
 }
+
+test_module_config {
+    name: "FrameworksMockingServicesTests_service_batteryServiceTest",
+    base: "FrameworksMockingServicesTests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.server.BatteryServiceTest"],
+}
diff --git a/services/tests/mockingservicestests/jni/Android.bp b/services/tests/mockingservicestests/jni/Android.bp
index 00543a8..94d4b95 100644
--- a/services/tests/mockingservicestests/jni/Android.bp
+++ b/services/tests/mockingservicestests/jni/Android.bp
@@ -22,8 +22,8 @@
     srcs: [
         ":lib_cachedAppOptimizer_native",
         ":lib_freezer_native",
-        ":lib_gameManagerService_native",
         ":lib_oomConnection_native",
+        ":lib_lazilyRegisteredServices_native",
         "onload.cpp",
     ],
 
@@ -54,6 +54,8 @@
         "android.hardware.graphics.bufferqueue@2.0",
         "android.hardware.graphics.common@1.2",
         "android.hardware.graphics.mapper@4.0",
+        "android.hardware.ir@1.0",
+        "android.hardware.vr@1.0",
         "android.hidl.token@1.0-utils",
     ],
 }
diff --git a/services/tests/mockingservicestests/jni/onload.cpp b/services/tests/mockingservicestests/jni/onload.cpp
index cb246d1..9b4c817 100644
--- a/services/tests/mockingservicestests/jni/onload.cpp
+++ b/services/tests/mockingservicestests/jni/onload.cpp
@@ -26,8 +26,8 @@
 namespace android {
 int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
 int register_android_server_am_Freezer(JNIEnv* env);
-int register_android_server_app_GameManagerService(JNIEnv* env);
 int register_android_server_am_OomConnection(JNIEnv* env);
+int register_android_server_utils_LazyJniRegistrar(JNIEnv* env);
 };
 
 using namespace android;
@@ -44,7 +44,7 @@
     ALOG_ASSERT(env, "Could not retrieve the env!");
     register_android_server_am_CachedAppOptimizer(env);
     register_android_server_am_Freezer(env);
-    register_android_server_app_GameManagerService(env);
     register_android_server_am_OomConnection(env);
+    register_android_server_utils_LazyJniRegistrar(env);
     return JNI_VERSION_1_4;
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/BatteryServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/BatteryServiceTest.java
index 5e2f80b..1fbd53a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/BatteryServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/BatteryServiceTest.java
@@ -79,6 +79,8 @@
     private static final int UPDATED_BATTERY_HEALTH = 3;
     private static final int CURRENT_CHARGE_COUNTER = 4680000;
     private static final int UPDATED_CHARGE_COUNTER = 4218000;
+    private static final int CURRENT_MAX_CHARGING_CURRENT = 298125;
+    private static final int UPDATED_MAX_CHARGING_CURRENT = 398125;
     private static final int HANDLER_IDLE_TIME_MS = 5000;
     @Rule
     public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
@@ -143,7 +145,7 @@
     @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
     public void onlyVoltageUpdated_lessThenOnePercent_broadcastNotSent() {
         mBatteryService.update(createHealthInfo(VOLTAGE_LESS_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
-                CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+                CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH, CURRENT_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
@@ -156,7 +158,8 @@
         mBatteryService.update(
                 createHealthInfo(VOLTAGE_MORE_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
                         CURRENT_CHARGE_COUNTER,
-                        CURRENT_BATTERY_HEALTH));
+                        CURRENT_BATTERY_HEALTH,
+                        CURRENT_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
@@ -165,13 +168,17 @@
 
     @Test
     @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
-    public void onlyVoltageUpdated_broadcastSent() {
+    public void voltageUpdated_withUpdateInChargingCurrent_broadcastSent() {
         mBatteryService.mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime() - 20000;
+        long lastChargingCurrentUpdateTime =
+                mBatteryService.mLastBroadcastMaxChargingCurrentUpdateTime;
         mBatteryService.update(createHealthInfo(VOLTAGE_MORE_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
-                CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+                CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH, UPDATED_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
+        assertTrue(lastChargingCurrentUpdateTime
+                < mBatteryService.mLastBroadcastMaxChargingCurrentUpdateTime);
         verifyNumberOfTimesBroadcastSent(1);
     }
 
@@ -180,7 +187,8 @@
     public void onlyTempUpdated_lessThenOneDegreeCelsius_broadcastNotSent() {
         mBatteryService.update(
                 createHealthInfo(CURRENT_BATTERY_VOLTAGE, TEMP_LESS_THEN_ONE_DEGREE_CELSIUS,
-                        CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+                        CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH,
+                        CURRENT_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
@@ -191,23 +199,31 @@
     @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
     public void tempUpdated_broadcastSent() {
         long lastVoltageUpdateTime = mBatteryService.mLastBroadcastVoltageUpdateTime;
+        long lastChargingCurrentUpdateTime =
+                mBatteryService.mLastBroadcastMaxChargingCurrentUpdateTime;
         mBatteryService.update(
                 createHealthInfo(VOLTAGE_LESS_THEN_ONE_PERCENT, TEMP_MORE_THEN_ONE_DEGREE_CELSIUS,
-                        UPDATED_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+                        UPDATED_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH,
+                        UPDATED_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
         assertTrue(lastVoltageUpdateTime < mBatteryService.mLastBroadcastVoltageUpdateTime);
+        assertTrue(lastChargingCurrentUpdateTime
+                < mBatteryService.mLastBroadcastMaxChargingCurrentUpdateTime);
         verifyNumberOfTimesBroadcastSent(1);
     }
 
     @Test
     @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
-    public void batteryHealthUpdated_voltageAndTempConst_broadcastSent() {
+    public void batteryHealthUpdated_withOtherExtrasConstant_broadcastSent() {
+        long lastVoltageUpdateTime = mBatteryService.mLastBroadcastVoltageUpdateTime;
+        long lastChargingCurrentUpdateTime =
+                mBatteryService.mLastBroadcastMaxChargingCurrentUpdateTime;
         mBatteryService.update(
-                createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
+                createHealthInfo(VOLTAGE_LESS_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
                         CURRENT_CHARGE_COUNTER,
-                        UPDATED_BATTERY_HEALTH));
+                        UPDATED_BATTERY_HEALTH, UPDATED_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
@@ -217,10 +233,13 @@
         mBatteryService.update(
                 createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
                         UPDATED_CHARGE_COUNTER,
-                        UPDATED_BATTERY_HEALTH));
+                        UPDATED_BATTERY_HEALTH, CURRENT_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
+        assertTrue(lastVoltageUpdateTime < mBatteryService.mLastBroadcastVoltageUpdateTime);
+        assertTrue(lastChargingCurrentUpdateTime
+                < mBatteryService.mLastBroadcastMaxChargingCurrentUpdateTime);
         verifyNumberOfTimesBroadcastSent(1);
     }
 
@@ -228,7 +247,7 @@
     @DisableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
     public void voltageUpdated_lessThanOnePercent_flagDisabled_broadcastSent() {
         mBatteryService.update(createHealthInfo(VOLTAGE_LESS_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
-                CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+                CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH, CURRENT_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
@@ -241,7 +260,7 @@
         mBatteryService.update(
                 createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
                         UPDATED_CHARGE_COUNTER,
-                        CURRENT_BATTERY_HEALTH));
+                        CURRENT_BATTERY_HEALTH, CURRENT_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
@@ -254,7 +273,7 @@
         mBatteryService.update(
                 createHealthInfo(CURRENT_BATTERY_VOLTAGE, TEMP_LESS_THEN_ONE_DEGREE_CELSIUS,
                         UPDATED_CHARGE_COUNTER,
-                        CURRENT_BATTERY_HEALTH));
+                        CURRENT_BATTERY_HEALTH, CURRENT_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
@@ -267,18 +286,51 @@
         mBatteryService.update(
                 createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
                         UPDATED_CHARGE_COUNTER,
-                        CURRENT_BATTERY_HEALTH));
+                        CURRENT_BATTERY_HEALTH, CURRENT_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
 
         verifyNumberOfTimesBroadcastSent(1);
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+    public void onlyMaxChargingCurrentUpdated_beforeFiveSeconds_broadcastNotSent() {
+        mBatteryService.update(
+                createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
+                        CURRENT_CHARGE_COUNTER,
+                        CURRENT_BATTERY_HEALTH,
+                        UPDATED_MAX_CHARGING_CURRENT));
+
+        waitForHandlerToExecute();
+
+        verifyNumberOfTimesBroadcastSent(0);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+    public void maxChargingCurrentUpdated_afterFiveSeconds_broadcastSent() {
+        mBatteryService.mLastBroadcastMaxChargingCurrentUpdateTime =
+                SystemClock.elapsedRealtime() - 5000;
+        long lastVoltageUpdateTime = mBatteryService.mLastBroadcastVoltageUpdateTime;
+        mBatteryService.update(
+                createHealthInfo(VOLTAGE_MORE_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
+                        CURRENT_CHARGE_COUNTER,
+                        CURRENT_BATTERY_HEALTH,
+                        UPDATED_MAX_CHARGING_CURRENT));
+
+        waitForHandlerToExecute();
+
+        assertTrue(lastVoltageUpdateTime < mBatteryService.mLastBroadcastVoltageUpdateTime);
+        verifyNumberOfTimesBroadcastSent(1);
+    }
+
     private HealthInfo createHealthInfo(
             int batteryVoltage,
             int batteryTemperature,
             int batteryChargeCounter,
-            int batteryHealth) {
+            int batteryHealth,
+            int maxChargingCurrent) {
         HealthInfo h = new HealthInfo();
         h.batteryVoltageMillivolts = batteryVoltage;
         h.batteryTemperatureTenthsCelsius = batteryTemperature;
@@ -287,7 +339,7 @@
         h.batteryHealth = batteryHealth;
         h.batteryPresent = true;
         h.batteryLevel = 100;
-        h.maxChargingCurrentMicroamps = 298125;
+        h.maxChargingCurrentMicroamps = maxChargingCurrent;
         h.batteryCurrentAverageMicroamps = -2812;
         h.batteryCurrentMicroamps = 298125;
         h.maxChargingVoltageMicrovolts = 3000;
@@ -308,7 +360,8 @@
         mBatteryService.update(
                 createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
                         CURRENT_CHARGE_COUNTER,
-                        CURRENT_BATTERY_HEALTH));
+                        CURRENT_BATTERY_HEALTH,
+                        CURRENT_MAX_CHARGING_CURRENT));
 
         waitForHandlerToExecute();
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 5a872ea..ace6aae 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -283,9 +283,9 @@
         // Required for updating DeviceConfig.
         InstrumentationRegistry.getInstrumentation()
                 .getUiAutomation()
-                .adoptShellPermissionIdentity(
-                Manifest.permission.READ_DEVICE_CONFIG,
-                Manifest.permission.WRITE_DEVICE_CONFIG);
+                .adoptShellPermissionIdentity(Manifest.permission.READ_DEVICE_CONFIG,
+                        Manifest.permission.WRITE_DEVICE_CONFIG,
+                        Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
         sProcessListSettingsListener = mAms.mProcessList.getProcessListSettingsListener();
         assertThat(sProcessListSettingsListener).isNotNull();
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index a9569b4..1efe470 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -105,6 +105,7 @@
 import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.util.ArrayMap;
@@ -3260,6 +3261,24 @@
                 "cch-empty");
     }
 
+    @SuppressWarnings("GuardedBy")
+    @Test
+    @EnableFlags(Flags.FLAG_FIX_APPLY_OOMADJ_ORDER)
+    public void testUpdateOomAdj_ApplyOomAdjInCorrectOrder() {
+        final int numberOfApps = 5;
+        final ProcessRecord[] apps = new ProcessRecord[numberOfApps];
+        for (int i = 0; i < numberOfApps; i++) {
+            apps[i] = spy(makeDefaultProcessRecord(MOCKAPP_PID + i, MOCKAPP_UID + i,
+                    MOCKAPP_PROCESSNAME + i, MOCKAPP_PACKAGENAME + i, true));
+        }
+        updateOomAdj(apps);
+        for (int i = 1; i < numberOfApps; i++) {
+            final int pre = mInjector.mSetOomAdjAppliedAt.get(apps[i - 1].mPid);
+            final int cur = mInjector.mSetOomAdjAppliedAt.get(apps[i].mPid);
+            assertTrue("setOomAdj is called in wrong order", pre < cur);
+        }
+    }
+
     private ProcessRecord makeDefaultProcessRecord(int pid, int uid, String processName,
             String packageName, boolean hasShownUi) {
         return new ProcessRecordBuilder(pid, uid, processName, packageName).setHasShownUi(
@@ -3589,9 +3608,16 @@
         long mTimeOffsetMillis = 0;
         private SparseIntArray mLastSetOomAdj = new SparseIntArray();
 
+        // A sequence number that increases every time setOomAdj is called
+        int mLastAppliedAt = 0;
+        // Holds the last sequence number setOomAdj is called for a pid
+        private SparseIntArray mSetOomAdjAppliedAt = new SparseIntArray();
+
         void reset() {
             mTimeOffsetMillis = 0;
             mLastSetOomAdj.clear();
+            mLastAppliedAt = 0;
+            mSetOomAdjAppliedAt.clear();
         }
 
         void jumpUptimeAheadTo(long uptimeMillis) {
@@ -3616,6 +3642,7 @@
                 final int pid = proc.getPid();
                 if (pid <= 0) continue;
                 mLastSetOomAdj.put(pid, proc.mState.getCurAdj());
+                mSetOomAdjAppliedAt.put(pid, mLastAppliedAt++);
             }
         }
 
@@ -3623,6 +3650,7 @@
         void setOomAdj(int pid, int uid, int adj) {
             if (pid <= 0) return;
             mLastSetOomAdj.put(pid, adj);
+            mSetOomAdjAppliedAt.put(pid, mLastAppliedAt++);
         }
 
         @Override
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java b/services/tests/mockingservicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java
index c77ab0f..7454248 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/SettingsToPropertiesMapperTest.java
@@ -21,10 +21,14 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 
+import static org.mockito.Mockito.verify;
+
 import android.content.ContentResolver;
 import android.os.SystemProperties;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 
@@ -34,6 +38,7 @@
 import org.junit.Test;
 import org.mockito.Answers;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoSession;
 import org.mockito.quality.Strictness;
 import org.mockito.stubbing.Answer;
@@ -111,6 +116,20 @@
     }
 
     @Test
+    public void testClearAconfigStorageOverride() {
+        SettingsToPropertiesMapper spyMapper = Mockito.spy(new SettingsToPropertiesMapper(
+                mMockContentResolver, TEST_MAPPING, new String[] {}, new String[] {}));
+        HashMap flags = new HashMap();
+        flags.put("test_package.test_flag", null);
+        DeviceConfig.Properties props = new DeviceConfig.Properties("test_namespace", flags);
+
+        spyMapper.setLocalOverridesInNewStorage(props);
+
+        verify(spyMapper).writeFlagOverrideRemovalRequest(new ProtoOutputStream(),
+                "test_package", "test_flag", true);
+    }
+
+    @Test
     public void validateRegisteredGlobalSettings() {
         HashSet<String> hashSet = new HashSet<>();
         for (String globalSetting : SettingsToPropertiesMapper.sGlobalSettings) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java
index 19e43b6..2461e9e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java
@@ -196,6 +196,31 @@
     }
 
     @Test
+    public void bindToAgentSynchronous_unexpectedAgentConnected_doesNotReturnWrongAgent()
+            throws Exception {
+        when(mActivityManager.bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(),
+                anyInt(), anyBoolean())).thenReturn(true);
+        // This is so that IBackupAgent.Stub.asInterface() works.
+        when(mBackupAgentStub.queryLocalInterface(any())).thenReturn(mBackupAgentStub);
+        when(mConnectionManager.getCallingUid()).thenReturn(Process.SYSTEM_UID);
+
+        // This is going to block until it receives the callback so we need to run it on a
+        // separate thread.
+        Thread testThread = new Thread(() -> setBackupAgentResult(
+                mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+                        ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD)),
+                "backup-agent-connection-manager-test");
+        testThread.start();
+        // Give the testThread a head start, otherwise agentConnected() might run before
+        // bindToAgentSynchronous() is called.
+        Thread.sleep(500);
+        mConnectionManager.agentConnected("com.other.package", mBackupAgentStub);
+        testThread.join(100); // Avoid waiting the full timeout.
+
+        assertThat(mBackupAgentResult).isNull();
+    }
+
+    @Test
     @DisableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
     public void bindToAgentSynchronous_restrictedModeChangesFlagOff_shouldUseRestrictedMode()
             throws Exception {
@@ -345,6 +370,7 @@
 
     @Test
     public void agentDisconnected_cancelsCurrentOperations() throws Exception {
+        when(mConnectionManager.getCallingUid()).thenReturn(Process.SYSTEM_UID);
         when(mOperationStorage.operationTokensForPackage(eq(TEST_PACKAGE))).thenReturn(
                 ImmutableSet.of(123, 456, 789));
         when(mConnectionManager.getThreadForCancellation(any())).thenAnswer(invocation -> {
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index dd7ce21..c831475 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.job;
 
+import static android.app.job.Flags.FLAG_HANDLE_ABANDONED_JOBS;
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -82,6 +83,7 @@
 import android.os.SystemClock;
 import android.os.WorkSource;
 import android.os.WorkSource.WorkChain;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.RequiresFlagsDisabled;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
@@ -1056,6 +1058,75 @@
     /**
      * Confirm that
      * {@link JobSchedulerService#getRescheduleJobForFailureLocked(JobStatus, int, int)}
+     * returns a job with the correct delay for abandoned jobs.
+     */
+    @Test
+    @EnableFlags(FLAG_HANDLE_ABANDONED_JOBS)
+    public void testGetRescheduleJobForFailure_abandonedJob() {
+        final long nowElapsed = sElapsedRealtimeClock.millis();
+        final long initialBackoffMs = MINUTE_IN_MILLIS;
+        mService.mConstants.SYSTEM_STOP_TO_FAILURE_RATIO = 3;
+
+        JobStatus originalJob = createJobStatus("testGetRescheduleJobForFailure",
+                createJobInfo()
+                        .setBackoffCriteria(initialBackoffMs, JobInfo.BACKOFF_POLICY_LINEAR));
+        assertEquals(JobStatus.NO_EARLIEST_RUNTIME, originalJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_LATEST_RUNTIME, originalJob.getLatestRunTimeElapsed());
+
+        // failure = 1, systemStop = 0, abandoned = 1
+        JobStatus rescheduledJob = mService.getRescheduleJobForFailureLocked(originalJob,
+                JobParameters.STOP_REASON_DEVICE_STATE,
+                JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED);
+        assertEquals(nowElapsed + initialBackoffMs, rescheduledJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
+
+        // failure = 2, systemstop = 0, abandoned = 2
+        rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob,
+                JobParameters.STOP_REASON_DEVICE_STATE,
+                JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED);
+        assertEquals(nowElapsed + (2 * initialBackoffMs), rescheduledJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
+
+        // failure = 3, systemstop = 0, abandoned = 3
+        rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob,
+                JobParameters.STOP_REASON_DEVICE_STATE,
+                JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED);
+        assertEquals(nowElapsed + (3 * initialBackoffMs), rescheduledJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
+
+        // failure = 4, systemstop = 0, abandoned = 4
+        rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob,
+                JobParameters.STOP_REASON_DEVICE_STATE,
+                JobParameters.INTERNAL_STOP_REASON_TIMEOUT_ABANDONED);
+        assertEquals(
+                nowElapsed + ((long) Math.scalb((float) initialBackoffMs, 3)),
+                rescheduledJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
+
+        // failure = 4, systemstop = 1, abandoned = 4
+        rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob,
+                JobParameters.STOP_REASON_DEVICE_STATE,
+                JobParameters.INTERNAL_STOP_REASON_DEVICE_THERMAL);
+        assertEquals(
+                nowElapsed + ((long) Math.scalb((float) initialBackoffMs, 3)),
+                rescheduledJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
+
+        // failure = 4, systemStop =  4  / SYSTEM_STOP_TO_FAILURE_RATIO, abandoned = 4
+        for (int i = 0; i < mService.mConstants.SYSTEM_STOP_TO_FAILURE_RATIO; ++i) {
+            rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob,
+                    JobParameters.STOP_REASON_SYSTEM_PROCESSING,
+                    JobParameters.INTERNAL_STOP_REASON_RTC_UPDATED);
+        }
+        assertEquals(
+                nowElapsed + ((long) Math.scalb((float) initialBackoffMs, 4)),
+                rescheduledJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
+    }
+
+    /**
+     * Confirm that
+     * {@link JobSchedulerService#getRescheduleJobForFailureLocked(JobStatus, int, int)}
      * returns a job that is correctly marked as demoted by the user.
      */
     @Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
index c6a6865..c64973a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
@@ -706,14 +706,14 @@
                 // "True" start is nowElapsed + HOUR_IN_MILLIS
                 nowElapsed + HOUR_IN_MILLIS + adjustmentMs,
                 nowElapsed + 2 * HOUR_IN_MILLIS,
-                0 /* numFailures */, 0 /* numSystemStops */,
+                0 /* numFailures */, 0 /* numAbandonedFailures */, 0 /* numSystemStops */,
                 JobSchedulerService.sSystemClock.millis() /* lastSuccessfulRunTime */,
                 0, 0);
         jsFlex = new JobStatus(jsFlex,
                 // "True" start is nowElapsed + 2 * HOUR_IN_MILLIS - 20 * MINUTE_IN_MILLIS
                 nowElapsed + 2 * HOUR_IN_MILLIS - 20 * MINUTE_IN_MILLIS + adjustmentMs,
                 nowElapsed + 2 * HOUR_IN_MILLIS,
-                0 /* numFailures */, 0 /* numSystemStops */,
+                0 /* numFailures */, 0 /* numAbandonedFailures */, 0 /* numSystemStops */,
                 JobSchedulerService.sSystemClock.millis() /* lastSuccessfulRunTime */,
                 0, 0);
 
@@ -726,13 +726,13 @@
         jsBasic = new JobStatus(jsBasic,
                 nowElapsed + 30 * MINUTE_IN_MILLIS,
                 NO_LATEST_RUNTIME,
-                1 /* numFailures */, 1 /* numSystemStops */,
+                1 /* numFailures */, 0 /* numAbandonedFailures */, 1 /* numSystemStops */,
                 JobSchedulerService.sSystemClock.millis() /* lastSuccessfulRunTime */,
                 0, 0);
         jsFlex = new JobStatus(jsFlex,
                 nowElapsed + 30 * MINUTE_IN_MILLIS,
                 NO_LATEST_RUNTIME,
-                1 /* numFailures */, 1 /* numSystemStops */,
+                1 /* numFailures */, 0 /* numAbandonedFailures */, 1 /* numSystemStops */,
                 JobSchedulerService.sSystemClock.millis() /* lastSuccessfulRunTime */,
                 0, 0);
 
@@ -847,21 +847,24 @@
         JobInfo.Builder jb = createJob(0).setOverrideDeadline(HOUR_IN_MILLIS);
         JobStatus js = createJobStatus("time", jb);
         js = new JobStatus(
-                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 2, /* numSystemStops */ 0,
+                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 2,
+                0 /* numAbandonedFailures */, /* numSystemStops */ 0,
                 0, FROZEN_TIME, FROZEN_TIME);
 
         assertEquals(mFcConfig.RESCHEDULED_JOB_DEADLINE_MS,
                 mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, 0));
 
         js = new JobStatus(
-                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 2, /* numSystemStops */ 1,
+                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 2,
+                0 /* numAbandonedFailures */, /* numSystemStops */ 1,
                 0, FROZEN_TIME, FROZEN_TIME);
 
         assertEquals(2 * mFcConfig.RESCHEDULED_JOB_DEADLINE_MS,
                 mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, 0));
 
         js = new JobStatus(
-                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 0, /* numSystemStops */ 10,
+                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 0,
+                0 /* numAbandonedFailures */, /* numSystemStops */ 10,
                 0, FROZEN_TIME, FROZEN_TIME);
         assertEquals(mFcConfig.MAX_RESCHEDULED_DEADLINE_MS,
                 mFlexibilityController.getLifeCycleEndElapsedLocked(js, nowElapsed, 0));
@@ -1092,11 +1095,13 @@
         JobInfo.Builder jb = createJob(0);
         JobStatus js = createJobStatus("time", jb);
         js = new JobStatus(
-                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 1, /* numSystemStops */ 0,
+                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 1,
+                /* numAbandonedFailures */ 0, /* numSystemStops */ 0,
                 0, FROZEN_TIME, FROZEN_TIME);
         assertFalse(js.hasFlexibilityConstraint());
         js = new JobStatus(
-                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 0, /* numSystemStops */ 1,
+                js, FROZEN_TIME, NO_LATEST_RUNTIME, /* numFailures */ 0,
+                /* numAbandonedFailures */ 0, /* numSystemStops */ 1,
                 0, FROZEN_TIME, FROZEN_TIME);
         assertFalse(js.hasFlexibilityConstraint());
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
index 2d0f4b6..86101cf 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
@@ -459,35 +459,35 @@
         int numFailures = 1;
         int numSystemStops = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority());
 
         // 2+ failures, priority should be lowered as much as possible.
         numFailures = 2;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority());
         numFailures = 5;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority());
         numFailures = 8;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority());
 
         // System stops shouldn't factor in the downgrade.
         numSystemStops = 10;
         numFailures = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority());
 
         // Less than 2 failures, but job is downgraded.
         numFailures = 1;
         numSystemStops = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER);
         assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority());
     }
@@ -505,44 +505,44 @@
         int numFailures = 1;
         int numSystemStops = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority());
 
         // Failures in [2,4), priority should be lowered slightly.
         numFailures = 2;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_DEFAULT, job.getEffectivePriority());
         numFailures = 3;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_DEFAULT, job.getEffectivePriority());
 
         // Failures in [4,6), priority should be lowered more.
         numFailures = 4;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority());
         numFailures = 5;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority());
 
         // 6+ failures, priority should be lowered as much as possible.
         numFailures = 6;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority());
         numFailures = 12;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority());
 
         // System stops shouldn't factor in the downgrade.
         numSystemStops = 10;
         numFailures = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority());
     }
 
@@ -563,32 +563,32 @@
         int numFailures = 1;
         int numSystemStops = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority());
         numFailures = 4;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority());
         numFailures = 5;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority());
 
         // 6+ failures, priority should be lowered as much as possible.
         numFailures = 6;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority());
         numFailures = 12;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority());
 
         // System stops shouldn't factor in the downgrade.
         numSystemStops = 10;
         numFailures = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority());
     }
 
@@ -606,28 +606,28 @@
         int numFailures = 1;
         int numSystemStops = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority());
 
         // 2+ failures, priority shouldn't be affected while job is still a UI job
         numFailures = 2;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority());
         numFailures = 5;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority());
         numFailures = 8;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority());
 
         // System stops shouldn't factor in the downgrade.
         numSystemStops = 10;
         numFailures = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MAX, job.getEffectivePriority());
 
         // Job can no long run as user-initiated. Downgrades should be effective.
@@ -641,28 +641,28 @@
         numFailures = 1;
         numSystemStops = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority());
 
         // 2+ failures, priority should start getting lower
         numFailures = 2;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_DEFAULT, job.getEffectivePriority());
         numFailures = 5;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_LOW, job.getEffectivePriority());
         numFailures = 8;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_MIN, job.getEffectivePriority());
 
         // System stops shouldn't factor in the downgrade.
         numSystemStops = 10;
         numFailures = 0;
         job = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME, numFailures,
-                numSystemStops, 0, 0, 0);
+                0, numSystemStops, 0, 0, 0);
         assertEquals(JobInfo.PRIORITY_HIGH, job.getEffectivePriority());
     }
 
@@ -772,14 +772,14 @@
         assertTrue(job.shouldTreatAsUserInitiatedJob());
 
         JobStatus rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME,
-                0, 0, 0, 0, 0);
+                0, 0, 0, 0, 0, 0);
         assertTrue(rescheduledJob.shouldTreatAsUserInitiatedJob());
 
         job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER);
         assertFalse(job.shouldTreatAsUserInitiatedJob());
 
         rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME,
-                0, 0, 0, 0, 0);
+                0, 0, 0, 0, 0, 0);
         assertFalse(rescheduledJob.shouldTreatAsUserInitiatedJob());
 
         rescheduledJob.removeInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER);
@@ -797,14 +797,14 @@
         assertTrue(job.shouldTreatAsUserInitiatedJob());
 
         JobStatus rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME,
-                0, 0, 0, 0, 0);
+                0, 0, 0, 0, 0, 0);
         assertTrue(rescheduledJob.shouldTreatAsUserInitiatedJob());
 
         job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ);
         assertFalse(job.shouldTreatAsUserInitiatedJob());
 
         rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME,
-                0, 0, 0, 0, 0);
+                0, 0, 0, 0, 0, 0);
         assertFalse(rescheduledJob.shouldTreatAsUserInitiatedJob());
 
         rescheduledJob.removeInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ);
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/geometry/S2CellIdUtilsTest.java b/services/tests/mockingservicestests/src/com/android/server/location/geometry/S2CellIdUtilsTest.java
new file mode 100644
index 0000000..9e43b81
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/location/geometry/S2CellIdUtilsTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.location.geometry;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.location.geometry.S2CellIdUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class S2CellIdUtilsTest {
+
+    // S2 cell ID of a level-30 cell in Times Square.
+    private static final long TIMES_SQUARE_S2_ID =
+            S2CellIdUtils.fromLatLngDegrees(40.758896, -73.985130);
+
+    // Position of the Eiffel tower (outside of any parent cell from Times Square).
+    private static final double[] EIFFEL_TOWER_LATLNG = {48.858093, 2.294694};
+
+    // Test vector around TIMES_SQUARE_S2_ID: Cell IDs and the centers for levels 0 to 30.
+    // This test vector has been computed using the public S2 library in
+    // external/s2-geometry-library-java
+    private static final CellAndCenter[] TIMES_SQUARE_CELLS = {
+            new CellAndCenter("9", -0.0, -90.0),
+            new CellAndCenter("8c", 21.037511025421814, -67.38013505195958),
+            new CellAndCenter("89", 34.04786296943431, -79.38034472384487),
+            new CellAndCenter("89c", 38.79459515585768, -73.46516214265485),
+            new CellAndCenter("89d", 41.74704688465104, -76.45630866778862),
+            new CellAndCenter("89c4", 40.29416073145462, -74.96763653470293),
+            new CellAndCenter("89c3", 40.827706513259564, -74.21793256064282),
+            new CellAndCenter("89c24", 40.45771021423038, -73.84190634077625),
+            new CellAndCenter("89c25", 40.64307662867646, -74.03001224983848),
+            new CellAndCenter("89c25c", 40.708880489804564, -73.93598211433742),
+            new CellAndCenter("89c259", 40.75509755935301, -73.9830029344863),
+            new CellAndCenter("89c2584", 40.7781887758716, -74.00650903621303),
+            new CellAndCenter("89c2585", 40.766644611813284, -73.99475634561863),
+            new CellAndCenter("89c25854", 40.76087144655763, -73.98887973002674),
+            new CellAndCenter("89c25855", 40.75798459318946, -73.98594135473846),
+            new CellAndCenter("89c25855c", 40.75901097797799, -73.98447215023141),
+            new CellAndCenter("89c25855b", 40.758497791893824, -73.98520675388987),
+            new CellAndCenter("89c25855bc", 40.75875438651343, -73.98483945241185),
+            new CellAndCenter("89c25855b9", 40.758934819692875, -73.98502310323867),
+            new CellAndCenter("89c25855b9c", 40.75887067137071, -73.98511492858621),
+            new CellAndCenter("89c25855b9d", 40.75891577956465, -73.98516084124353),
+            new CellAndCenter("89c25855b9c4", 40.758893225473194, -73.98513788491626),
+            new CellAndCenter("89c25855b9c7", 40.75890124402366, -73.98512640675159),
+            new CellAndCenter("89c25855b9c6c", 40.758897234748815, -73.985132145834),
+            new CellAndCenter("89c25855b9c6d", 40.75889441548664, -73.98512927629281),
+            new CellAndCenter("89c25855b9c6c4", 40.75889582511775, -73.98513071106342),
+            new CellAndCenter("89c25855b9c6c3", 40.758896326277146, -73.98512999367811),
+            new CellAndCenter("89c25855b9c6c3c", 40.75889607569745, -73.98513035237076),
+            new CellAndCenter("89c25855b9c6c39", 40.75889589949357, -73.98513017302443),
+            new CellAndCenter("89c25855b9c6c39c", 40.75889596213849, -73.98513008335128),
+            new CellAndCenter("89c25855b9c6c39f", 40.75889599346095, -73.9851300385147)};
+
+    @Test
+    public void toLatLngDegrees_matchesTestVector() {
+        for (int level = 0; level <= 30; level++) {
+            double[] expected = TIMES_SQUARE_CELLS[level].mCenter;
+            long cellId = S2CellIdUtils.getParent(TIMES_SQUARE_S2_ID, level);
+
+            double[] centerPoint = {0.0, 0.0};
+            S2CellIdUtils.toLatLngDegrees(cellId, centerPoint);
+
+            assertThat(approxEquals(centerPoint[0], expected[0])).isTrue();
+            assertThat(approxEquals(centerPoint[1], expected[1])).isTrue();
+        }
+    }
+
+    private static boolean approxEquals(double a, double b) {
+        return Math.abs(a - b) <= 1e-14;
+    }
+
+    @Test
+    public void containsLatLngDegrees_eachCellContainsItsCenter_works() {
+        for (int level = 0; level <= 30; level++) {
+            long cellId = TIMES_SQUARE_CELLS[level].toCellId();
+            double[] center = TIMES_SQUARE_CELLS[level].mCenter;
+
+            boolean isContained = S2CellIdUtils.containsLatLngDegrees(cellId, center[0], center[1]);
+
+            assertThat(isContained).isTrue();
+        }
+    }
+
+    @Test
+    public void containsLatLngDegrees_testWithOutsidePoint() {
+        for (int level = 0; level <= 30; level++) {
+            long cellId = TIMES_SQUARE_CELLS[level].toCellId();
+
+            assertThat(S2CellIdUtils.containsLatLngDegrees(cellId, EIFFEL_TOWER_LATLNG[0],
+                  EIFFEL_TOWER_LATLNG[1])).isFalse();
+        }
+    }
+
+    // A tuple with a S2 cell id, and a S2LatLng representing its center.
+    private static class CellAndCenter {
+        public String mToken;
+        public double[] mCenter;
+
+        CellAndCenter(String token, double latDegrees, double lngDegrees) {
+            this.mToken = token;
+            this.mCenter = new double[] {latDegrees, lngDegrees};
+        }
+
+        // Converts from hex representation to long format.
+        long toCellId() {
+            long value = 0;
+            for (int pos = 0; pos < mToken.length(); pos++) {
+                int digitValue = Character.digit(mToken.charAt(pos), 16);
+                if (digitValue == -1) {
+                    return -1;
+                }
+                value = value * 16 + digitValue;
+            }
+            value = value << (4 * (16 - mToken.length()));  // remove implicit zeros
+            return value;
+        }
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java
index 769f071..405024c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -134,7 +134,7 @@
         mMockSystem.system().validateFinalState();
         mInstallPackageHelper = new InstallPackageHelper(mPmService, mock(AppDataHelper.class),
                 mock(RemovePackageHelper.class), mock(DeletePackageHelper.class),
-                mock(BroadcastHelper.class));
+                mock(BroadcastHelper.class), mock(InstallDependencyHelper.class));
     }
 
     @NonNull
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java
index 20ac078..0304a74 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java
@@ -79,12 +79,14 @@
     @Mock private SharedLibrariesImpl mSharedLibraries;
     @Mock private Context mContext;
     @Mock private Computer mComputer;
+    @Mock private PackageInstallerService mPackageInstallerService;
     private InstallDependencyHelper mInstallDependencyHelper;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mInstallDependencyHelper = new InstallDependencyHelper(mContext, mSharedLibraries);
+        mInstallDependencyHelper = new InstallDependencyHelper(mContext, mSharedLibraries,
+                mPackageInstallerService);
     }
 
     @Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 0a6edf1..b53dbc8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -218,6 +218,8 @@
         val handler = TestHandler(null)
         val defaultAppProvider: DefaultAppProvider = mock()
         val backgroundHandler = TestHandler(null)
+        val packageInstallerService: PackageInstallerService = mock()
+        val installDependencyHelper: InstallDependencyHelper = mock()
         val updateOwnershipHelper: UpdateOwnershipHelper = mock()
     }
 
@@ -306,6 +308,7 @@
         whenever(mocks.injector.handler) { mocks.handler }
         whenever(mocks.injector.defaultAppProvider) { mocks.defaultAppProvider }
         whenever(mocks.injector.backgroundHandler) { mocks.backgroundHandler }
+        whenever(mocks.injector.packageInstallerService) { mocks.packageInstallerService }
         whenever(mocks.injector.updateOwnershipHelper) { mocks.updateOwnershipHelper }
         whenever(mocks.injector.getSystemService(AppOpsManager::class.java)) { mocks.appOpsManager }
         wheneverStatic { SystemConfig.getInstance() }.thenReturn(mocks.systemConfig)
@@ -332,6 +335,8 @@
             DEVICE_PROVISIONING_PACKAGE_NAME
         }
         whenever(mocks.apexManager.activeApexInfos).thenReturn(DEFAULT_ACTIVE_APEX_INFO_LIST)
+        whenever(mocks.packageInstallerService.installDependencyHelper).thenReturn(
+            mocks.installDependencyHelper)
         whenever(mocks.settings.packagesLocked).thenReturn(mSettingsMap)
         whenever(mocks.settings.internalVersion).thenReturn(DEFAULT_VERSION_INFO)
         whenever(mocks.settings.keySetManagerService).thenReturn(mocks.keySetManagerService)
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
index 71c60ad..6f5e2b7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
@@ -741,11 +741,6 @@
                 /* stagedSessionErrorCode */ PackageManager.INSTALL_UNKNOWN,
                 /* stagedSessionErrorMessage */ "no error",
                 /* preVerifiedDomains */ null,
-                /* verifierController */ null,
-                /* initialVerificationPolicy */
-                PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED,
-                /* currentVerificationPolicy */
-                PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED,
                 /* installDependencyHelper */ null);
 
         StagingManager.StagedSession stagedSession = spy(session.mStagedSession);
diff --git a/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java b/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java
index d3943e3..d12579c 100644
--- a/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java
+++ b/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java
@@ -18,10 +18,10 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.ondeviceintelligence.InferenceInfo;
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService;
-import android.app.ondeviceintelligence.InferenceInfo;
 import android.util.Base64;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -32,7 +32,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.io.IOException;
 import java.util.List;
 
 @RunWith(AndroidJUnit4.class)
@@ -53,8 +52,8 @@
         List<InferenceInfo> inferenceInfos = inferenceInfoStore.getLatestInferenceInfo(0);
         assertThat(inferenceInfos).hasSize(1);
         assertThat(inferenceInfos.get(0).getUid()).isEqualTo(1);
-        assertThat(inferenceInfos.get(0).getStartTimeMs()).isEqualTo(1);
-        assertThat(inferenceInfos.get(0).getEndTimeMs()).isEqualTo(100);
+        assertThat(inferenceInfos.get(0).getStartTimeMillis()).isEqualTo(1);
+        assertThat(inferenceInfos.get(0).getEndTimeMillis()).isEqualTo(100);
     }
 
     @Test
@@ -66,8 +65,8 @@
         List<InferenceInfo> inferenceInfos = inferenceInfoStore.getLatestInferenceInfo(0);
         assertThat(inferenceInfos).hasSize(1);
         assertThat(inferenceInfos.get(0).getUid()).isEqualTo(1);
-        assertThat(inferenceInfos.get(0).getStartTimeMs()).isEqualTo(1);
-        assertThat(inferenceInfos.get(0).getEndTimeMs()).isEqualTo(100);
+        assertThat(inferenceInfos.get(0).getStartTimeMillis()).isEqualTo(1);
+        assertThat(inferenceInfos.get(0).getEndTimeMillis()).isEqualTo(100);
     }
 
 
@@ -87,8 +86,8 @@
         List<InferenceInfo> inferenceInfos = inferenceInfoStore.getLatestInferenceInfo(0);
         assertThat(inferenceInfos).hasSize(2);
         assertThat(inferenceInfos.get(0).getUid()).isEqualTo(1);
-        assertThat(inferenceInfos.get(0).getStartTimeMs()).isEqualTo(testStartTime - 10);
-        assertThat(inferenceInfos.get(0).getEndTimeMs()).isEqualTo(testStartTime + 100);
+        assertThat(inferenceInfos.get(0).getStartTimeMillis()).isEqualTo(testStartTime - 10);
+        assertThat(inferenceInfos.get(0).getEndTimeMillis()).isEqualTo(testStartTime + 100);
         inferenceInfoStore.addInferenceInfoFromBundle(bundle);
         List<InferenceInfo> inferenceInfos2 = inferenceInfoStore.getLatestInferenceInfo(0);
         assertThat(inferenceInfos2).hasSize(1); //previous entries should have been evicted
diff --git a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
index 0881b4c..313c01d 100644
--- a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -18,7 +18,6 @@
 
 
 import static com.android.server.power.hint.HintManagerService.CLEAN_UP_UID_DELAY_MILLIS;
-import static com.android.server.power.hint.HintManagerService.DEFAULT_HEADROOM_PID;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -53,7 +52,9 @@
 import android.hardware.power.ChannelConfig;
 import android.hardware.power.ChannelMessage;
 import android.hardware.power.CpuHeadroomParams;
+import android.hardware.power.CpuHeadroomResult;
 import android.hardware.power.GpuHeadroomParams;
+import android.hardware.power.GpuHeadroomResult;
 import android.hardware.power.IPower;
 import android.hardware.power.SessionConfig;
 import android.hardware.power.SessionTag;
@@ -66,6 +67,7 @@
 import android.os.PerformanceHintManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SessionCreationConfig;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -200,7 +202,7 @@
         when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID),
                 eq(SESSION_TIDS_C), eq(0L), anyInt(),
                 any(SessionConfig.class))).thenAnswer(fakeCreateWithConfig(SESSION_PTRS[2],
-                SESSION_IDS[2]));
+                    SESSION_IDS[2]));
 
         when(mIPowerMock.getInterfaceVersion()).thenReturn(6);
         when(mIPowerMock.getSessionChannel(anyInt(), anyInt())).thenReturn(mConfig);
@@ -305,6 +307,14 @@
         return mService;
     }
 
+    private SessionCreationConfig makeSessionCreationConfig(int[] tids,
+            long targetWorkDurationNanos) {
+        SessionCreationConfig config = new SessionCreationConfig();
+        config.tids = tids;
+        config.targetWorkDurationNanos = targetWorkDurationNanos;
+        return config;
+    }
+
     @Test
     public void testInitializeService() {
         HintManagerService service = createService();
@@ -316,12 +326,14 @@
     public void testCreateHintSessionInvalidPid() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(new int[]{TID, 1}, DEFAULT_TARGET_DURATION);
         // Make sure we throw exception when adding a TID doesn't belong to the processes
         // In this case, we add `init` PID into the list.
         SessionConfig config = new SessionConfig();
         assertThrows(SecurityException.class,
                 () -> service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                        new int[]{TID, 1}, DEFAULT_TARGET_DURATION, SessionTag.OTHER, config));
+                        SessionTag.OTHER, creationConfig, config));
     }
 
     @Test
@@ -329,17 +341,23 @@
         HintManagerService service = createService();
         IBinder token = new Binder();
         makeConfigCreationUnsupported();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SESSION_TIDS_A, DEFAULT_TARGET_DURATION, SessionTag.OTHER, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig());
         assertNotNull(a);
 
+        creationConfig.tids = SESSION_TIDS_B;
+        creationConfig.targetWorkDurationNanos = DOUBLED_TARGET_DURATION;
         IHintSession b = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SESSION_TIDS_B, DOUBLED_TARGET_DURATION, SessionTag.OTHER, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig());
         assertNotEquals(a, b);
 
+        creationConfig.tids = SESSION_TIDS_C;
+        creationConfig.targetWorkDurationNanos = 0L;
         IHintSession c = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SESSION_TIDS_C, 0L, SessionTag.OTHER, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig());
         assertNotNull(c);
         verify(mNativeWrapperMock, times(3)).halCreateHintSession(anyInt(), anyInt(),
                 any(int[].class), anyLong());
@@ -349,22 +367,28 @@
     public void testCreateHintSessionWithConfig() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         SessionConfig config = new SessionConfig();
         IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SESSION_TIDS_A, DEFAULT_TARGET_DURATION, SessionTag.OTHER, config);
+                SessionTag.OTHER, creationConfig, config);
         assertNotNull(a);
         assertEquals(SESSION_IDS[0], config.id);
 
         SessionConfig config2 = new SessionConfig();
+        creationConfig.tids = SESSION_TIDS_B;
+        creationConfig.targetWorkDurationNanos = DOUBLED_TARGET_DURATION;
         IHintSession b = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SESSION_TIDS_B, DOUBLED_TARGET_DURATION, SessionTag.APP, config2);
+                SessionTag.APP, creationConfig, config2);
         assertNotEquals(a, b);
         assertEquals(SESSION_IDS[1], config2.id);
 
         SessionConfig config3 = new SessionConfig();
+        creationConfig.tids = SESSION_TIDS_C;
+        creationConfig.targetWorkDurationNanos = 0L;
         IHintSession c = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SESSION_TIDS_C, 0L, SessionTag.GAME, config3);
+                SessionTag.GAME, creationConfig, config3);
         assertNotNull(c);
         assertEquals(SESSION_IDS[2], config3.id);
         verify(mNativeWrapperMock, times(3)).halCreateHintSessionWithConfig(anyInt(), anyInt(),
@@ -372,13 +396,48 @@
     }
 
     @Test
-    public void testPauseResumeHintSession() throws Exception {
+    public void testCreateGraphicsPipelineSessions() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
 
+        final int threadCount =
+                service.getBinderServiceInstance().getMaxGraphicsPipelineThreadsCount();
+        long sessionPtr1 = 1111L;
+        long sessionId1 = 11111L;
+        CountDownLatch stopLatch1 = new CountDownLatch(1);
+        int[] tids1 = createThreads(threadCount, stopLatch1);
+        when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID), eq(tids1),
+                eq(DEFAULT_TARGET_DURATION), anyInt(), any(SessionConfig.class)))
+                .thenAnswer(fakeCreateWithConfig(sessionPtr1, sessionId1));
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
+
+        creationConfig.modesToEnable = new int[] {1}; // GRAPHICS_PIPELINE
+
+        SessionConfig config = new SessionConfig();
+        IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
+                SessionTag.OTHER, creationConfig, config);
+        assertNotNull(a);
+        assertEquals(sessionId1, config.id);
+
+        creationConfig.tids = createThreads(1, stopLatch1);
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            service.getBinderServiceInstance().createHintSessionWithConfig(token,
+                    SessionTag.OTHER, creationConfig, config);
+        });
+    }
+
+    @Test
+    public void testPauseResumeHintSession() throws Exception {
+        HintManagerService service = createService();
+        IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
 
         // Set session to background and calling updateHintAllowedByProcState() would invoke
         // pause();
@@ -414,9 +473,11 @@
     public void testCloseHintSession() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SESSION_TIDS_A, DEFAULT_TARGET_DURATION, SessionTag.OTHER, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig());
 
         a.close();
         verify(mNativeWrapperMock, times(1)).halCloseHintSession(anyLong());
@@ -426,9 +487,11 @@
     public void testUpdateTargetWorkDuration() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SESSION_TIDS_A, DEFAULT_TARGET_DURATION, SessionTag.OTHER, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig());
 
         assertThrows(IllegalArgumentException.class, () -> {
             a.updateTargetWorkDuration(-1L);
@@ -446,10 +509,12 @@
     public void testReportActualWorkDuration() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
 
         a.updateTargetWorkDuration(100L);
         a.reportActualWorkDuration(DURATIONS_THREE, TIMESTAMPS_THREE);
@@ -489,10 +554,12 @@
     public void testSendHint() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
 
         a.sendHint(PerformanceHintManager.Session.CPU_LOAD_RESET);
         verify(mNativeWrapperMock, times(1)).halSendHint(anyLong(),
@@ -516,10 +583,12 @@
     public void testDoHintInBackground() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
 
         service.mUidObserver.onUidStateChanged(
                 a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND, 0, 0);
@@ -538,10 +607,12 @@
     public void testDoHintInForeground() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
 
         service.mUidObserver.onUidStateChanged(
                 a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0, 0);
@@ -552,10 +623,12 @@
     public void testSetThreads() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
 
         a.updateTargetWorkDuration(100L);
 
@@ -591,9 +664,11 @@
         when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID), eq(tids1),
                 eq(DEFAULT_TARGET_DURATION), anyInt(), any(SessionConfig.class)))
                 .thenReturn(sessionPtr1);
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
         AppHintSession session1 = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, tids1, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
         assertNotNull(session1);
 
         // trigger UID state change by making the process foreground->background, but because the
@@ -626,9 +701,11 @@
         when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID), eq(tids1),
                 eq(DEFAULT_TARGET_DURATION), anyInt(), any(SessionConfig.class)))
                 .thenReturn(sessionPtr1);
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
         AppHintSession session1 = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, tids1, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
         assertNotNull(session1);
 
         // let all session 1 threads to exit and the cleanup should force pause the session 1
@@ -734,10 +811,12 @@
     public void testSetMode() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
 
         a.setMode(0, true);
         verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
@@ -746,12 +825,19 @@
         a.setMode(0, false);
         verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
                 eq(0), eq(false));
+    }
 
-        assertThrows(IllegalArgumentException.class, () -> {
-            a.setMode(-1, true);
-        });
+    @Test
+    public void testSetModeSessionInBackGround() throws Exception {
+        HintManagerService service = createService();
+        IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
-        reset(mNativeWrapperMock);
+        AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
+
         // Set session to background, then the duration would not be updated.
         service.mUidObserver.onUidStateChanged(
                 a.mUid, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0);
@@ -763,6 +849,40 @@
     }
 
     @Test
+    public void testSetModeInvalid() throws Exception {
+        HintManagerService service = createService();
+        IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
+        AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            a.setMode(-1, true);
+        });
+    }
+
+    @Test
+    public void testSetModeUponSessionCreation() throws Exception {
+        HintManagerService service = createService();
+        IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+        creationConfig.modesToEnable = new int[] {0, 1};
+
+        AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
+        assertNotNull(a);
+        verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
+                eq(0), eq(true));
+        verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
+                eq(1), eq(true));
+    }
+
+    @Test
     public void testGetChannel() throws Exception {
         HintManagerService service = createService();
         Binder token = new Binder();
@@ -950,9 +1070,12 @@
     private void runAppHintSession(HintManagerService service, int logId,
             AtomicReference<Boolean> shouldRun) throws Exception {
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
         // we will start some threads and get their valid TIDs to update
         int threadCount = 3;
         // the list of TIDs
@@ -1017,10 +1140,12 @@
     public void testReportActualWorkDuration2() throws Exception {
         HintManagerService service = createService();
         IBinder token = new Binder();
+        SessionCreationConfig creationConfig =
+                makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
-                .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
-                        SessionTag.OTHER, new SessionConfig());
+                .createHintSessionWithConfig(token, SessionTag.OTHER,
+                        creationConfig, new SessionConfig());
 
         a.updateTargetWorkDuration(100L);
         a.reportActualWorkDuration2(WORK_DURATIONS_FIVE);
@@ -1127,67 +1252,98 @@
         CpuHeadroomParams halParams1 = new CpuHeadroomParams();
         halParams1.calculationType = CpuHeadroomParams.CalculationType.MIN;
         halParams1.selectionType = CpuHeadroomParams.SelectionType.ALL;
-        halParams1.pid = Process.myPid();
+        halParams1.tids = new int[]{Process.myPid()};
 
         CpuHeadroomParamsInternal params2 = new CpuHeadroomParamsInternal();
         params2.usesDeviceHeadroom = true;
-        params2.calculationType = CpuHeadroomParams.CalculationType.AVERAGE;
+        params2.calculationType = CpuHeadroomParams.CalculationType.MIN;
         params2.selectionType = CpuHeadroomParams.SelectionType.PER_CORE;
         CpuHeadroomParams halParams2 = new CpuHeadroomParams();
-        halParams2.calculationType = CpuHeadroomParams.CalculationType.AVERAGE;
+        halParams2.calculationType = CpuHeadroomParams.CalculationType.MIN;
         halParams2.selectionType = CpuHeadroomParams.SelectionType.PER_CORE;
-        halParams2.pid = DEFAULT_HEADROOM_PID;
+        halParams2.tids = new int[]{};
 
-        float[] headroom1 = new float[] {0.1f};
-        when(mIPowerMock.getCpuHeadroom(eq(halParams1))).thenReturn(headroom1);
-        float[] headroom2 = new float[] {0.1f, 0.5f};
-        when(mIPowerMock.getCpuHeadroom(eq(halParams2))).thenReturn(headroom2);
+        CpuHeadroomParamsInternal params3 = new CpuHeadroomParamsInternal();
+        params3.calculationType = CpuHeadroomParams.CalculationType.AVERAGE;
+        params3.selectionType = CpuHeadroomParams.SelectionType.ALL;
+        CpuHeadroomParams halParams3 = new CpuHeadroomParams();
+        halParams3.calculationType = CpuHeadroomParams.CalculationType.AVERAGE;
+        halParams3.selectionType = CpuHeadroomParams.SelectionType.ALL;
+        halParams3.tids = new int[]{Process.myPid()};
+
+        // this params should not be cached as the window is not default
+        CpuHeadroomParamsInternal params4 = new CpuHeadroomParamsInternal();
+        params4.calculationWindowMillis = 123;
+        CpuHeadroomParams halParams4 = new CpuHeadroomParams();
+        halParams4.calculationType = CpuHeadroomParams.CalculationType.MIN;
+        halParams4.selectionType = CpuHeadroomParams.SelectionType.ALL;
+        halParams4.calculationWindowMillis = 123;
+        halParams4.tids = new int[]{Process.myPid()};
+
+        float headroom1 = 0.1f;
+        CpuHeadroomResult halRet1 = CpuHeadroomResult.globalHeadroom(headroom1);
+        when(mIPowerMock.getCpuHeadroom(eq(halParams1))).thenReturn(halRet1);
+        float[] headroom2 = new float[] {0.2f, 0.2f};
+        CpuHeadroomResult halRet2 = CpuHeadroomResult.perCoreHeadroom(headroom2);
+        when(mIPowerMock.getCpuHeadroom(eq(halParams2))).thenReturn(halRet2);
+        float headroom3 = 0.3f;
+        CpuHeadroomResult halRet3 = CpuHeadroomResult.globalHeadroom(headroom3);
+        when(mIPowerMock.getCpuHeadroom(eq(halParams3))).thenReturn(halRet3);
+        float headroom4 = 0.4f;
+        CpuHeadroomResult halRet4 = CpuHeadroomResult.globalHeadroom(headroom4);
+        when(mIPowerMock.getCpuHeadroom(eq(halParams4))).thenReturn(halRet4);
 
         HintManagerService service = createService();
         clearInvocations(mIPowerMock);
 
         service.getBinderServiceInstance().getCpuHeadroomMinIntervalMillis();
         verify(mIPowerMock, times(0)).getCpuHeadroomMinIntervalMillis();
-        service.getBinderServiceInstance().getCpuHeadroom(params1);
+        assertEquals(halRet1, service.getBinderServiceInstance().getCpuHeadroom(params1));
         verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams1));
-        service.getBinderServiceInstance().getCpuHeadroom(params2);
+        assertEquals(halRet2, service.getBinderServiceInstance().getCpuHeadroom(params2));
         verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams2));
+        assertEquals(halRet3, service.getBinderServiceInstance().getCpuHeadroom(params3));
+        verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams3));
+        assertEquals(halRet4, service.getBinderServiceInstance().getCpuHeadroom(params4));
+        verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams4));
 
         // verify cache is working
         clearInvocations(mIPowerMock);
-        assertArrayEquals(headroom1, service.getBinderServiceInstance().getCpuHeadroom(params1),
-                0.01f);
-        assertArrayEquals(headroom2, service.getBinderServiceInstance().getCpuHeadroom(params2),
-                0.01f);
-        verify(mIPowerMock, times(0)).getCpuHeadroom(any());
+        assertEquals(halRet1, service.getBinderServiceInstance().getCpuHeadroom(params1));
+        assertEquals(halRet2, service.getBinderServiceInstance().getCpuHeadroom(params2));
+        assertEquals(halRet3, service.getBinderServiceInstance().getCpuHeadroom(params3));
+        assertEquals(halRet4, service.getBinderServiceInstance().getCpuHeadroom(params4));
+        verify(mIPowerMock, times(1)).getCpuHeadroom(any());
+        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams1));
+        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams2));
+        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams3));
+        verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams4));
 
         // after 1 more second it should be served with cache still
         Thread.sleep(1000);
         clearInvocations(mIPowerMock);
-        assertArrayEquals(headroom1, service.getBinderServiceInstance().getCpuHeadroom(params1),
-                0.01f);
-        assertArrayEquals(headroom2, service.getBinderServiceInstance().getCpuHeadroom(params2),
-                0.01f);
-        verify(mIPowerMock, times(0)).getCpuHeadroom(any());
-
-        // after 1.5 more second it should be served with cache still as timer reset
-        Thread.sleep(1500);
-        clearInvocations(mIPowerMock);
-        assertArrayEquals(headroom1, service.getBinderServiceInstance().getCpuHeadroom(params1),
-                0.01f);
-        assertArrayEquals(headroom2, service.getBinderServiceInstance().getCpuHeadroom(params2),
-                0.01f);
-        verify(mIPowerMock, times(0)).getCpuHeadroom(any());
+        assertEquals(halRet1, service.getBinderServiceInstance().getCpuHeadroom(params1));
+        assertEquals(halRet2, service.getBinderServiceInstance().getCpuHeadroom(params2));
+        assertEquals(halRet3, service.getBinderServiceInstance().getCpuHeadroom(params3));
+        assertEquals(halRet4, service.getBinderServiceInstance().getCpuHeadroom(params4));
+        verify(mIPowerMock, times(1)).getCpuHeadroom(any());
+        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams1));
+        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams2));
+        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams3));
+        verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams4));
 
         // after 2+ seconds it should be served from HAL as it exceeds 2000 millis interval
-        Thread.sleep(2100);
+        Thread.sleep(1100);
         clearInvocations(mIPowerMock);
-        assertArrayEquals(headroom1, service.getBinderServiceInstance().getCpuHeadroom(params1),
-                0.01f);
-        assertArrayEquals(headroom2, service.getBinderServiceInstance().getCpuHeadroom(params2),
-                0.01f);
+        assertEquals(halRet1, service.getBinderServiceInstance().getCpuHeadroom(params1));
+        assertEquals(halRet2, service.getBinderServiceInstance().getCpuHeadroom(params2));
+        assertEquals(halRet3, service.getBinderServiceInstance().getCpuHeadroom(params3));
+        assertEquals(halRet4, service.getBinderServiceInstance().getCpuHeadroom(params4));
+        verify(mIPowerMock, times(4)).getCpuHeadroom(any());
         verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams1));
         verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams2));
+        verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams3));
+        verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams4));
     }
 
     @Test
@@ -1198,59 +1354,52 @@
         halParams1.calculationType = GpuHeadroomParams.CalculationType.MIN;
 
         GpuHeadroomParamsInternal params2 = new GpuHeadroomParamsInternal();
+        params2.calculationType = GpuHeadroomParams.CalculationType.AVERAGE;
+        params2.calculationWindowMillis = 123;
         GpuHeadroomParams halParams2 = new GpuHeadroomParams();
-        params2.calculationType =
-                halParams2.calculationType = GpuHeadroomParams.CalculationType.AVERAGE;
+        halParams2.calculationType = GpuHeadroomParams.CalculationType.AVERAGE;
+        halParams2.calculationWindowMillis = 123;
 
         float headroom1 = 0.1f;
-        when(mIPowerMock.getGpuHeadroom(eq(halParams1))).thenReturn(headroom1);
+        GpuHeadroomResult halRet1 = GpuHeadroomResult.globalHeadroom(headroom1);
+        when(mIPowerMock.getGpuHeadroom(eq(halParams1))).thenReturn(halRet1);
         float headroom2 = 0.2f;
-        when(mIPowerMock.getGpuHeadroom(eq(halParams2))).thenReturn(headroom2);
+        GpuHeadroomResult halRet2 = GpuHeadroomResult.globalHeadroom(headroom2);
+        when(mIPowerMock.getGpuHeadroom(eq(halParams2))).thenReturn(halRet2);
         HintManagerService service = createService();
         clearInvocations(mIPowerMock);
 
         service.getBinderServiceInstance().getGpuHeadroomMinIntervalMillis();
         verify(mIPowerMock, times(0)).getGpuHeadroomMinIntervalMillis();
-        assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1),
-                0.01f);
-        assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2),
-                0.01f);
+        assertEquals(halRet1, service.getBinderServiceInstance().getGpuHeadroom(params1));
+        assertEquals(halRet2, service.getBinderServiceInstance().getGpuHeadroom(params2));
+        verify(mIPowerMock, times(2)).getGpuHeadroom(any());
         verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams1));
         verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2));
 
         // verify cache is working
         clearInvocations(mIPowerMock);
-        assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1),
-                0.01f);
-        assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2),
-                0.01f);
-        verify(mIPowerMock, times(0)).getGpuHeadroom(any());
+        assertEquals(halRet1, service.getBinderServiceInstance().getGpuHeadroom(params1));
+        assertEquals(halRet2, service.getBinderServiceInstance().getGpuHeadroom(params2));
+        verify(mIPowerMock, times(1)).getGpuHeadroom(any());
+        verify(mIPowerMock, times(0)).getGpuHeadroom(eq(halParams1));
+        verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2));
 
         // after 1 more second it should be served with cache still
         Thread.sleep(1000);
         clearInvocations(mIPowerMock);
-        assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1),
-                0.01f);
-        assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2),
-                0.01f);
-        verify(mIPowerMock, times(0)).getGpuHeadroom(any());
-
-        // after 1.5 more second it should be served with cache still as timer reset
-        Thread.sleep(1500);
-        clearInvocations(mIPowerMock);
-        assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1),
-                0.01f);
-        assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2),
-                0.01f);
-        verify(mIPowerMock, times(0)).getGpuHeadroom(any());
+        assertEquals(halRet1, service.getBinderServiceInstance().getGpuHeadroom(params1));
+        assertEquals(halRet2, service.getBinderServiceInstance().getGpuHeadroom(params2));
+        verify(mIPowerMock, times(1)).getGpuHeadroom(any());
+        verify(mIPowerMock, times(0)).getGpuHeadroom(eq(halParams1));
+        verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2));
 
         // after 2+ seconds it should be served from HAL as it exceeds 2000 millis interval
-        Thread.sleep(2100);
+        Thread.sleep(1100);
         clearInvocations(mIPowerMock);
-        assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1),
-                0.01f);
-        assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2),
-                0.01f);
+        assertEquals(halRet1, service.getBinderServiceInstance().getGpuHeadroom(params1));
+        assertEquals(halRet2, service.getBinderServiceInstance().getGpuHeadroom(params2));
+        verify(mIPowerMock, times(2)).getGpuHeadroom(any());
         verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams1));
         verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2));
     }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java
index c0be865..4b91d84 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java
@@ -79,8 +79,6 @@
         // 100,000,00 uC / 1000 (micro-/milli-) / 360 (seconds/hour) = 27.777778 mAh
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
                 .isWithin(PRECISION).of(27.777778);
-        assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 
     @Test
@@ -140,8 +138,6 @@
         // (seconds/hour) = 27.777778 mAh
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
                 .isWithin(PRECISION).of(83.33333);
-        assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 
     @Test
@@ -163,8 +159,6 @@
                 .isEqualTo(90 * MINUTE_IN_MS);
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
                 .isWithin(PRECISION).of(15.0);
-        assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
     @Test
@@ -195,7 +189,5 @@
                 .isEqualTo(120 * MINUTE_IN_MS);
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
                 .isWithin(PRECISION).of(35.0);
-        assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java
index 5d50e6c..9da89fc 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java
@@ -311,10 +311,6 @@
                 bus.getAggregateBatteryConsumer(AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE),
                 proto.deviceBatteryConsumer);
 
-        for (int i = 0; i < BatteryConsumer.POWER_COMPONENT_COUNT; i++) {
-            assertPowerComponentModel(i, abc.getPowerModel(i), proto);
-        }
-
         // Now for the UidBatteryConsumers.
         final List<android.os.UidBatteryConsumer> uidConsumers = bus.getUidBatteryConsumers();
         uidConsumers.sort((a, b) -> a.getUid() - b.getUid());
@@ -450,34 +446,6 @@
         }
     }
 
-    /**
-     * Validates the PowerComponentModel object that matches powerComponent.
-     */
-    private void assertPowerComponentModel(int powerComponent,
-            @BatteryConsumer.PowerModel int powerModel, BatteryUsageStatsAtomsProto proto) {
-        boolean found = false;
-        for (BatteryUsageStatsAtomsProto.PowerComponentModel powerComponentModel :
-                proto.componentModels) {
-            if (powerComponentModel.component == powerComponent) {
-                if (found) {
-                    fail("Power component " + BatteryConsumer.powerComponentIdToString(
-                            powerComponent) + " found multiple times in the proto");
-                }
-                found = true;
-                final int expectedPowerModel = BatteryConsumer.powerModelToProtoEnum(powerModel);
-                assertEquals(expectedPowerModel, powerComponentModel.powerModel);
-            }
-        }
-        if (!found) {
-            final int model = BatteryConsumer.powerModelToProtoEnum(powerModel);
-            assertEquals(
-                    "Power component " + BatteryConsumer.powerComponentIdToString(powerComponent)
-                            + " was not found in the proto but has a defined power model.",
-                    BatteryUsageStatsAtomsProto.PowerComponentModel.UNDEFINED,
-                    model);
-        }
-    }
-
     /** Converts charge from milliamp hours (mAh) to decicoulombs (dC). */
     private long convertMahToDc(double powerMah) {
         return (long) (powerMah * 36 + 0.5);
@@ -486,7 +454,6 @@
     private BatteryUsageStats buildBatteryUsageStats() {
         final BatteryUsageStats.Builder builder =
                 new BatteryUsageStats.Builder(new String[]{"CustomConsumer1", "CustomConsumer2"},
-                        /* includePowerModels */ true,
                         /* includeProcessStats */ true,
                         /* includeScreenStateData */ false,
                         /* includePowerStateData */ false,
@@ -524,13 +491,13 @@
         final BatteryConsumer.Key keyCached = uidBuilder.getKey(BatteryConsumer.POWER_COMPONENT_CPU,
                 BatteryConsumer.PROCESS_STATE_CACHED);
 
-        uidBuilder.addConsumedPower(keyFg, 9100, BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+        uidBuilder.addConsumedPower(keyFg, 9100)
                 .addUsageDurationMillis(keyFg, 8100)
-                .addConsumedPower(keyBg, 9200, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
+                .addConsumedPower(keyBg, (double) 9200)
                 .addUsageDurationMillis(keyBg, 8200)
-                .addConsumedPower(keyFgs, 9300, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
+                .addConsumedPower(keyFgs, (double) 9300)
                 .addUsageDurationMillis(keyFgs, 8300)
-                .addConsumedPower(keyCached, 9400, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
+                .addConsumedPower(keyCached, (double) 9400)
                 .addUsageDurationMillis(keyCached, 8400);
 
         final BatteryConsumer.Key keyCustomFg = uidBuilder.getKey(
@@ -539,10 +506,8 @@
         final BatteryConsumer.Key keyCustomBg = uidBuilder.getKey(
                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
                 BatteryConsumer.PROCESS_STATE_BACKGROUND);
-        uidBuilder.addConsumedPower(
-                keyCustomFg, 100, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
-        uidBuilder.addConsumedPower(
-                keyCustomBg, 350, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
+        uidBuilder.addConsumedPower(keyCustomFg, 100);
+        uidBuilder.addConsumedPower(keyCustomBg, 350);
 
         builder.getOrCreateUidBatteryConsumerBuilder(UID_1)
                 .setPackageWithHighestDrain("myPackage1")
@@ -557,14 +522,11 @@
         builder.getAggregateBatteryConsumerBuilder(AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
                 .addConsumedPower(30000)
                 .addConsumedPower(
-                        BatteryConsumer.POWER_COMPONENT_CPU, 20100,
-                        BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                        BatteryConsumer.POWER_COMPONENT_CPU, 20100)
                 .addConsumedPower(
-                        BatteryConsumer.POWER_COMPONENT_AUDIO, 0,
-                        BatteryConsumer.POWER_MODEL_POWER_PROFILE) // Empty
+                        BatteryConsumer.POWER_COMPONENT_AUDIO, 0) // Empty
                 .addConsumedPower(
-                        BatteryConsumer.POWER_COMPONENT_CAMERA, 20150,
-                        BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
+                        BatteryConsumer.POWER_COMPONENT_CAMERA, 20150)
                 .addConsumedPower(
                         BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20200)
                 .addUsageDurationMillis(
@@ -576,8 +538,7 @@
         builder.getAggregateBatteryConsumerBuilder(
                         BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
                 .addConsumedPower(
-                        BatteryConsumer.POWER_COMPONENT_CPU, 10100,
-                        BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                        BatteryConsumer.POWER_COMPONENT_CPU, 10100)
                 .addConsumedPower(
                         BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200);
 
@@ -587,7 +548,7 @@
     @Test
     public void testLargeAtomTruncated() throws Exception {
         final BatteryUsageStats.Builder builder =
-                new BatteryUsageStats.Builder(new String[0], true, false, false, false, 0);
+                new BatteryUsageStats.Builder(new String[0], false, false, false, 0);
         // If not truncated, this BatteryUsageStats object would generate a proto buffer
         // significantly larger than 50 Kb
         for (int i = 0; i < 3000; i++) {
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
index 383616e..a3c7ece 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
@@ -423,8 +423,6 @@
             mBatteryUsageStats = null;
         }
         final String[] customPowerComponentNames = mBatteryStats.getCustomEnergyConsumerNames();
-        final boolean includePowerModels = (query.getFlags()
-                & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0;
         final boolean includeProcessStateData = (query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0;
         final boolean includeScreenStateData = (query.getFlags()
@@ -433,7 +431,7 @@
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_STATE) != 0;
         final double minConsumedPowerThreshold = query.getMinConsumedPowerThreshold();
         BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
-                customPowerComponentNames, includePowerModels, includeProcessStateData,
+                customPowerComponentNames, includeProcessStateData,
                 includeScreenStateData, includePowerStateData, minConsumedPowerThreshold);
         SparseArray<? extends BatteryStats.Uid> uidStats = mBatteryStats.getUidStats();
         for (int i = 0; i < uidStats.size(); i++) {
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
index 9771da5..dd50431 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
@@ -17,8 +17,6 @@
 package com.android.server.power.stats;
 
 import static android.os.BatteryConsumer.POWER_COMPONENT_ANY;
-import static android.os.BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION;
-import static android.os.BatteryConsumer.POWER_MODEL_UNDEFINED;
 import static android.os.BatteryConsumer.PROCESS_STATE_BACKGROUND;
 import static android.os.BatteryConsumer.PROCESS_STATE_CACHED;
 import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND;
@@ -237,7 +235,7 @@
         final BatteryUsageStats stats1 = buildBatteryUsageStats1(false).build();
         final BatteryUsageStats stats2 = buildBatteryUsageStats2(new String[]{"FOO"}, true).build();
         final BatteryUsageStats sum =
-                new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, true, true, 0)
+                new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, true, 0)
                         .add(stats1)
                         .add(stats2)
                         .build();
@@ -248,15 +246,13 @@
         for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
             if (uidBatteryConsumer.getUid() == APP_UID1) {
                 assertUidBatteryConsumer(uidBatteryConsumer, 1200 + 924, null,
-                        5321, 6900, 532, 423, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400 + 345,
-                        POWER_MODEL_UNDEFINED,
+                        5321, 6900, 532, 423, 400 + 345,
                         500 + 456, 1167, 1478,
                         true, 3554, 4732, 3998, 444, 3554, 15542, 3776, 17762, 3998, 19982,
                         444, 1110);
             } else if (uidBatteryConsumer.getUid() == APP_UID2) {
                 assertUidBatteryConsumer(uidBatteryConsumer, 1332, "bar",
-                        1111, 2220, 2, 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
-                        BatteryConsumer.POWER_MODEL_POWER_PROFILE,
+                        1111, 2220, 2, 333, 444,
                         555, 666, 777,
                         true, 1777, 2443, 1999, 321, 1777, 7771, 1888, 8881, 1999, 9991,
                         321, 654);
@@ -280,7 +276,7 @@
     @Test
     public void testAdd_customComponentMismatch() throws Exception {
         final BatteryUsageStats.Builder builder =
-                new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, true, true, 0);
+                new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, true, 0);
         final BatteryUsageStats stats = buildBatteryUsageStats2(new String[]{"BAR"}, false).build();
 
         assertThrows(IllegalArgumentException.class, () -> builder.add(stats));
@@ -291,7 +287,7 @@
     @Test
     public void testAdd_processStateDataMismatch() throws Exception {
         final BatteryUsageStats.Builder builder =
-                new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, true, true, 0);
+                new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, true, 0);
         final BatteryUsageStats stats = buildBatteryUsageStats2(new String[]{"FOO"}, false).build();
 
         assertThrows(IllegalArgumentException.class, () -> builder.add(stats));
@@ -328,7 +324,7 @@
         final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
 
         final BatteryUsageStats.Builder builder =
-                new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true,
+                new BatteryUsageStats.Builder(new String[]{"FOO"}, true,
                         includeScreenState, includePowerState, 0)
                         .setBatteryCapacity(4000)
                         .setDischargePercentage(20)
@@ -339,8 +335,8 @@
 
         addUidBatteryConsumer(builder, batteryStats, APP_UID1, "foo",
                 1000, 1500, 500,
-                300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
-                BatteryConsumer.POWER_MODEL_POWER_PROFILE, 500, 600, 800,
+                300, 400,
+                500, 600, 800,
                 1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
 
         addAggregateBatteryConsumer(builder,
@@ -373,7 +369,7 @@
         final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
 
         final BatteryUsageStats.Builder builder =
-                new BatteryUsageStats.Builder(customPowerComponentNames, true,
+                new BatteryUsageStats.Builder(customPowerComponentNames,
                         includeProcessStateData, true, true, 0);
         builder.setDischargePercentage(30)
                 .setDischargedPowerRange(1234, 2345)
@@ -382,14 +378,14 @@
 
         addUidBatteryConsumer(builder, batteryStats, APP_UID1, null,
                 4321, 5400, 32,
-                123, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 345, POWER_MODEL_ENERGY_CONSUMPTION,
+                123, 345,
                 456, 567, 678,
                 1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
 
         addUidBatteryConsumer(builder, batteryStats, APP_UID2, "bar",
                 1111, 2220, 2,
-                333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
-                BatteryConsumer.POWER_MODEL_POWER_PROFILE, 555, 666, 777,
+                333, 444,
+                555, 666, 777,
                 1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
 
         addAggregateBatteryConsumer(builder,
@@ -409,7 +405,7 @@
             MockBatteryStatsImpl batteryStats, int uid, String packageWithHighestDrain,
             int timeInProcessStateForeground, int timeInProcessStateBackground,
             int timeInProcessStateForegroundService, double screenPower,
-            int screenPowerModel, double cpuPower, int cpuPowerModel, double customComponentPower,
+            double cpuPower, double customComponentPower,
             int cpuDuration, int customComponentDuration, double cpuPowerForeground,
             int cpuDurationForeground, double cpuPowerBackground, int cpuDurationBackground,
             double cpuPowerFgs, int cpuDurationFgs, double cpuPowerCached, long cpuDurationCached) {
@@ -423,9 +419,9 @@
                 .setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE,
                         timeInProcessStateForegroundService)
                 .addConsumedPower(
-                        BatteryConsumer.POWER_COMPONENT_SCREEN, screenPower, screenPowerModel)
+                        BatteryConsumer.POWER_COMPONENT_SCREEN, screenPower)
                 .addConsumedPower(
-                        BatteryConsumer.POWER_COMPONENT_CPU, cpuPower, cpuPowerModel)
+                        BatteryConsumer.POWER_COMPONENT_CPU, cpuPower)
                 .addConsumedPower(
                         BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentPower)
                 .addUsageDurationMillis(
@@ -460,21 +456,15 @@
                     : uidBuilder.getKey(
                             BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
                             BatteryConsumer.PROCESS_STATE_BACKGROUND);
-            uidBuilder
-                    .addConsumedPower(cpuFgKey, cpuPowerForeground,
-                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+            uidBuilder.addConsumedPower(cpuFgKey, cpuPowerForeground)
                     .addUsageDurationMillis(cpuFgKey, cpuDurationForeground)
-                    .addConsumedPower(cpuBgKey, cpuPowerBackground,
-                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                    .addConsumedPower(cpuBgKey, cpuPowerBackground)
                     .addUsageDurationMillis(cpuBgKey, cpuDurationBackground)
-                    .addConsumedPower(cpuFgsKey, cpuPowerFgs,
-                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                    .addConsumedPower(cpuFgsKey, cpuPowerFgs)
                     .addUsageDurationMillis(cpuFgsKey, cpuDurationFgs)
-                    .addConsumedPower(cachedKey, cpuPowerCached,
-                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                    .addConsumedPower(cachedKey, cpuPowerCached)
                     .addUsageDurationMillis(cachedKey, cpuDurationCached)
-                    .addConsumedPower(customBgKey, customComponentPower,
-                            BatteryConsumer.POWER_MODEL_UNDEFINED)
+                    .addConsumedPower(customBgKey, customComponentPower)
                     .addUsageDurationMillis(customBgKey, customComponentDuration);
         }
     }
@@ -518,18 +508,13 @@
                     BatteryConsumer.PROCESS_STATE_UNSPECIFIED,
                     BatteryConsumer.SCREEN_STATE_OTHER,
                     BatteryConsumer.POWER_STATE_OTHER);
-            aggBuilder
-                    .addConsumedPower(cpuBatScrOn, cpuPowerBatScrOn,
-                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+            aggBuilder.addConsumedPower(cpuBatScrOn, cpuPowerBatScrOn)
                     .addUsageDurationMillis(cpuBatScrOn, cpuDurationBatScrOn)
-                    .addConsumedPower(cpuBatScrOff, cpuPowerBatScrOff,
-                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                    .addConsumedPower(cpuBatScrOff, cpuPowerBatScrOff)
                     .addUsageDurationMillis(cpuBatScrOff, cpuDurationBatScrOff)
-                    .addConsumedPower(cpuChgScrOn, cpuPowerChgScrOn,
-                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                    .addConsumedPower(cpuChgScrOn, cpuPowerChgScrOn)
                     .addUsageDurationMillis(cpuChgScrOn, cpuDurationChgScrOn)
-                    .addConsumedPower(cpuChgScrOff, cpuPowerChgScrOff,
-                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                    .addConsumedPower(cpuChgScrOff, cpuPowerChgScrOff)
                     .addUsageDurationMillis(cpuChgScrOff, cpuDurationChgScrOff);
         }
     }
@@ -544,8 +529,7 @@
         for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
             if (uidBatteryConsumer.getUid() == APP_UID1) {
                 assertUidBatteryConsumer(uidBatteryConsumer, 1200, "foo",
-                        1000, 1500, 500, 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
-                        BatteryConsumer.POWER_MODEL_POWER_PROFILE,
+                        1000, 1500, 500, 300, 400,
                         500, 600, 800,
                         true, 1777, 2388, 1999, 123, 1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
             } else {
@@ -596,8 +580,8 @@
     private void assertUidBatteryConsumer(UidBatteryConsumer uidBatteryConsumer,
             double consumedPower, String packageWithHighestDrain, int timeInProcessStateForeground,
             int timeInProcessStateBackground, int timeInProcessStateForegroundService,
-            int screenPower, int screenPowerModel, double cpuPower,
-            int cpuPowerModel, double customComponentPower, int cpuDuration,
+            int screenPower, double cpuPower,
+            double customComponentPower, int cpuDuration,
             int customComponentDuration, boolean processStateDataIncluded,
             double totalPowerForeground, double totalPowerBackground, double totalPowerFgs,
             double totalPowerCached, double cpuPowerForeground, int cpuDurationForeground,
@@ -620,12 +604,8 @@
                 PROCESS_STATE_FOREGROUND_SERVICE)).isEqualTo(timeInProcessStateForegroundService);
         assertThat(uidBatteryConsumer.getConsumedPower(
                 BatteryConsumer.POWER_COMPONENT_SCREEN)).isEqualTo(screenPower);
-        assertThat(uidBatteryConsumer.getPowerModel(
-                BatteryConsumer.POWER_COMPONENT_SCREEN)).isEqualTo(screenPowerModel);
         assertThat(uidBatteryConsumer.getConsumedPower(
                 BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower);
-        assertThat(uidBatteryConsumer.getPowerModel(
-                BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPowerModel);
         assertThat(uidBatteryConsumer.getConsumedPower(
                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower);
         assertThat(uidBatteryConsumer.getUsageDurationMillis(
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java
index fe6424f..c9cb0df 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java
@@ -82,16 +82,16 @@
 
         assertBluetoothPowerAndDuration(
                 mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID),
-                0.06944, 3000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.06944, 3000);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getUidBatteryConsumer(APP_UID),
-                0.19444, 9000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.19444, 9000);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getDeviceBatteryConsumer(),
-                0.26388, 12000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.26388, 12000);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getAppsBatteryConsumer(),
-                0.26388, 12000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.26388, 12000);
     }
 
     @Test
@@ -144,8 +144,6 @@
                 .isEqualTo(6166);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH))
                 .isWithin(PRECISION).of(0.1226666);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_BLUETOOTH))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         final BatteryConsumer.Key foreground = uidConsumer.getKey(
                 BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
@@ -178,16 +176,16 @@
 
         assertBluetoothPowerAndDuration(
                 mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID),
-                0.08216, 3583, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.08216, 3583);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getUidBatteryConsumer(APP_UID),
-                0.18169, 8416, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.18169, 8416);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getDeviceBatteryConsumer(),
-                0.30030, 12000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.30030, 12000);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getAppsBatteryConsumer(),
-                0.26386, 11999, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.26386, 11999);
     }
 
     @Test
@@ -202,16 +200,16 @@
 
         assertBluetoothPowerAndDuration(
                 mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID),
-                0.10378, 3583, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
+                0.10378, 3583);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getUidBatteryConsumer(APP_UID),
-                0.22950, 8416, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
+                0.22950, 8416);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getDeviceBatteryConsumer(),
-                0.33333, 12000, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
+                0.33333, 12000);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getAppsBatteryConsumer(),
-                0.33329, 11999, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
+                0.33329, 11999);
     }
 
     @Test
@@ -264,8 +262,6 @@
                 .isEqualTo(6166);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH))
                 .isWithin(PRECISION).of(0.8220561);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_BLUETOOTH))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         final BatteryConsumer.Key foreground = uidConsumer.getKey(
                 BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
@@ -299,16 +295,16 @@
 
         assertBluetoothPowerAndDuration(
                 mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID),
-                0.08216, 3583, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.08216, 3583);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getUidBatteryConsumer(APP_UID),
-                0.18169, 8416, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.18169, 8416);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getDeviceBatteryConsumer(),
-                0.26388, 12000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.26388, 12000);
         assertBluetoothPowerAndDuration(
                 mStatsRule.getAppsBatteryConsumer(),
-                0.26386, 11999, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                0.26386, 11999);
     }
 
     private void setupBluetoothEnergyInfo(long reportedEnergyUc, long consumedEnergyUc) {
@@ -326,14 +322,12 @@
     }
 
     private void assertBluetoothPowerAndDuration(@Nullable BatteryConsumer batteryConsumer,
-            double powerMah, int durationMs, @BatteryConsumer.PowerModel int powerModel) {
+            double powerMah, int durationMs) {
         assertThat(batteryConsumer).isNotNull();
 
         double consumedPower = batteryConsumer.getConsumedPower(
                 BatteryConsumer.POWER_COMPONENT_BLUETOOTH);
         assertThat(consumedPower).isWithin(PRECISION).of(powerMah);
-        assertThat(batteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_BLUETOOTH))
-                .isEqualTo(powerModel);
 
         long usageDurationMillis = batteryConsumer.getUsageDurationMillis(
                 BatteryConsumer.POWER_COMPONENT_BLUETOOTH);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java
index 7225f2d..4cd3857 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java
@@ -70,16 +70,12 @@
                 .isEqualTo(1000);
         assertThat(app1Consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isWithin(PRECISION).of(0.1);
-        assertThat(app1Consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         UidBatteryConsumer app2Consumer = mStatsRule.getUidBatteryConsumer(APP2_UID);
         assertThat(app2Consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isEqualTo(2000);
         assertThat(app2Consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isWithin(PRECISION).of(0.2);
-        assertThat(app2Consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceBatteryConsumer
@@ -87,8 +83,6 @@
                 .isEqualTo(3000);
         assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isWithin(PRECISION).of(0.3);
-        assertThat(deviceBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         final BatteryConsumer appsBatteryConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsBatteryConsumer
@@ -96,8 +90,6 @@
                 .isEqualTo(3000);
         assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isWithin(PRECISION).of(0.3);
-        assertThat(appsBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
     @Test
@@ -122,16 +114,12 @@
                 .isEqualTo(1000);
         assertThat(app1Consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isWithin(PRECISION).of(0.2);
-        assertThat(app1Consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         UidBatteryConsumer app2Consumer = mStatsRule.getUidBatteryConsumer(APP2_UID);
         assertThat(app2Consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isEqualTo(2000);
         assertThat(app2Consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isWithin(PRECISION).of(0.3);
-        assertThat(app2Consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceBatteryConsumer
@@ -139,8 +127,6 @@
                 .isEqualTo(3000);
         assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isWithin(PRECISION).of(0.5);
-        assertThat(deviceBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         final BatteryConsumer appsBatteryConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsBatteryConsumer
@@ -148,7 +134,5 @@
                 .isEqualTo(3000);
         assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
                 .isWithin(PRECISION).of(0.5);
-        assertThat(appsBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java
index 4cea728..527db67 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java
@@ -192,8 +192,6 @@
                 .isEqualTo(3333);
         assertThat(uidConsumer1.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU))
                 .isWithin(PRECISION).of(1.031677);
-        assertThat(uidConsumer1.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
         assertThat(uidConsumer1.getPackageWithHighestDrain()).isEqualTo("bar");
 
         UidBatteryConsumer uidConsumer2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
@@ -201,21 +199,15 @@
                 .isEqualTo(7777);
         assertThat(uidConsumer2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU))
                 .isWithin(PRECISION).of(2.489544);
-        assertThat(uidConsumer2.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
         assertThat(uidConsumer2.getPackageWithHighestDrain()).isNull();
 
         final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU))
                 .isWithin(PRECISION).of(3.52122);
-        assertThat(deviceBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         final BatteryConsumer appsBatteryConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU))
                 .isWithin(PRECISION).of(3.52122);
-        assertThat(appsBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
     @Test
@@ -264,8 +256,6 @@
                 .isEqualTo(3333);
         assertThat(uidConsumer1.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU))
                 .isWithin(PRECISION).of(3.18877);
-        assertThat(uidConsumer1.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
         assertThat(uidConsumer1.getPackageWithHighestDrain()).isEqualTo("bar");
 
         UidBatteryConsumer uidConsumer2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
@@ -273,21 +263,15 @@
                 .isEqualTo(7777);
         assertThat(uidConsumer2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU))
                 .isWithin(PRECISION).of(7.44072);
-        assertThat(uidConsumer2.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
         assertThat(uidConsumer2.getPackageWithHighestDrain()).isNull();
 
         final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU))
                 .isWithin(PRECISION).of(10.62949);
-        assertThat(deviceBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         final BatteryConsumer appsBatteryConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU))
                 .isWithin(PRECISION).of(10.62949);
-        assertThat(appsBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 
     @Test
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java
index 3b5658c..506bab4 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java
@@ -68,20 +68,14 @@
                 .isEqualTo(1000);
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
                 .isWithin(PRECISION).of(0.1);
-        assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
                 .isWithin(PRECISION).of(0.1);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
                 .isWithin(PRECISION).of(0.1);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
     @Test
@@ -107,27 +101,19 @@
                 .isEqualTo(1000);
         assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
                 .isWithin(PRECISION).of(2.77777);
-        assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         UidBatteryConsumer consumer2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(consumer2.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_GNSS))
                 .isEqualTo(2000);
         assertThat(consumer2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
                 .isWithin(PRECISION).of(5.55555);
-        assertThat(consumer2.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
                 .isWithin(PRECISION).of(8.333333);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
                 .isWithin(PRECISION).of(8.333333);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java
index 9b810bc..eba820e 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java
@@ -164,8 +164,6 @@
         // =    4604000 mA-ms or 1.27888 mA-h
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.27888);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         //    720 mA * 100 ms  (level 0 TX drain rate * level 0 TX duration)
         // + 1080 mA * 200 ms  (level 1 TX drain rate * level 1 TX duration)
@@ -178,22 +176,16 @@
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(0.94);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         // 3/4 of total packets were sent by APP_UID so 75% of total
         UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(0.705);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         // Rest should go to the other app
         UidBatteryConsumer uidConsumer2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uidConsumer2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(0.235);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
     @Test
@@ -321,8 +313,6 @@
         // =    5177753 mA-ms or 1.43826 mA-h total consumption
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.43826);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         //    720 mA * 100 ms  (level 0 TX drain rate * level 0 TX duration)
         // + 1080 mA * 200 ms  (level 1 TX drain rate * level 1 TX duration)
@@ -335,22 +325,16 @@
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.09938);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         // 3/4 of total packets were sent by APP_UID so 75% of total
         UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(0.82453);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         // Rest should go to the other app
         UidBatteryConsumer uidConsumer2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uidConsumer2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(0.27484);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
     @Test
@@ -441,8 +425,6 @@
         // =    4604000 mA-ms or 1.27888 mA-h
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.27888);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         //    720 mA * 100 ms  (level 0 TX drain rate * level 0 TX duration)
         // + 1080 mA * 200 ms  (level 1 TX drain rate * level 1 TX duration)
@@ -455,22 +437,16 @@
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(0.94);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         // 3/4 of total packets were sent by APP_UID so 75% of total
         UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(0.705);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         // Rest should go to the other app
         UidBatteryConsumer uidConsumer2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uidConsumer2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(0.235);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
     @Test
@@ -648,24 +624,16 @@
         // 200ms phone on duration / 2000 total duration *  2.77778 mAh = 0.27777
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(2.5);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE))
                 .isWithin(PRECISION).of(0.27778);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_PHONE))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.38541);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.38541);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 
     @Test
@@ -782,12 +750,8 @@
         // 1000ms phone on duration / 10000 total duration *  2.77778 mAh = 0.27777
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(2.5);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE))
                 .isWithin(PRECISION).of(0.27778);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_PHONE))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         // CDMA2000 [Tx0, Tx1, Tx2, Tx3, Tx4, Rx] drain * duration
         //   [720, 1080, 1440, 1800, 2160, 1440] mA . [10, 11, 12, 13, 14, 15] ms = 111600 mA-ms
@@ -817,8 +781,6 @@
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.91094);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         // 240 ms Rx Time, 1110 ms Tx Time, 1350 ms active time
         // 150 App 1 Rx Packets, 10 App 1 Tx packets
@@ -841,15 +803,11 @@
         UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.27574);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         // Rest should go to the other app
         UidBatteryConsumer uidConsumer2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uidConsumer2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(0.63520);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 
     @Test
@@ -936,12 +894,8 @@
         // 1000ms phone on duration / 10000 total duration *  2.77778 mAh = 0.27777
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(2.5);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE))
                 .isWithin(PRECISION).of(0.27778);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_PHONE))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         // Estimated Rx/Tx modem consumption = 0.94 mAh
@@ -949,14 +903,10 @@
         // 2.5 * 0.94 / 1.27888 = 1.83754 mAh
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.83754);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                 .isWithin(PRECISION).of(1.83754);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 
     @Test
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java
index 2da98e8..7f20035 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java
@@ -104,8 +104,6 @@
         // Uid1 charge = 200000000 + 5 / 45 * 300000000 mAs = 64.81 mAh
         assertThat(uid1.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(64.81481);
-        assertThat(uid1.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         UidBatteryConsumer uid2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uid2.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
@@ -116,8 +114,6 @@
         // Uid2 charge = 40 / 45 * 300000000 + 100000000 mAs = 101.85 mAh
         assertThat(uid2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(101.85185);
-        assertThat(uid2.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
@@ -126,8 +122,6 @@
         // 600000000 uAs * (1 mA / 1000 uA) * (1 h / 3600 s)  = 166.66666 mAh
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(166.66666);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
@@ -135,11 +129,8 @@
 
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(166.66666);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 
-
     @Test
     public void testMeasuredEnergyBasedModel_multiDisplay() {
         mStatsRule.initMeasuredEnergyStatsLocked()
@@ -202,8 +193,6 @@
         // (600000000 + 800000000) uAs * (1 mA / 1000 uA) * (1 h / 3600 s)  = 166.66666 mAh
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(388.88888);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         UidBatteryConsumer uid1 = mStatsRule.getUidBatteryConsumer(APP_UID1);
         assertThat(uid1.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
@@ -214,8 +203,6 @@
         // Uid1 charge = 20 / 80 * 600000000 mAs = 41.66666 mAh
         assertThat(uid1.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(41.66666);
-        assertThat(uid1.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         UidBatteryConsumer uid2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uid2.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
@@ -226,17 +213,12 @@
         // Uid1 charge = 60 / 80 * 600000000 + 800000000 mAs = 347.22222 mAh
         assertThat(uid2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(347.22222);
-        assertThat(uid2.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isEqualTo(110 * MINUTE_IN_MS);
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(388.88888);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
-
     }
 
     @Test
@@ -277,8 +259,6 @@
         // Uid1 charge = 20 / 80 * 92.0 = 23.0 mAh
         assertThat(uid1.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(23.0);
-        assertThat(uid1.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         UidBatteryConsumer uid2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uid2.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
@@ -288,27 +268,20 @@
         // Uid2 charge = 60 / 80 * 92.0 = 69.0 mAh
         assertThat(uid2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(69.0);
-        assertThat(uid2.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isEqualTo(80 * MINUTE_IN_MS);
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(92);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isEqualTo(80 * MINUTE_IN_MS);
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(92);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
-
     @Test
     public void testPowerProfileBasedModel_multiDisplay() {
         mStatsRule.setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_ON, 1, 60.0)
@@ -364,8 +337,6 @@
         // 92 + 60 * 0.5 + 10 * 0.1 + 90 * 0.2 + 30 * 0.2 = 147
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(147);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         UidBatteryConsumer uid1 = mStatsRule.getUidBatteryConsumer(APP_UID1);
         assertThat(uid1.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
@@ -375,8 +346,6 @@
         // Uid1 charge = 20 / 110 * 147.0 = 23.0 mAh
         assertThat(uid1.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(26.72727);
-        assertThat(uid1.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         UidBatteryConsumer uid2 = mStatsRule.getUidBatteryConsumer(APP_UID2);
         assertThat(uid2.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
@@ -386,17 +355,12 @@
         // Uid2 charge = 90 / 110 * 92.0 = 69.0 mAh
         assertThat(uid2.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(120.272727);
-        assertThat(uid2.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
         assertThat(appsConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isEqualTo(110 * MINUTE_IN_MS);
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
                 .isWithin(PRECISION).of(147);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
-
     }
 
     private void setProcState(int uid, int procState, boolean resumed, long realtimeMs,
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java
index 8e221be..827d2f8 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java
@@ -159,22 +159,16 @@
                 .isEqualTo(2473);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(0.3964);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isEqualTo(4001);
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(0.86666);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         BatteryConsumer appsConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(0.866666);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
     @Test
@@ -214,8 +208,6 @@
                 .isEqualTo(12423);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(2.0214666);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
 
         final BatteryConsumer.Key foreground = uidConsumer.getKey(
                 BatteryConsumer.POWER_COMPONENT_WIFI,
@@ -248,22 +240,16 @@
         /* Same ratio as in testPowerControllerBasedModel_nonMeasured but scaled by 1_000_000uC. */
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(0.2214666 / (0.2214666 + 0.645200) * 1_000_000 / 3600000);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isEqualTo(4002);
         assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(0.27777);
-        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         BatteryConsumer appsConsumer = mStatsRule.getDeviceBatteryConsumer();
         assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(0.277777);
-        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 
     @Test
@@ -302,8 +288,6 @@
                 .isEqualTo(12423);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(1.0325211);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
 
         final BatteryConsumer.Key foreground = uidConsumer.getKey(
                 BatteryConsumer.POWER_COMPONENT_WIFI,
@@ -349,8 +333,6 @@
                 .isEqualTo(1000);
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(0.8231573);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
     }
 
     @Test
@@ -371,8 +353,6 @@
         /* Same ratio as in testTimerBasedModel_nonMeasured but scaled by 1_000_000uC. */
         assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
                 .isWithin(PRECISION).of(0.8231573 / (0.8231573 + 0.8759216) * 1_000_000 / 3600000);
-        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
-                .isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
     }
 
     private WifiActivityEnergyInfo buildWifiActivityEnergyInfo(long timeSinceBoot,
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BasePowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BasePowerStatsProcessorTest.java
index f7a1638..cca6033 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BasePowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BasePowerStatsProcessorTest.java
@@ -176,7 +176,6 @@
                 powerStatsAggregator, /* batterySessionTimeSpanSlackMillis */ 0);
 
         BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(new String[0],
-                /* includePowerModels */ false,
                 /* includeProcessStateData */ true,
                 /* includeScreenStateData */ true,
                 /* includesPowerStateData */ true,
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
index 4643ddd..38fe613 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
@@ -342,7 +342,7 @@
         PowerStatsExporter exporter = new PowerStatsExporter(mPowerStatsStore,
                 mPowerStatsAggregator, /* batterySessionTimeSpanSlackMillis */ 0);
 
-        BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(new String[0], false,
+        BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(new String[0],
                 includeProcessStateData, includeScreenStateData, includesPowerStateData, 0);
         exporter.populateBatteryUsageStatsBuilder(builder, aps);
         return builder.build();
@@ -361,7 +361,7 @@
     private void breakdownByProcState_fullRange(boolean includeScreenStateData,
             boolean includePowerStateData) throws Exception {
         BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
-                new String[]{"cu570m"}, /* includePowerModels */ false,
+                new String[]{"cu570m"},
                 /* includeProcessStateData */ true, includeScreenStateData,
                 includePowerStateData, /* powerThreshold */ 0);
         exportAggregatedPowerStats(builder, 1000, 10000);
@@ -406,7 +406,7 @@
     @Test
     public void breakdownByProcState_subRange() throws Exception {
         BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
-                new String[]{"cu570m"}, /* includePowerModels */ false,
+                new String[]{"cu570m"},
                 /* includeProcessStateData */ true, true, true, /* powerThreshold */ 0);
         exportAggregatedPowerStats(builder, 3700, 6700);
 
@@ -438,7 +438,7 @@
     @Test
     public void combinedProcessStates() throws Exception {
         BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
-                new String[]{"cu570m"}, /* includePowerModels */ false,
+                new String[]{"cu570m"},
                 /* includeProcessStateData */ false, true, true, /* powerThreshold */ 0);
         exportAggregatedPowerStats(builder, 1000, 10000);
 
diff --git a/services/tests/security/intrusiondetection/AndroidManifest.xml b/services/tests/security/intrusiondetection/AndroidManifest.xml
index f388e7e..39e41cd 100644
--- a/services/tests/security/intrusiondetection/AndroidManifest.xml
+++ b/services/tests/security/intrusiondetection/AndroidManifest.xml
@@ -18,10 +18,19 @@
   package="com.android.server.security.intrusiondetection.tests">
 
        <uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING"     />
-       <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
+       <uses-permission android:name="android.permission.INTERNET"/>
 
-    <application android:testOnly="true">
+    <application android:testOnly="true" android:debuggable="true" android:usesCleartextTraffic="true">
       <uses-library android:name="android.test.runner"/>
+        <receiver android:name="com.android.server.security.intrusiondetection.IntrusionDetectionAdminReceiver"
+             android:permission="android.permission.BIND_DEVICE_ADMIN"
+             android:exported="true">
+            <meta-data android:name="android.app.device_admin"
+                 android:resource="@xml/device_admin"/>
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
+            </intent-filter>
+        </receiver>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/packages/BackupRestoreConfirmation/res/values/styles.xml b/services/tests/security/intrusiondetection/res/xml/device_admin.xml
similarity index 66%
rename from packages/BackupRestoreConfirmation/res/values/styles.xml
rename to services/tests/security/intrusiondetection/res/xml/device_admin.xml
index ce54568..f8cd8f0 100644
--- a/packages/BackupRestoreConfirmation/res/values/styles.xml
+++ b/services/tests/security/intrusiondetection/res/xml/device_admin.xml
@@ -14,11 +14,5 @@
      limitations under the License.
 -->
 
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <!--
-        TODO(b/309578419): Make activities handle insets properly and then remove this.
-    -->
-    <style name="OptOutEdgeToEdgeEnforcement">
-        <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
-    </style>
-</resources>
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
+</device-admin>
diff --git a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
index bc854cf..c185ad5 100644
--- a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
@@ -16,14 +16,19 @@
 
 package com.android.server.security.intrusiondetection;
 
+import static android.Manifest.permission.INTERNET;
 import static android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE;
 import static android.Manifest.permission.READ_INTRUSION_DETECTION_STATE;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
@@ -33,7 +38,9 @@
 import android.annotation.SuppressLint;
 import android.app.admin.ConnectEvent;
 import android.app.admin.DnsEvent;
+import android.app.admin.SecurityLog;
 import android.app.admin.SecurityLog.SecurityEvent;
+import android.content.ComponentName;
 import android.content.Context;
 import android.os.Looper;
 import android.os.PermissionEnforcer;
@@ -43,19 +50,44 @@
 import android.security.intrusiondetection.IIntrusionDetectionServiceCommandCallback;
 import android.security.intrusiondetection.IIntrusionDetectionServiceStateCallback;
 import android.security.intrusiondetection.IntrusionDetectionEvent;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
 
 import androidx.test.core.app.ApplicationProvider;
 
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.annotations.AfterClass;
+import com.android.bedstead.harrier.annotations.BeforeClass;
+import com.android.bedstead.multiuser.annotations.RequireRunOnSystemUser;
+import com.android.bedstead.nene.TestApis;
+import com.android.bedstead.nene.devicepolicy.DeviceOwner;
+import com.android.bedstead.nene.exceptions.NeneException;
+import com.android.bedstead.permissions.CommonPermissions;
+import com.android.bedstead.permissions.PermissionContext;
+import com.android.bedstead.permissions.annotations.EnsureHasPermission;
 import com.android.server.ServiceThread;
 
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
+@RunWith(BedsteadJUnit4.class)
 public class IntrusionDetectionServiceTest {
     private static final int STATE_UNKNOWN =
             IIntrusionDetectionServiceStateCallback.State.UNKNOWN;
@@ -73,6 +105,8 @@
     private static final int ERROR_DATA_SOURCE_UNAVAILABLE =
             IIntrusionDetectionServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
 
+    private static DeviceOwner sDeviceOwner;
+
     private Context mContext;
     private IntrusionDetectionEventTransportConnection mIntrusionDetectionEventTransportConnection;
     private DataAggregator mDataAggregator;
@@ -83,6 +117,28 @@
     private Looper mLooperOfDataAggregator;
     private FakePermissionEnforcer mPermissionEnforcer;
 
+    @BeforeClass
+    public static void setDeviceOwner() {
+        ComponentName admin =
+                new ComponentName(
+                        ApplicationProvider.getApplicationContext(),
+                        IntrusionDetectionAdminReceiver.class);
+        try {
+            sDeviceOwner = TestApis.devicePolicy().setDeviceOwner(admin);
+        } catch (NeneException e) {
+            fail("Failed to set device owner " + admin.flattenToString() + ": " + e);
+        }
+    }
+
+    @AfterClass
+    public static void removeDeviceOwner() {
+        try {
+            sDeviceOwner.remove();
+        } catch (NeneException e) {
+            fail("Failed to remove device owner : " + e);
+        }
+    }
+
     @SuppressLint("VisibleForTests")
     @Before
     public void setUp() {
@@ -343,6 +399,172 @@
         assertNotNull(receivedEvents.get(2).getDnsEvent());
     }
 
+    @Test
+    @RequireRunOnSystemUser
+    public void testDataSources_Initialize_HasDeviceOwner() throws Exception {
+        NetworkLogSource networkLogSource = new NetworkLogSource(mContext, mDataAggregator);
+        SecurityLogSource securityLogSource = new SecurityLogSource(mContext, mDataAggregator);
+
+        assertTrue(networkLogSource.initialize());
+        assertTrue(securityLogSource.initialize());
+    }
+
+    @Test
+    @RequireRunOnSystemUser
+    public void testDataSources_Initialize_NoDeviceOwner() throws Exception {
+        NetworkLogSource networkLogSource = new NetworkLogSource(mContext, mDataAggregator);
+        SecurityLogSource securityLogSource = new SecurityLogSource(mContext, mDataAggregator);
+        ComponentName admin = sDeviceOwner.componentName();
+
+        try {
+            sDeviceOwner.remove();
+            assertFalse(networkLogSource.initialize());
+            assertFalse(securityLogSource.initialize());
+        } finally {
+            sDeviceOwner = TestApis.devicePolicy().setDeviceOwner(admin);
+        }
+    }
+
+    @Test
+    @RequireRunOnSystemUser
+    @EnsureHasPermission(CommonPermissions.MANAGE_DEVICE_POLICY_AUDIT_LOGGING)
+    public void testDataAggregator_AddSecurityEvent() throws Exception {
+        mIntrusionDetectionService.setState(STATE_ENABLED);
+        ServiceThread mockThread = spy(ServiceThread.class);
+        mDataAggregator.setHandler(mLooperOfDataAggregator, mockThread);
+        assertTrue(mDataAggregator.initialize());
+
+        // SecurityLogging generates a number of events and callbacks, so create a latch to wait for
+        // the given event.
+        String eventString = this.getClass().getName() + ".testSecurityEvent";
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        // TODO: Replace this mock when the IntrusionDetectionEventTransportConnection is ready.
+        doAnswer(
+                    new Answer<Boolean>() {
+                        @Override
+                        public Boolean answer(InvocationOnMock input) {
+                            List<IntrusionDetectionEvent> receivedEvents =
+                                    (List<IntrusionDetectionEvent>) input.getArguments()[0];
+                            for (IntrusionDetectionEvent event : receivedEvents) {
+                                if (event.getType() == IntrusionDetectionEvent.SECURITY_EVENT) {
+                                    SecurityEvent securityEvent = event.getSecurityEvent();
+                                    Object[] eventData = (Object[]) securityEvent.getData();
+                                    if (securityEvent.getTag() == SecurityLog.TAG_KEY_GENERATED
+                                            && eventData[1].equals(eventString)) {
+                                        latch.countDown();
+                                    }
+                                }
+                            }
+                            return true;
+                        }
+                    })
+            .when(mIntrusionDetectionEventTransportConnection).addData(any());
+        mDataAggregator.enable();
+
+        // Generate the security event.
+        generateSecurityEvent(eventString);
+        TestApis.devicePolicy().forceSecurityLogs();
+
+        // Verify the event is received.
+        mTestLooper.startAutoDispatch();
+        assertTrue(latch.await(1, TimeUnit.SECONDS));
+        mTestLooper.stopAutoDispatch();
+
+        mDataAggregator.disable();
+    }
+
+    @Test
+    @RequireRunOnSystemUser
+    @EnsureHasPermission(CommonPermissions.MANAGE_DEVICE_POLICY_AUDIT_LOGGING)
+    public void testDataAggregator_AddNetworkEvent() throws Exception {
+        mIntrusionDetectionService.setState(STATE_ENABLED);
+        ServiceThread mockThread = spy(ServiceThread.class);
+        mDataAggregator.setHandler(mLooperOfDataAggregator, mockThread);
+        assertTrue(mDataAggregator.initialize());
+
+        // Network logging may log multiple and callbacks, so create a latch to wait for
+        // the given event.
+        // eventServer must be a valid domain to generate a network log event.
+        String eventServer = "google.com";
+        final CountDownLatch latch = new CountDownLatch(1);
+        // TODO: Replace this mock when the IntrusionDetectionEventTransportConnection is ready.
+        doAnswer(
+                    new Answer<Boolean>() {
+                        @Override
+                        public Boolean answer(InvocationOnMock input) {
+                            List<IntrusionDetectionEvent> receivedEvents =
+                                    (List<IntrusionDetectionEvent>) input.getArguments()[0];
+                            for (IntrusionDetectionEvent event : receivedEvents) {
+                                if (event.getType()
+                                        == IntrusionDetectionEvent.NETWORK_EVENT_DNS) {
+                                    DnsEvent dnsEvent = event.getDnsEvent();
+                                    if (dnsEvent.getHostname().equals(eventServer)) {
+                                        latch.countDown();
+                                    }
+                                }
+                            }
+                            return true;
+                        }
+                    })
+            .when(mIntrusionDetectionEventTransportConnection).addData(any());
+        mDataAggregator.enable();
+
+        // Generate the network event.
+        generateNetworkEvent(eventServer);
+        TestApis.devicePolicy().forceNetworkLogs();
+
+        // Verify the event is received.
+        mTestLooper.startAutoDispatch();
+        assertTrue(latch.await(1, TimeUnit.SECONDS));
+        mTestLooper.stopAutoDispatch();
+
+        mDataAggregator.disable();
+    }
+
+    /** Emits a given string into security log (if enabled). */
+    private void generateSecurityEvent(String eventString)
+            throws IllegalArgumentException, GeneralSecurityException, IOException {
+        if (eventString == null || eventString.isEmpty()) {
+            throw new IllegalArgumentException(
+                    "Error generating security event: eventString must not be empty");
+        }
+
+        final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
+        keyGen.initialize(
+                new KeyGenParameterSpec.Builder(eventString, KeyProperties.PURPOSE_SIGN).build());
+        // Emit key generation event.
+        final KeyPair keyPair = keyGen.generateKeyPair();
+        assertNotNull(keyPair);
+
+        final KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
+        ks.load(null);
+        // Emit key destruction event.
+        ks.deleteEntry(eventString);
+    }
+
+    /** Emits a given string into network log (if enabled). */
+    private void generateNetworkEvent(String server) throws IllegalArgumentException, IOException {
+        if (server == null || server.isEmpty()) {
+            throw new IllegalArgumentException(
+                    "Error generating network event: server must not be empty");
+        }
+
+        HttpURLConnection urlConnection = null;
+        int connectionTimeoutMS = 2_000;
+        try (PermissionContext p = TestApis.permissions().withPermission(INTERNET)) {
+            final URL url = new URL("http://" + server);
+            urlConnection = (HttpURLConnection) url.openConnection();
+            urlConnection.setConnectTimeout(connectionTimeoutMS);
+            urlConnection.setReadTimeout(connectionTimeoutMS);
+            urlConnection.getResponseCode();
+        } finally {
+            if (urlConnection != null) {
+                urlConnection.disconnect();
+            }
+        }
+    }
+
     private class MockInjector implements IntrusionDetectionService.Injector {
         private final Context mContext;
 
diff --git a/services/tests/servicestests/jni/Android.bp b/services/tests/servicestests/jni/Android.bp
index 0a31037..e738c19 100644
--- a/services/tests/servicestests/jni/Android.bp
+++ b/services/tests/servicestests/jni/Android.bp
@@ -22,9 +22,9 @@
     srcs: [
         ":lib_cachedAppOptimizer_native",
         ":lib_freezer_native",
-        ":lib_gameManagerService_native",
         ":lib_oomConnection_native",
         ":lib_anrTimer_native",
+        ":lib_lazilyRegisteredServices_native",
         "onload.cpp",
     ],
 
@@ -55,6 +55,8 @@
         "android.hardware.graphics.bufferqueue@2.0",
         "android.hardware.graphics.common@1.2",
         "android.hardware.graphics.mapper@4.0",
+        "android.hardware.ir@1.0",
+        "android.hardware.vr@1.0",
         "android.hidl.token@1.0-utils",
     ],
 }
diff --git a/services/tests/servicestests/jni/onload.cpp b/services/tests/servicestests/jni/onload.cpp
index 25487c5..ad979c6 100644
--- a/services/tests/servicestests/jni/onload.cpp
+++ b/services/tests/servicestests/jni/onload.cpp
@@ -25,9 +25,9 @@
 
 namespace android {
 int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
-int register_android_server_app_GameManagerService(JNIEnv* env);
 int register_android_server_am_OomConnection(JNIEnv* env);
 int register_android_server_utils_AnrTimer(JNIEnv *env);
+int register_android_server_utils_LazyJniRegistrar(JNIEnv* env);
 };
 
 using namespace android;
@@ -43,8 +43,8 @@
     }
     ALOG_ASSERT(env, "Could not retrieve the env!");
     register_android_server_am_CachedAppOptimizer(env);
-    register_android_server_app_GameManagerService(env);
     register_android_server_am_OomConnection(env);
     register_android_server_utils_AnrTimer(env);
+    register_android_server_utils_LazyJniRegistrar(env);
     return JNI_VERSION_1_4;
 }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index d5b9307..27de764 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -38,7 +38,6 @@
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity.EXTRA_TYPE_TO_CHOOSE;
 import static com.android.server.accessibility.AccessibilityManagerService.ACTION_LAUNCH_HEARING_DEVICES_DIALOG;
-import static com.android.window.flags.Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -601,7 +600,6 @@
     }
 
     @Test
-    @EnableFlags(FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER)
     public void testSetConnectionNull_borderFlagEnabled_unregisterFullScreenMagnification()
             throws RemoteException {
         mFakePermissionEnforcer.grant(Manifest.permission.STATUS_BAR_SERVICE);
@@ -1136,7 +1134,6 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_ENABLE_HARDWARE_SHORTCUT_DISABLES_WARNING)
     public void enableHardwareShortcutsForTargets_shortcutDialogSetting_isShown() {
         // TODO(b/111889696): Remove the user 0 assumption once we support multi-user
         assumeTrue("The test is setup to run as a user 0",
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index 403930d..2ae31ad 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -18,20 +18,24 @@
 
 import static com.android.server.accessibility.AbstractAccessibilityServiceConnection.DISPLAY_TYPE_DEFAULT;
 import static com.android.server.accessibility.AccessibilityWindowManagerTest.DisplayIdMatcher.displayId;
+import static com.android.server.accessibility.AccessibilityWindowManagerTest.EventWindowIdMatcher.eventWindowId;
 import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowChangesMatcher.a11yWindowChanges;
-import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowIdMatcher.a11yWindowId;
+import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowIdMatcher.windowId;
 
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
@@ -42,14 +46,13 @@
 import static org.mockito.Mockito.when;
 
 import android.annotation.Nullable;
+import android.graphics.Point;
+import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.IBinder;
 import android.os.LocaleList;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.IWindow;
@@ -63,6 +66,7 @@
 
 import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
 import com.android.server.accessibility.test.MessageCapturingHandler;
+import com.android.server.wm.AccessibilityWindowsPopulator.AccessibilityWindow;
 import com.android.server.wm.WindowManagerInternal;
 import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback;
 
@@ -70,7 +74,6 @@
 import org.hamcrest.TypeSafeMatcher;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
@@ -81,17 +84,9 @@
 import java.util.Arrays;
 import java.util.List;
 
-// This test verifies deprecated codepath. Probably changing this file means
-// AccessibilityWindowManagerWithAccessibilityWindowTest also needs to be updated.
-// LINT.IfChange
-
 /**
- * Tests for the AccessibilityWindowManager with Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2
- * enabled.
- * TODO(b/322444245): Merge with AccessibilityWindowManagerWithAccessibilityWindowTest
- *  after completing the flag migration.
+ * Tests for the AccessibilityWindowManager.
  */
-@RequiresFlagsDisabled(Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2)
 public class AccessibilityWindowManagerTest {
     private static final String PACKAGE_NAME = "com.android.server.accessibility";
     private static final boolean FORCE_SEND = true;
@@ -122,9 +117,8 @@
 
     // List of window token, mapping from windowId -> window token.
     private final SparseArray<IWindow> mA11yWindowTokens = new SparseArray<>();
-    // List of window info lists, mapping from displayId -> window info lists.
-    private final SparseArray<ArrayList<WindowInfo>> mWindowInfos =
-            new SparseArray<>();
+    // List of window info lists, mapping from displayId -> a11y window lists.
+    private final SparseArray<ArrayList<AccessibilityWindow>> mWindows = new SparseArray<>();
     // List of callback, mapping from displayId -> callback.
     private final SparseArray<WindowsForAccessibilityCallback> mCallbackOfWindows =
             new SparseArray<>();
@@ -134,6 +128,13 @@
 
     private final MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
 
+    // This maps displayId -> next region offset.
+    // Touchable region must have un-occluded area so that it's exposed to a11y services.
+    // This offset can be used as left and top of new region so that top-left of each region are
+    // kept visible.
+    // It's expected to be incremented by some amount everytime the value is used.
+    private final SparseArray<Integer> mNextRegionOffsets = new SparseArray<>();
+
     @Mock private WindowManagerInternal mMockWindowManagerInternal;
     @Mock private AccessibilityWindowManager.AccessibilityEventSender mMockA11yEventSender;
     @Mock private AccessibilitySecurityPolicy mMockA11ySecurityPolicy;
@@ -144,9 +145,6 @@
     @Mock private IBinder mMockEmbeddedToken;
     @Mock private IBinder mMockInvalidToken;
 
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
     @Before
     public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
@@ -159,7 +157,7 @@
                 anyString(), anyInt(), anyInt(), anyInt())).thenReturn(PACKAGE_NAME);
 
         doAnswer((invocation) -> {
-            onWindowsForAccessibilityChanged(invocation.getArgument(0), false);
+            onAccessibilityWindowsChanged(invocation.getArgument(0), false);
             return null;
         }).when(mMockWindowManagerInternal).computeWindowsForAccessibility(anyInt());
 
@@ -173,7 +171,7 @@
         // as top focused display before each testing starts.
         startTrackingPerDisplay(Display.DEFAULT_DISPLAY);
 
-        // AccessibilityEventSender is invoked during onWindowsForAccessibilityChanged.
+        // AccessibilityEventSender is invoked during onAccessibilityWindowsChanged.
         // Resets it for mockito verify of further test case.
         Mockito.reset(mMockA11yEventSender);
 
@@ -237,19 +235,18 @@
     @Test
     public void onWindowsChanged_duringTouchInteractAndFocusChange_shouldChangeActiveWindow() {
         final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        WindowInfo focusedWindowInfo =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX);
+        final WindowInfo focusedWindowInfo =
+                mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
         assertEquals(activeWindowId, mA11yWindowManager.findWindowIdLocked(
                 USER_SYSTEM_ID, focusedWindowInfo.token));
 
         focusedWindowInfo.focused = false;
-        focusedWindowInfo =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX + 1);
-        focusedWindowInfo.focused = true;
+        mWindows.get(Display.DEFAULT_DISPLAY).get(
+                DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().focused = true;
 
         mA11yWindowManager.onTouchInteractionStart();
         setTopFocusedWindowAndDisplay(Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX + 1);
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
     }
@@ -273,7 +270,7 @@
         changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
                 DEFAULT_FOCUSED_INDEX + 1, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
 
-        onWindowsForAccessibilityChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
         // The active window should not be changed.
         assertEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
         // The top focused window should not be changed.
@@ -301,8 +298,8 @@
         changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
                 DEFAULT_FOCUSED_INDEX, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        onWindowsForAccessibilityChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
         // The active window should be changed.
         assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
         // The top focused window should be changed.
@@ -312,53 +309,181 @@
 
     @Test
     public void onWindowsChanged_shouldReportCorrectLayer() {
-        // AccessibilityWindowManager#onWindowsForAccessibilityChanged already invoked in setup.
+        // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
         List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
         for (int i = 0; i < a11yWindows.size(); i++) {
             final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
-            final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(i);
-            assertThat(mWindowInfos.get(Display.DEFAULT_DISPLAY).size() - windowInfo.layer - 1,
+            assertThat(mWindows.get(Display.DEFAULT_DISPLAY).size() - i - 1,
                     is(a11yWindow.getLayer()));
         }
     }
 
     @Test
     public void onWindowsChanged_shouldReportCorrectOrder() {
-        // AccessibilityWindowManager#onWindowsForAccessibilityChanged already invoked in setup.
+        // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
         List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
         for (int i = 0; i < a11yWindows.size(); i++) {
             final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
             final IBinder windowToken = mA11yWindowManager
                     .getWindowTokenForUserAndWindowIdLocked(USER_SYSTEM_ID, a11yWindow.getId());
-            final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(i);
+            final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY)
+                    .get(i).getWindowInfo();
             assertThat(windowToken, is(windowInfo.token));
         }
     }
 
     @Test
-    public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
-        final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        final int correctLayer =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer();
-        windowInfo.layer += 1;
+    public void onWindowsChanged_shouldNotReportNonTouchableWindow() {
+        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        when(window.isTouchable()).thenReturn(false);
+        final int windowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, window.getWindowInfo().token);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-        assertNotEquals(correctLayer,
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer());
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, not(hasItem(windowId(windowId))));
     }
 
     @Test
-    public void onWindowsChangedNoForceSend_layerChanged_shouldNotUpdateWindows() {
-        final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        final int correctLayer =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer();
-        windowInfo.layer += 1;
+    public void onWindowsChanged_shouldReportFocusedNonTouchableWindow() {
+        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
+                DEFAULT_FOCUSED_INDEX);
+        when(window.isTouchable()).thenReturn(false);
+        final int windowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, window.getWindowInfo().token);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        assertEquals(correctLayer,
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer());
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasItem(windowId(windowId)));
+    }
+
+    @Test
+    public void onWindowsChanged_trustedFocusedNonTouchableWindow_shouldNotHideWindowsBelow() {
+        // Make the focused trusted un-touchable window fullscreen.
+        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
+                DEFAULT_FOCUSED_INDEX);
+        setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+        when(window.isTouchable()).thenReturn(false);
+        when(window.isTrustedOverlay()).thenReturn(true);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
+    }
+
+    @Test
+    public void onWindowsChanged_accessibilityOverlay_shouldNotHideWindowsBelow() {
+        // Make the a11y overlay window fullscreen.
+        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+        when(window.getType()).thenReturn(WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
+    }
+
+    @Test
+    public void onWindowsChanged_shouldReportFocusedWindowEvenIfOccluded() {
+        // Make the front window fullscreen.
+        final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(frontWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+        final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
+
+        final AccessibilityWindow focusedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(
+                DEFAULT_FOCUSED_INDEX);
+        final int focusedWindowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, focusedWindow.getWindowInfo().token);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(2));
+        assertThat(a11yWindows.get(0), windowId(frontWindowId));
+        assertThat(a11yWindows.get(1), windowId(focusedWindowId));
+    }
+
+    @Test
+    public void onWindowsChanged_embeddedWindows_shouldOnlyReportHost() throws RemoteException {
+        final Rect embeddingBounds = new Rect(0, 0, 200, 100);
+
+        // The embedded window comes front of the host window.
+        final IBinder embeddedWindowLeashToken = Mockito.mock(IBinder.class);
+        final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
+                false, embeddedWindowLeashToken, USER_SYSTEM_ID);
+        final AccessibilityWindow embeddedWindow = createMockAccessibilityWindow(
+                mA11yWindowTokens.get(embeddedWindowId), Display.DEFAULT_DISPLAY);
+        setRegionForMockAccessibilityWindow(embeddedWindow, new Region(embeddingBounds));
+        mWindows.get(Display.DEFAULT_DISPLAY).set(0, embeddedWindow);
+
+        final IBinder hostWindowLeashToken = Mockito.mock(IBinder.class);
+        final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
+                false, hostWindowLeashToken, USER_SYSTEM_ID);
+        final AccessibilityWindow hostWindow = createMockAccessibilityWindow(
+                mA11yWindowTokens.get(hostWindowId), Display.DEFAULT_DISPLAY);
+        setRegionForMockAccessibilityWindow(hostWindow, new Region(embeddingBounds));
+        mWindows.get(Display.DEFAULT_DISPLAY).set(1, hostWindow);
+
+        mA11yWindowManager.associateEmbeddedHierarchyLocked(
+                hostWindowLeashToken, embeddedWindowLeashToken);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, not(hasItem(windowId(embeddedWindowId))));
+        assertThat(a11yWindows.get(0), windowId(hostWindowId));
+        final Rect bounds = new Rect();
+        a11yWindows.get(0).getBoundsInScreen(bounds);
+        assertEquals(bounds, embeddingBounds);
+    }
+
+    @Test
+    public void onWindowsChanged_shouldNotReportfullyOccludedWindow() {
+        final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(frontWindow, new Region(100, 100, 300, 300));
+        final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
+
+        // index 1 is focused. Let's use the next one for this test.
+        final AccessibilityWindow occludedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(2);
+        setRegionForMockAccessibilityWindow(occludedWindow, new Region(150, 150, 250, 250));
+        final int occludedWindowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, occludedWindow.getWindowInfo().token);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasItem(windowId(frontWindowId)));
+        assertThat(a11yWindows, not(hasItem(windowId(occludedWindowId))));
+    }
+
+    @Test
+    public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
+        assertNotEquals("new title",
+                toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
+                        .get(0).getTitle()));
+
+        mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().title = "new title";
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+        assertEquals("new title",
+                toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
+                        .get(0).getTitle()));
     }
 
     @Test
@@ -368,14 +493,10 @@
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0);
         final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
                 true, USER_SYSTEM_ID);
-        final WindowInfo windowInfo = WindowInfo.obtain();
-        windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
-        windowInfo.token = token.asBinder();
-        windowInfo.layer = 0;
-        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-        mWindowInfos.get(Display.DEFAULT_DISPLAY).set(0, windowInfo);
+        mWindows.get(Display.DEFAULT_DISPLAY).set(0,
+                createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
         assertNotEquals(oldWindow,
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0));
     }
@@ -383,12 +504,12 @@
     @Test
     public void onWindowsChangedNoForceSend_focusChanged_shouldUpdateWindows() {
         final WindowInfo focusedWindowInfo =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX);
-        final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
+                mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
+        final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo();
         focusedWindowInfo.focused = false;
         windowInfo.focused = true;
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
         assertTrue(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0)
                 .isFocused());
     }
@@ -497,15 +618,18 @@
     @Test
     public void computePartialInteractiveRegionForWindow_wholeVisible_returnWholeRegion() {
         // Updates top 2 z-order WindowInfo are whole visible.
-        WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
-        windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(1);
-        windowInfo.regionInScreen.set(0, SCREEN_HEIGHT / 2,
-                SCREEN_WIDTH, SCREEN_HEIGHT);
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(firstWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
+        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
+        setRegionForMockAccessibilityWindow(secondWindow,
+                new Region(0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         final List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(2));
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(0).getId();
 
@@ -523,12 +647,17 @@
     @Test
     public void computePartialInteractiveRegionForWindow_halfVisible_returnHalfRegion() {
         // Updates z-order #1 WindowInfo is half visible.
-        WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
+        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(firstWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
+        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
+        setRegionForMockAccessibilityWindow(secondWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
         final List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(2));
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(1).getId();
 
@@ -539,9 +668,17 @@
 
     @Test
     public void computePartialInteractiveRegionForWindow_notVisible_returnEmptyRegion() {
-        // Since z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
+        // z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
+        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(firstWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
         final List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        // Note that the second window is also exposed even if region is empty because it's focused.
+        assertThat(a11yWindows, hasSize(2));
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(1).getId();
 
@@ -552,16 +689,21 @@
     @Test
     public void computePartialInteractiveRegionForWindow_partialVisible_returnVisibleRegion() {
         // Updates z-order #0 WindowInfo to have two interact-able areas.
-        Region region = new Region(0, 0, SCREEN_WIDTH, 200);
+        final Region region = new Region(0, 0, SCREEN_WIDTH, 200);
         region.op(0, SCREEN_HEIGHT - 200, SCREEN_WIDTH, SCREEN_HEIGHT, Region.Op.UNION);
-        WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        windowInfo.regionInScreen.set(region);
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(firstWindow, region);
+        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
+        setRegionForMockAccessibilityWindow(secondWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         final List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(2));
         final Region outBounds = new Region();
-        int windowId = a11yWindows.get(1).getId();
+        final int windowId = a11yWindows.get(1).getId();
 
         mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
         assertFalse(outBounds.getBounds().isEmpty());
@@ -572,7 +714,8 @@
     @Test
     public void updateActiveAndA11yFocusedWindow_windowStateChangedEvent_noTracking_shouldUpdate() {
         final IBinder eventWindowToken =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX + 1).token;
+                mWindows.get(Display.DEFAULT_DISPLAY)
+                        .get(DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().token;
         final int eventWindowId = mA11yWindowManager.findWindowIdLocked(
                 USER_SYSTEM_ID, eventWindowToken);
         when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
@@ -611,11 +754,11 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(currentActiveWindowId),
+                        eventWindowId(currentActiveWindowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
         assertThat(captor.getAllValues().get(1),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(eventWindowId),
+                        eventWindowId(eventWindowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
     }
 
@@ -641,7 +784,7 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(eventWindowId),
+                        eventWindowId(eventWindowId),
                         a11yWindowChanges(
                                 AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
     }
@@ -690,12 +833,12 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(initialDisplayId),
-                        a11yWindowId(initialWindowId),
+                        eventWindowId(initialWindowId),
                         a11yWindowChanges(
                                 AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
         assertThat(captor.getAllValues().get(1),
                 allOf(displayId(eventDisplayId),
-                        a11yWindowId(eventWindowId),
+                        eventWindowId(eventWindowId),
                         a11yWindowChanges(
                                 AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
     }
@@ -722,7 +865,7 @@
                 AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
                 noUse);
         assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY),
+                        AccessibilityNodeInfo.FOCUS_ACCESSIBILITY),
                 is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));
     }
 
@@ -751,11 +894,11 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(eventWindowId),
+                        eventWindowId(eventWindowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
         assertThat(captor.getAllValues().get(1),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(currentActiveWindowId),
+                        eventWindowId(currentActiveWindowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
     }
 
@@ -763,7 +906,8 @@
     public void onTouchInteractionEnd_noServiceInteractiveWindow_shouldClearA11yFocus()
             throws RemoteException {
         final IBinder defaultFocusWinToken =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).token;
+                mWindows.get(Display.DEFAULT_DISPLAY).get(
+                        DEFAULT_FOCUSED_INDEX).getWindowInfo().token;
         final int defaultFocusWindowId = mA11yWindowManager.findWindowIdLocked(
                 USER_SYSTEM_ID, defaultFocusWinToken);
         when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
@@ -808,8 +952,8 @@
     @Test
     public void getPictureInPictureWindow_shouldNotNull() {
         assertNull(mA11yWindowManager.getPictureInPictureWindowLocked());
-        mWindowInfos.get(Display.DEFAULT_DISPLAY).get(1).inPictureInPicture = true;
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        mWindows.get(Display.DEFAULT_DISPLAY).get(1).getWindowInfo().inPictureInPicture = true;
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         assertNotNull(mA11yWindowManager.getPictureInPictureWindowLocked());
     }
@@ -823,8 +967,9 @@
         final IAccessibilityInteractionConnection mockRemoteConnection =
                 mA11yWindowManager.getConnectionLocked(
                         USER_SYSTEM_ID, outsideWindowId).getRemote();
-        mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0).hasFlagWatchOutsideTouch = true;
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().hasFlagWatchOutsideTouch =
+                true;
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         mA11yWindowManager.notifyOutsideTouch(USER_SYSTEM_ID, targetWindowId);
         verify(mockRemoteConnection).notifyOutsideTouch();
@@ -942,18 +1087,14 @@
 
     @Test
     public void sendAccessibilityEventOnWindowRemoval() {
-        final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
+        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
 
         // Removing index 0 because it's not focused, and avoids unnecessary layer change.
         final int windowId =
                 getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-        infos.remove(0);
-        for (WindowInfo info : infos) {
-            // Adjust layer number because it should start from 0.
-            info.layer--;
-        }
+        windows.remove(0);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
 
         final ArgumentCaptor<AccessibilityEvent> captor =
                 ArgumentCaptor.forClass(AccessibilityEvent.class);
@@ -961,27 +1102,21 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(windowId),
+                        eventWindowId(windowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_REMOVED)));
     }
 
     @Test
     public void sendAccessibilityEventOnWindowAddition() throws RemoteException {
-        final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
-
-        for (WindowInfo info : infos) {
-            // Adjust layer number because new window will have 0 so that layer number in
-            // A11yWindowInfo in window won't be changed.
-            info.layer++;
-        }
+        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
 
         final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
                 false, USER_SYSTEM_ID);
-        addWindowInfo(infos, token, 0);
-        final int windowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, infos.size() - 1);
+        // Adding window to the front so that other windows' layer won't change.
+        windows.add(0, createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
+        final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
 
         final ArgumentCaptor<AccessibilityEvent> captor =
                 ArgumentCaptor.forClass(AccessibilityEvent.class);
@@ -989,17 +1124,17 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(windowId),
+                        eventWindowId(windowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ADDED)));
     }
 
     @Test
     public void sendAccessibilityEventOnWindowChange() {
-        final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
-        infos.get(0).title = "new title";
+        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
+        windows.get(0).getWindowInfo().title = "new title";
         final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
 
         final ArgumentCaptor<AccessibilityEvent> captor =
                 ArgumentCaptor.forClass(AccessibilityEvent.class);
@@ -1007,7 +1142,7 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(windowId),
+                        eventWindowId(windowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_TITLE)));
     }
 
@@ -1017,48 +1152,47 @@
     }
 
     private void startTrackingPerDisplay(int displayId) throws RemoteException {
-        ArrayList<WindowInfo> windowInfosForDisplay = new ArrayList<>();
+        ArrayList<AccessibilityWindow> windowsForDisplay = new ArrayList<>();
         // Adds RemoteAccessibilityConnection into AccessibilityWindowManager, and copy
         // mock window token into mA11yWindowTokens. Also, preparing WindowInfo mWindowInfos
         // for the test.
-        int layer = 0;
         for (int i = 0; i < NUM_GLOBAL_WINDOWS; i++) {
             final IWindow token = addAccessibilityInteractionConnection(displayId,
                     true, USER_SYSTEM_ID);
-            addWindowInfo(windowInfosForDisplay, token, layer++);
+            windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
 
         }
         for (int i = 0; i < NUM_APP_WINDOWS; i++) {
             final IWindow token = addAccessibilityInteractionConnection(displayId,
                     false, USER_SYSTEM_ID);
-            addWindowInfo(windowInfosForDisplay, token, layer++);
+            windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
         }
         // Sets up current focused window of display.
         // Each display has its own current focused window if config_perDisplayFocusEnabled is true.
         // Otherwise only default display needs to current focused window.
         if (mSupportPerDisplayFocus || displayId == Display.DEFAULT_DISPLAY) {
-            windowInfosForDisplay.get(DEFAULT_FOCUSED_INDEX).focused = true;
+            windowsForDisplay.get(DEFAULT_FOCUSED_INDEX).getWindowInfo().focused = true;
         }
         // Turns on windows tracking, and update window info.
         mA11yWindowManager.startTrackingWindows(displayId, false);
         // Puts window lists into array.
-        mWindowInfos.put(displayId, windowInfosForDisplay);
+        mWindows.put(displayId, windowsForDisplay);
         // Sets the default display is the top focused display and
         // its current focused window is the top focused window.
         if (displayId == Display.DEFAULT_DISPLAY) {
             setTopFocusedWindowAndDisplay(displayId, DEFAULT_FOCUSED_INDEX);
         }
         // Invokes callback for sending window lists to A11y framework.
-        onWindowsForAccessibilityChanged(displayId, FORCE_SEND);
+        onAccessibilityWindowsChanged(displayId, FORCE_SEND);
 
         assertEquals(mA11yWindowManager.getWindowListLocked(displayId).size(),
-                windowInfosForDisplay.size());
+                windowsForDisplay.size());
     }
 
     private WindowsForAccessibilityCallback getWindowsForAccessibilityCallbacks(int displayId) {
         ArgumentCaptor<WindowsForAccessibilityCallback> windowsForAccessibilityCallbacksCaptor =
                 ArgumentCaptor.forClass(
-                        WindowManagerInternal.WindowsForAccessibilityCallback.class);
+                        WindowsForAccessibilityCallback.class);
         verify(mMockWindowManagerInternal)
                 .setWindowsForAccessibilityCallback(eq(displayId),
                         windowsForAccessibilityCallbacksCaptor.capture());
@@ -1106,36 +1240,28 @@
         return windowId;
     }
 
-    private void addWindowInfo(ArrayList<WindowInfo> windowInfos, IWindow windowToken, int layer) {
-        final WindowInfo windowInfo = WindowInfo.obtain();
-        windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
-        windowInfo.token = windowToken.asBinder();
-        windowInfo.layer = layer;
-        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-        windowInfos.add(windowInfo);
-    }
-
     private int getWindowIdFromWindowInfosForDisplay(int displayId, int index) {
-        final IBinder windowToken = mWindowInfos.get(displayId).get(index).token;
+        final IBinder windowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
         return mA11yWindowManager.findWindowIdLocked(
                 USER_SYSTEM_ID, windowToken);
     }
 
     private void setTopFocusedWindowAndDisplay(int displayId, int index) {
         // Sets the top focus window.
-        mTopFocusedWindowToken = mWindowInfos.get(displayId).get(index).token;
+        mTopFocusedWindowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
         // Sets the top focused display.
         mTopFocusedDisplayId = displayId;
     }
 
-    private void onWindowsForAccessibilityChanged(int displayId, boolean forceSend) {
+    private void onAccessibilityWindowsChanged(int displayId, boolean forceSend) {
         WindowsForAccessibilityCallback callbacks = mCallbackOfWindows.get(displayId);
         if (callbacks == null) {
             callbacks = getWindowsForAccessibilityCallbacks(displayId);
             mCallbackOfWindows.put(displayId, callbacks);
         }
-        callbacks.onWindowsForAccessibilityChanged(forceSend, mTopFocusedDisplayId,
-                mTopFocusedWindowToken, mWindowInfos.get(displayId));
+        callbacks.onAccessibilityWindowsChanged(forceSend, mTopFocusedDisplayId,
+                mTopFocusedWindowToken, new Point(SCREEN_WIDTH, SCREEN_HEIGHT),
+                mWindows.get(displayId));
     }
 
     private void changeFocusedWindowOnDisplayPerDisplayFocusConfig(
@@ -1144,23 +1270,23 @@
         if (mSupportPerDisplayFocus) {
             // Gets the old focused window of display which wants to change focused window.
             WindowInfo focusedWindowInfo =
-                    mWindowInfos.get(changeFocusedDisplayId).get(oldFocusedWindowIndex);
+                    mWindows.get(changeFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
             // Resets the focus of old focused window.
             focusedWindowInfo.focused = false;
             // Gets the new window of display which wants to change focused window.
             focusedWindowInfo =
-                    mWindowInfos.get(changeFocusedDisplayId).get(newFocusedWindowIndex);
+                    mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
             // Sets the focus of new focused window.
             focusedWindowInfo.focused = true;
         } else {
             // Gets the window of display which wants to change focused window.
             WindowInfo focusedWindowInfo =
-                    mWindowInfos.get(changeFocusedDisplayId).get(newFocusedWindowIndex);
+                    mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
             // Sets the focus of new focused window.
             focusedWindowInfo.focused = true;
             // Gets the old focused window of old top focused display.
             focusedWindowInfo =
-                    mWindowInfos.get(oldTopFocusedDisplayId).get(oldFocusedWindowIndex);
+                    mWindows.get(oldTopFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
             // Resets the focus of old focused window.
             focusedWindowInfo.focused = false;
             // Changes the top focused display and window.
@@ -1168,6 +1294,39 @@
         }
     }
 
+    private AccessibilityWindow createMockAccessibilityWindow(IWindow windowToken, int displayId) {
+        final WindowInfo windowInfo = WindowInfo.obtain();
+        windowInfo.type = WindowManager.LayoutParams.TYPE_APPLICATION;
+        windowInfo.token = windowToken.asBinder();
+
+        final AccessibilityWindow window = Mockito.mock(AccessibilityWindow.class);
+        when(window.getWindowInfo()).thenReturn(windowInfo);
+        when(window.isFocused()).thenAnswer(invocation -> windowInfo.focused);
+        when(window.isTouchable()).thenReturn(true);
+        when(window.getType()).thenReturn(windowInfo.type);
+
+        setRegionForMockAccessibilityWindow(window, nextToucableRegion(displayId));
+        return window;
+    }
+
+    private void setRegionForMockAccessibilityWindow(AccessibilityWindow window, Region region) {
+        doAnswer(invocation -> {
+            ((Region) invocation.getArgument(0)).set(region);
+            return null;
+        }).when(window).getTouchableRegionInScreen(any(Region.class));
+        doAnswer(invocation -> {
+            ((Region) invocation.getArgument(0)).set(region);
+            return null;
+        }).when(window).getTouchableRegionInWindow(any(Region.class));
+    }
+
+    private Region nextToucableRegion(int displayId) {
+        final int topLeft = mNextRegionOffsets.get(displayId, 0);
+        final int bottomRight = topLeft + 100;
+        mNextRegionOffsets.put(displayId, topLeft + 10);
+        return new Region(topLeft, topLeft, bottomRight, bottomRight);
+    }
+
     @Nullable
     private static String toString(@Nullable CharSequence cs) {
         return cs == null ? null : cs.toString();
@@ -1196,16 +1355,16 @@
         }
     }
 
-    static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
+    static class EventWindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
         private int mWindowId;
 
-        WindowIdMatcher(int windowId) {
+        EventWindowIdMatcher(int windowId) {
             super();
             mWindowId = windowId;
         }
 
-        static WindowIdMatcher a11yWindowId(int windowId) {
-            return new WindowIdMatcher(windowId);
+        static EventWindowIdMatcher eventWindowId(int windowId) {
+            return new EventWindowIdMatcher(windowId);
         }
 
         @Override
@@ -1241,5 +1400,27 @@
             description.appendText("Matching to window changes " + mWindowChanges);
         }
     }
+
+    static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityWindowInfo> {
+        private final int mWindowId;
+
+        WindowIdMatcher(int windowId) {
+            super();
+            mWindowId = windowId;
+        }
+
+        static WindowIdMatcher windowId(int windowId) {
+            return new WindowIdMatcher(windowId);
+        }
+
+        @Override
+        protected boolean matchesSafely(AccessibilityWindowInfo window) {
+            return window.getId() == mWindowId;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("Matching to windowId " + mWindowId);
+        }
+    }
 }
-// LINT.ThenChange(/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java)
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java
deleted file mode 100644
index 1904145..0000000
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java
+++ /dev/null
@@ -1,1444 +0,0 @@
-/*
- * Copyright (C) 2019 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.accessibility;
-
-import static com.android.server.accessibility.AbstractAccessibilityServiceConnection.DISPLAY_TYPE_DEFAULT;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.DisplayIdMatcher.displayId;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.WindowIdMatcher.windowId;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.WindowChangesMatcher.a11yWindowChanges;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.EventWindowIdMatcher.eventWindowId;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.allOf;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.Nullable;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.IBinder;
-import android.os.LocaleList;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.util.SparseArray;
-import android.view.Display;
-import android.view.IWindow;
-import android.view.WindowInfo;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityWindowAttributes;
-import android.view.accessibility.AccessibilityWindowInfo;
-import android.view.accessibility.IAccessibilityInteractionConnection;
-
-import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
-import com.android.server.accessibility.test.MessageCapturingHandler;
-import com.android.server.wm.AccessibilityWindowsPopulator.AccessibilityWindow;
-import com.android.server.wm.WindowManagerInternal;
-import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for the AccessibilityWindowManager with Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2
- * TODO(b/322444245): Merge with AccessibilityWindowManagerTest
- *  after completing the flag migration.
- */
-@RequiresFlagsEnabled(Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2)
-public class AccessibilityWindowManagerWithAccessibilityWindowTest {
-    private static final String PACKAGE_NAME = "com.android.server.accessibility";
-    private static final boolean FORCE_SEND = true;
-    private static final boolean SEND_ON_WINDOW_CHANGES = false;
-    private static final int USER_SYSTEM_ID = UserHandle.USER_SYSTEM;
-    private static final int USER_PROFILE = 11;
-    private static final int USER_PROFILE_PARENT = 1;
-    private static final int SECONDARY_DISPLAY_ID = Display.DEFAULT_DISPLAY + 1;
-    private static final int NUM_GLOBAL_WINDOWS = 4;
-    private static final int NUM_APP_WINDOWS = 4;
-    private static final int NUM_OF_WINDOWS = (NUM_GLOBAL_WINDOWS + NUM_APP_WINDOWS);
-    private static final int DEFAULT_FOCUSED_INDEX = 1;
-    private static final int SCREEN_WIDTH = 1080;
-    private static final int SCREEN_HEIGHT = 1920;
-    private static final int INVALID_ID = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
-    private static final int HOST_WINDOW_ID = 10;
-    private static final int EMBEDDED_WINDOW_ID = 11;
-    private static final int OTHER_WINDOW_ID = 12;
-
-    private AccessibilityWindowManager mA11yWindowManager;
-    // Window manager will support multiple focused window if config_perDisplayFocusEnabled is true,
-    // i.e., each display would have its current focused window, and one of all focused windows
-    // would be top focused window. Otherwise, window manager only supports one focused window
-    // at all displays, and that focused window would be top focused window.
-    private boolean mSupportPerDisplayFocus = false;
-    private int mTopFocusedDisplayId = Display.INVALID_DISPLAY;
-    private IBinder mTopFocusedWindowToken = null;
-
-    // List of window token, mapping from windowId -> window token.
-    private final SparseArray<IWindow> mA11yWindowTokens = new SparseArray<>();
-    // List of window info lists, mapping from displayId -> a11y window lists.
-    private final SparseArray<ArrayList<AccessibilityWindow>> mWindows = new SparseArray<>();
-    // List of callback, mapping from displayId -> callback.
-    private final SparseArray<WindowsForAccessibilityCallback> mCallbackOfWindows =
-            new SparseArray<>();
-    // List of display ID.
-    private final ArrayList<Integer> mExpectedDisplayList = new ArrayList<>(Arrays.asList(
-            Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID));
-
-    private final MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
-
-    // This maps displayId -> next region offset.
-    // Touchable region must have un-occluded area so that it's exposed to a11y services.
-    // This offset can be used as left and top of new region so that top-left of each region are
-    // kept visible.
-    // It's expected to be incremented by some amount everytime the value is used.
-    private final SparseArray<Integer> mNextRegionOffsets = new SparseArray<>();
-
-    @Mock
-    private WindowManagerInternal mMockWindowManagerInternal;
-    @Mock
-    private AccessibilityWindowManager.AccessibilityEventSender mMockA11yEventSender;
-    @Mock
-    private AccessibilitySecurityPolicy mMockA11ySecurityPolicy;
-    @Mock
-    private AccessibilitySecurityPolicy.AccessibilityUserManager mMockA11yUserManager;
-    @Mock
-    private AccessibilityTraceManager mMockA11yTraceManager;
-
-    @Mock
-    private IBinder mMockHostToken;
-    @Mock
-    private IBinder mMockEmbeddedToken;
-    @Mock
-    private IBinder mMockInvalidToken;
-
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockA11yUserManager.getCurrentUserIdLocked()).thenReturn(USER_SYSTEM_ID);
-        when(mMockA11ySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
-                USER_PROFILE)).thenReturn(USER_PROFILE_PARENT);
-        when(mMockA11ySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
-                USER_SYSTEM_ID)).thenReturn(USER_SYSTEM_ID);
-        when(mMockA11ySecurityPolicy.resolveValidReportedPackageLocked(
-                anyString(), anyInt(), anyInt(), anyInt())).thenReturn(PACKAGE_NAME);
-
-        doAnswer((invocation) -> {
-            onAccessibilityWindowsChanged(invocation.getArgument(0), false);
-            return null;
-        }).when(mMockWindowManagerInternal).computeWindowsForAccessibility(anyInt());
-
-        mA11yWindowManager = new AccessibilityWindowManager(new Object(), mHandler,
-                mMockWindowManagerInternal,
-                mMockA11yEventSender,
-                mMockA11ySecurityPolicy,
-                mMockA11yUserManager,
-                mMockA11yTraceManager);
-        // Starts tracking window of default display and sets the default display
-        // as top focused display before each testing starts.
-        startTrackingPerDisplay(Display.DEFAULT_DISPLAY);
-
-        // AccessibilityEventSender is invoked during onAccessibilityWindowsChanged.
-        // Resets it for mockito verify of further test case.
-        Mockito.reset(mMockA11yEventSender);
-
-        registerLeashedTokenAndWindowId();
-    }
-
-    @After
-    public void tearDown() {
-        mHandler.removeAllMessages();
-    }
-
-    @Test
-    public void startTrackingWindows_shouldEnableWindowManagerCallback() {
-        // AccessibilityWindowManager#startTrackingWindows already invoked in setup.
-        assertTrue(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
-        final WindowsForAccessibilityCallback callbacks =
-                mCallbackOfWindows.get(Display.DEFAULT_DISPLAY);
-        verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(
-                eq(Display.DEFAULT_DISPLAY), eq(callbacks));
-    }
-
-    @Test
-    public void stopTrackingWindows_shouldDisableWindowManagerCallback() {
-        assertTrue(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
-        Mockito.reset(mMockWindowManagerInternal);
-
-        mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
-        assertFalse(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
-        verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(
-                eq(Display.DEFAULT_DISPLAY), isNull());
-
-    }
-
-    @Test
-    public void stopTrackingWindows_shouldClearWindows() {
-        assertTrue(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
-        final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-
-        mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
-        assertNull(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY));
-        assertEquals(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
-                AccessibilityWindowInfo.UNDEFINED_WINDOW_ID);
-        assertEquals(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID),
-                activeWindowId);
-    }
-
-    @Test
-    public void stopTrackingWindows_onNonTopFocusedDisplay_shouldNotResetTopFocusWindow()
-            throws RemoteException {
-        // At setup, the default display sets be the top focused display and
-        // its current focused window sets be the top focused window.
-        // Starts tracking window of second display.
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-        assertTrue(mA11yWindowManager.isTrackingWindowsLocked(SECONDARY_DISPLAY_ID));
-        // Stops tracking windows of second display.
-        mA11yWindowManager.stopTrackingWindows(SECONDARY_DISPLAY_ID);
-        assertNotEquals(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
-                AccessibilityWindowInfo.UNDEFINED_WINDOW_ID);
-    }
-
-    @Test
-    public void onWindowsChanged_duringTouchInteractAndFocusChange_shouldChangeActiveWindow() {
-        final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        final WindowInfo focusedWindowInfo =
-                mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
-        assertEquals(activeWindowId, mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, focusedWindowInfo.token));
-
-        focusedWindowInfo.focused = false;
-        mWindows.get(Display.DEFAULT_DISPLAY).get(
-                DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().focused = true;
-
-        mA11yWindowManager.onTouchInteractionStart();
-        setTopFocusedWindowAndDisplay(Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX + 1);
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
-    }
-
-    @Test
-    public void
-            onWindowsChanged_focusChangeOnNonTopFocusedDisplay_perDisplayFocusOn_notChangeWindow()
-            throws RemoteException {
-        // At setup, the default display sets be the top focused display and
-        // its current focused window sets be the top focused window.
-        // Sets supporting multiple focused window, i.e., config_perDisplayFocusEnabled is true.
-        mSupportPerDisplayFocus = true;
-        // Starts tracking window of second display.
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-        // Gets the active window.
-        final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        // Gets the top focused window.
-        final int topFocusedWindowId =
-                mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT);
-        // Changes the current focused window at second display.
-        changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
-                DEFAULT_FOCUSED_INDEX + 1, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
-
-        onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
-        // The active window should not be changed.
-        assertEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
-        // The top focused window should not be changed.
-        assertEquals(topFocusedWindowId,
-                mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT));
-    }
-
-    @Test
-    public void
-            onWindowChange_focusChangeToNonTopFocusedDisplay_perDisplayFocusOff_shouldChangeWindow()
-            throws RemoteException {
-        // At setup, the default display sets be the top focused display and
-        // its current focused window sets be the top focused window.
-        // Sets not supporting multiple focused window, i.e., config_perDisplayFocusEnabled is
-        // false.
-        mSupportPerDisplayFocus = false;
-        // Starts tracking window of second display.
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-        // Gets the active window.
-        final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        // Gets the top focused window.
-        final int topFocusedWindowId =
-                mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT);
-        // Changes the current focused window from default display to second display.
-        changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
-                DEFAULT_FOCUSED_INDEX, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
-        // The active window should be changed.
-        assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
-        // The top focused window should be changed.
-        assertNotEquals(topFocusedWindowId,
-                mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT));
-    }
-
-    @Test
-    public void onWindowsChanged_shouldReportCorrectLayer() {
-        // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
-        List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        for (int i = 0; i < a11yWindows.size(); i++) {
-            final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
-            assertThat(mWindows.get(Display.DEFAULT_DISPLAY).size() - i - 1,
-                    is(a11yWindow.getLayer()));
-        }
-    }
-
-    @Test
-    public void onWindowsChanged_shouldReportCorrectOrder() {
-        // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
-        List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        for (int i = 0; i < a11yWindows.size(); i++) {
-            final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
-            final IBinder windowToken = mA11yWindowManager
-                    .getWindowTokenForUserAndWindowIdLocked(USER_SYSTEM_ID, a11yWindow.getId());
-            final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY)
-                    .get(i).getWindowInfo();
-            assertThat(windowToken, is(windowInfo.token));
-        }
-    }
-
-    @Test
-    public void onWindowsChanged_shouldNotReportNonTouchableWindow() {
-        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        when(window.isTouchable()).thenReturn(false);
-        final int windowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, window.getWindowInfo().token);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, not(hasItem(windowId(windowId))));
-    }
-
-    @Test
-    public void onWindowsChanged_shouldReportFocusedNonTouchableWindow() {
-        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
-                DEFAULT_FOCUSED_INDEX);
-        when(window.isTouchable()).thenReturn(false);
-        final int windowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, window.getWindowInfo().token);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasItem(windowId(windowId)));
-    }
-
-    @Test
-    public void onWindowsChanged_trustedFocusedNonTouchableWindow_shouldNotHideWindowsBelow() {
-        // Make the focused trusted un-touchable window fullscreen.
-        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
-                DEFAULT_FOCUSED_INDEX);
-        setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-        when(window.isTouchable()).thenReturn(false);
-        when(window.isTrustedOverlay()).thenReturn(true);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
-    }
-
-    @Test
-    public void onWindowsChanged_accessibilityOverlay_shouldNotHideWindowsBelow() {
-        // Make the a11y overlay window fullscreen.
-        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-        when(window.getType()).thenReturn(WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
-    }
-
-    @Test
-    public void onWindowsChanged_shouldReportFocusedWindowEvenIfOccluded() {
-        // Make the front window fullscreen.
-        final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(frontWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-        final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
-
-        final AccessibilityWindow focusedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(
-                DEFAULT_FOCUSED_INDEX);
-        final int focusedWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, focusedWindow.getWindowInfo().token);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(2));
-        assertThat(a11yWindows.get(0), windowId(frontWindowId));
-        assertThat(a11yWindows.get(1), windowId(focusedWindowId));
-    }
-
-    @Test
-    public void onWindowsChanged_embeddedWindows_shouldOnlyReportHost() throws RemoteException {
-        final Rect embeddingBounds = new Rect(0, 0, 200, 100);
-
-        // The embedded window comes front of the host window.
-        final IBinder embeddedWindowLeashToken = Mockito.mock(IBinder.class);
-        final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, embeddedWindowLeashToken, USER_SYSTEM_ID);
-        final AccessibilityWindow embeddedWindow = createMockAccessibilityWindow(
-                mA11yWindowTokens.get(embeddedWindowId), Display.DEFAULT_DISPLAY);
-        setRegionForMockAccessibilityWindow(embeddedWindow, new Region(embeddingBounds));
-        mWindows.get(Display.DEFAULT_DISPLAY).set(0, embeddedWindow);
-
-        final IBinder hostWindowLeashToken = Mockito.mock(IBinder.class);
-        final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, hostWindowLeashToken, USER_SYSTEM_ID);
-        final AccessibilityWindow hostWindow = createMockAccessibilityWindow(
-                mA11yWindowTokens.get(hostWindowId), Display.DEFAULT_DISPLAY);
-        setRegionForMockAccessibilityWindow(hostWindow, new Region(embeddingBounds));
-        mWindows.get(Display.DEFAULT_DISPLAY).set(1, hostWindow);
-
-        mA11yWindowManager.associateEmbeddedHierarchyLocked(
-                hostWindowLeashToken, embeddedWindowLeashToken);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, not(hasItem(windowId(embeddedWindowId))));
-        assertThat(a11yWindows.get(0), windowId(hostWindowId));
-        final Rect bounds = new Rect();
-        a11yWindows.get(0).getBoundsInScreen(bounds);
-        assertEquals(bounds, embeddingBounds);
-    }
-
-    @Test
-    public void onWindowsChanged_shouldNotReportfullyOccludedWindow() {
-        final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(frontWindow, new Region(100, 100, 300, 300));
-        final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
-
-        // index 1 is focused. Let's use the next one for this test.
-        final AccessibilityWindow occludedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(2);
-        setRegionForMockAccessibilityWindow(occludedWindow, new Region(150, 150, 250, 250));
-        final int occludedWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, occludedWindow.getWindowInfo().token);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasItem(windowId(frontWindowId)));
-        assertThat(a11yWindows, not(hasItem(windowId(occludedWindowId))));
-    }
-
-    @Test
-    public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
-        assertNotEquals("new title",
-                toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
-                        .get(0).getTitle()));
-
-        mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().title = "new title";
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-        assertEquals("new title",
-                toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
-                        .get(0).getTitle()));
-    }
-
-    @Test
-    public void onWindowsChangedNoForceSend_windowChanged_shouldUpdateWindows()
-            throws RemoteException {
-        final AccessibilityWindowInfo oldWindow =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0);
-        final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                true, USER_SYSTEM_ID);
-        mWindows.get(Display.DEFAULT_DISPLAY).set(0,
-                createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        assertNotEquals(oldWindow,
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0));
-    }
-
-    @Test
-    public void onWindowsChangedNoForceSend_focusChanged_shouldUpdateWindows() {
-        final WindowInfo focusedWindowInfo =
-                mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
-        final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo();
-        focusedWindowInfo.focused = false;
-        windowInfo.focused = true;
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        assertTrue(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0)
-                .isFocused());
-    }
-
-    @Test
-    public void removeAccessibilityInteractionConnection_byWindowToken_shouldRemoved() {
-        for (int i = 0; i < NUM_OF_WINDOWS; i++) {
-            final int windowId = mA11yWindowTokens.keyAt(i);
-            final IWindow windowToken = mA11yWindowTokens.valueAt(i);
-            assertNotNull(mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId));
-
-            mA11yWindowManager.removeAccessibilityInteractionConnection(windowToken);
-            assertNull(mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId));
-        }
-    }
-
-    @Test
-    public void remoteAccessibilityConnection_binderDied_shouldRemoveConnection() {
-        for (int i = 0; i < NUM_OF_WINDOWS; i++) {
-            final int windowId = mA11yWindowTokens.keyAt(i);
-            final RemoteAccessibilityConnection remoteA11yConnection =
-                    mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId);
-            assertNotNull(remoteA11yConnection);
-
-            remoteA11yConnection.binderDied();
-            assertNull(mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId));
-        }
-    }
-
-    @Test
-    public void getWindowTokenForUserAndWindowId_shouldNotNull() {
-        final List<AccessibilityWindowInfo> windows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        for (int i = 0; i < windows.size(); i++) {
-            final int windowId = windows.get(i).getId();
-
-            assertNotNull(mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(
-                    USER_SYSTEM_ID, windowId));
-        }
-    }
-
-    @Test
-    public void findWindowId() {
-        final List<AccessibilityWindowInfo> windows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        for (int i = 0; i < windows.size(); i++) {
-            final int windowId = windows.get(i).getId();
-            final IBinder windowToken = mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(
-                    USER_SYSTEM_ID, windowId);
-
-            assertEquals(mA11yWindowManager.findWindowIdLocked(
-                    USER_SYSTEM_ID, windowToken), windowId);
-        }
-    }
-
-    @Test
-    public void resolveParentWindowId_windowIsNotEmbedded_shouldReturnGivenId()
-            throws RemoteException {
-        final int windowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY, false,
-                Mockito.mock(IBinder.class), USER_SYSTEM_ID);
-        assertEquals(windowId, mA11yWindowManager.resolveParentWindowIdLocked(windowId));
-    }
-
-    @Test
-    public void resolveParentWindowId_windowIsNotRegistered_shouldReturnGivenId() {
-        final int windowId = -1;
-        assertEquals(windowId, mA11yWindowManager.resolveParentWindowIdLocked(windowId));
-    }
-
-    @Test
-    public void resolveParentWindowId_windowIsAssociated_shouldReturnParentWindowId()
-            throws RemoteException {
-        final IBinder mockHostToken = Mockito.mock(IBinder.class);
-        final IBinder mockEmbeddedToken = Mockito.mock(IBinder.class);
-        final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, mockHostToken, USER_SYSTEM_ID);
-        final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, mockEmbeddedToken, USER_SYSTEM_ID);
-
-        mA11yWindowManager.associateEmbeddedHierarchyLocked(mockHostToken, mockEmbeddedToken);
-
-        final int resolvedWindowId = mA11yWindowManager.resolveParentWindowIdLocked(
-                embeddedWindowId);
-        assertEquals(hostWindowId, resolvedWindowId);
-    }
-
-    @Test
-    public void resolveParentWindowId_windowIsDisassociated_shouldReturnGivenId()
-            throws RemoteException {
-        final IBinder mockHostToken = Mockito.mock(IBinder.class);
-        final IBinder mockEmbeddedToken = Mockito.mock(IBinder.class);
-        final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, mockHostToken, USER_SYSTEM_ID);
-        final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, mockEmbeddedToken, USER_SYSTEM_ID);
-
-        mA11yWindowManager.associateEmbeddedHierarchyLocked(mockHostToken, mockEmbeddedToken);
-        mA11yWindowManager.disassociateEmbeddedHierarchyLocked(mockEmbeddedToken);
-
-        final int resolvedWindowId = mA11yWindowManager.resolveParentWindowIdLocked(
-                embeddedWindowId);
-        assertNotEquals(hostWindowId, resolvedWindowId);
-        assertEquals(embeddedWindowId, resolvedWindowId);
-    }
-
-    @Test
-    public void computePartialInteractiveRegionForWindow_wholeVisible_returnWholeRegion() {
-        // Updates top 2 z-order WindowInfo are whole visible.
-        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(firstWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
-        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
-        setRegionForMockAccessibilityWindow(secondWindow,
-                new Region(0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(2));
-        final Region outBounds = new Region();
-        int windowId = a11yWindows.get(0).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
-        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
-
-        windowId = a11yWindows.get(1).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
-        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
-    }
-
-    @Test
-    public void computePartialInteractiveRegionForWindow_halfVisible_returnHalfRegion() {
-        // Updates z-order #1 WindowInfo is half visible.
-        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(firstWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
-        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
-        setRegionForMockAccessibilityWindow(secondWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(2));
-        final Region outBounds = new Region();
-        int windowId = a11yWindows.get(1).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
-        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
-    }
-
-    @Test
-    public void computePartialInteractiveRegionForWindow_notVisible_returnEmptyRegion() {
-        // z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
-        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(firstWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        // Note that the second window is also exposed even if region is empty because it's focused.
-        assertThat(a11yWindows, hasSize(2));
-        final Region outBounds = new Region();
-        int windowId = a11yWindows.get(1).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertTrue(outBounds.getBounds().isEmpty());
-    }
-
-    @Test
-    public void computePartialInteractiveRegionForWindow_partialVisible_returnVisibleRegion() {
-        // Updates z-order #0 WindowInfo to have two interact-able areas.
-        final Region region = new Region(0, 0, SCREEN_WIDTH, 200);
-        region.op(0, SCREEN_HEIGHT - 200, SCREEN_WIDTH, SCREEN_HEIGHT, Region.Op.UNION);
-        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(firstWindow, region);
-        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
-        setRegionForMockAccessibilityWindow(secondWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(2));
-        final Region outBounds = new Region();
-        final int windowId = a11yWindows.get(1).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertFalse(outBounds.getBounds().isEmpty());
-        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
-        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT - 400));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_windowStateChangedEvent_noTracking_shouldUpdate() {
-        final IBinder eventWindowToken =
-                mWindows.get(Display.DEFAULT_DISPLAY)
-                        .get(DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().token;
-        final int eventWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, eventWindowToken);
-        when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
-                .thenReturn(eventWindowToken);
-
-        final int noUse = 0;
-        mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(eventWindowId));
-        assertThat(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
-                is(eventWindowId));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_hoverEvent_touchInteract_shouldSetActiveWindow() {
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX + 1);
-        final int currentActiveWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        assertThat(currentActiveWindowId, is(not(eventWindowId)));
-
-        final int noUse = 0;
-        mA11yWindowManager.onTouchInteractionStart();
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(eventWindowId));
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(2))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(currentActiveWindowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
-        assertThat(captor.getAllValues().get(1),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(eventWindowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_shouldUpdateA11yFocus() {
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX);
-        final int currentA11yFocusedWindowId = mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
-        assertThat(currentA11yFocusedWindowId, is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));
-
-        final int noUse = 0;
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(1))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(eventWindowId),
-                        a11yWindowChanges(
-                                AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_defaultToSecondary()
-            throws RemoteException {
-        runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
-                Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID);
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_SecondaryToDefault()
-            throws RemoteException {
-        runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
-                SECONDARY_DISPLAY_ID, Display.DEFAULT_DISPLAY);
-    }
-
-    private void runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
-            int initialDisplayId, int eventDisplayId) throws RemoteException {
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-        final int initialWindowId = getWindowIdFromWindowInfosForDisplay(
-                initialDisplayId, DEFAULT_FOCUSED_INDEX);
-        final int noUse = 0;
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                initialWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(initialWindowId));
-        Mockito.reset(mMockA11yEventSender);
-
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(
-                eventDisplayId, DEFAULT_FOCUSED_INDEX);
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(2))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(initialDisplayId),
-                        eventWindowId(initialWindowId),
-                        a11yWindowChanges(
-                                AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
-        assertThat(captor.getAllValues().get(1),
-                allOf(displayId(eventDisplayId),
-                        eventWindowId(eventWindowId),
-                        a11yWindowChanges(
-                                AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_clearA11yFocusEvent_shouldClearA11yFocus() {
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX);
-        final int currentA11yFocusedWindowId = mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
-        assertThat(currentA11yFocusedWindowId, is(not(eventWindowId)));
-
-        final int noUse = 0;
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                        AccessibilityNodeInfo.FOCUS_ACCESSIBILITY),
-                is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));
-    }
-
-    @Test
-    public void onTouchInteractionEnd_shouldRollbackActiveWindow() {
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX + 1);
-        final int currentActiveWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        assertThat(currentActiveWindowId, is(not(eventWindowId)));
-
-        final int noUse = 0;
-        mA11yWindowManager.onTouchInteractionStart();
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(eventWindowId));
-        // AccessibilityEventSender is invoked after active window changed. Reset it.
-        Mockito.reset(mMockA11yEventSender);
-
-        mA11yWindowManager.onTouchInteractionEnd();
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(2))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(eventWindowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
-        assertThat(captor.getAllValues().get(1),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(currentActiveWindowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
-    }
-
-    @Test
-    public void onTouchInteractionEnd_noServiceInteractiveWindow_shouldClearA11yFocus()
-            throws RemoteException {
-        final IBinder defaultFocusWinToken =
-                mWindows.get(Display.DEFAULT_DISPLAY).get(
-                        DEFAULT_FOCUSED_INDEX).getWindowInfo().token;
-        final int defaultFocusWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, defaultFocusWinToken);
-        when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
-                .thenReturn(defaultFocusWinToken);
-        final int newFocusWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX + 1);
-        final IAccessibilityInteractionConnection mockNewFocusConnection =
-                mA11yWindowManager.getConnectionLocked(
-                        USER_SYSTEM_ID, newFocusWindowId).getRemote();
-
-        mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
-        final int noUse = 0;
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                defaultFocusWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(defaultFocusWindowId));
-        assertThat(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
-                is(defaultFocusWindowId));
-
-        mA11yWindowManager.onTouchInteractionStart();
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                newFocusWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
-                noUse);
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                newFocusWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(newFocusWindowId));
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(newFocusWindowId));
-
-        mA11yWindowManager.onTouchInteractionEnd();
-        mHandler.sendLastMessage();
-        verify(mockNewFocusConnection).clearAccessibilityFocus();
-    }
-
-    @Test
-    public void getPictureInPictureWindow_shouldNotNull() {
-        assertNull(mA11yWindowManager.getPictureInPictureWindowLocked());
-        mWindows.get(Display.DEFAULT_DISPLAY).get(1).getWindowInfo().inPictureInPicture = true;
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        assertNotNull(mA11yWindowManager.getPictureInPictureWindowLocked());
-    }
-
-    @Test
-    public void notifyOutsideTouch() throws RemoteException {
-        final int targetWindowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 1);
-        final int outsideWindowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-        final IAccessibilityInteractionConnection mockRemoteConnection =
-                mA11yWindowManager.getConnectionLocked(
-                        USER_SYSTEM_ID, outsideWindowId).getRemote();
-        mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().hasFlagWatchOutsideTouch =
-                true;
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        mA11yWindowManager.notifyOutsideTouch(USER_SYSTEM_ID, targetWindowId);
-        verify(mockRemoteConnection).notifyOutsideTouch();
-    }
-
-    @Test
-    public void addAccessibilityInteractionConnection_profileUser_findInParentUser()
-            throws RemoteException {
-        final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, USER_PROFILE);
-        final int windowId = mA11yWindowManager.findWindowIdLocked(
-                USER_PROFILE_PARENT, token.asBinder());
-        assertTrue(windowId >= 0);
-    }
-
-    @Test
-    public void getDisplayList() throws RemoteException {
-        // Starts tracking window of second display.
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-
-        final ArrayList<Integer> displayList = mA11yWindowManager.getDisplayListLocked(
-                DISPLAY_TYPE_DEFAULT);
-        assertTrue(displayList.equals(mExpectedDisplayList));
-    }
-
-    @Test
-    public void setAccessibilityWindowIdToSurfaceMetadata()
-            throws RemoteException {
-        final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                true, USER_SYSTEM_ID);
-        int windowId = -1;
-        for (int i = 0; i < mA11yWindowTokens.size(); i++) {
-            if (mA11yWindowTokens.valueAt(i).equals(token)) {
-                windowId = mA11yWindowTokens.keyAt(i);
-            }
-        }
-        assertNotEquals("Returned token is not found in mA11yWindowTokens", -1, windowId);
-        verify(mMockWindowManagerInternal, times(1)).setAccessibilityIdToSurfaceMetadata(
-                token.asBinder(), windowId);
-
-        mA11yWindowManager.removeAccessibilityInteractionConnection(token);
-        verify(mMockWindowManagerInternal, times(1)).setAccessibilityIdToSurfaceMetadata(
-                token.asBinder(), -1);
-    }
-
-    @Test
-    public void getHostTokenLocked_hierarchiesAreAssociated_shouldReturnHostToken() {
-        mA11yWindowManager.associateLocked(mMockEmbeddedToken, mMockHostToken);
-        final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockEmbeddedToken);
-        assertEquals(hostToken, mMockHostToken);
-    }
-
-    @Test
-    public void getHostTokenLocked_hierarchiesAreNotAssociated_shouldReturnNull() {
-        final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockEmbeddedToken);
-        assertNull(hostToken);
-    }
-
-    @Test
-    public void getHostTokenLocked_embeddedHierarchiesAreDisassociated_shouldReturnNull() {
-        mA11yWindowManager.associateLocked(mMockEmbeddedToken, mMockHostToken);
-        mA11yWindowManager.disassociateLocked(mMockEmbeddedToken);
-        final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockEmbeddedToken);
-        assertNull(hostToken);
-    }
-
-    @Test
-    public void getHostTokenLocked_hostHierarchiesAreDisassociated_shouldReturnNull() {
-        mA11yWindowManager.associateLocked(mMockEmbeddedToken, mMockHostToken);
-        mA11yWindowManager.disassociateLocked(mMockHostToken);
-        final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockHostToken);
-        assertNull(hostToken);
-    }
-
-    @Test
-    public void getWindowIdLocked_windowIsRegistered_shouldReturnWindowId() {
-        final int windowId = mA11yWindowManager.getWindowIdLocked(mMockHostToken);
-        assertEquals(windowId, HOST_WINDOW_ID);
-    }
-
-    @Test
-    public void getWindowIdLocked_windowIsNotRegistered_shouldReturnInvalidWindowId() {
-        final int windowId = mA11yWindowManager.getWindowIdLocked(mMockInvalidToken);
-        assertEquals(windowId, INVALID_ID);
-    }
-
-    @Test
-    public void getTokenLocked_windowIsRegistered_shouldReturnToken() {
-        final IBinder token = mA11yWindowManager.getLeashTokenLocked(HOST_WINDOW_ID);
-        assertEquals(token, mMockHostToken);
-    }
-
-    @Test
-    public void getTokenLocked_windowIsNotRegistered_shouldReturnNull() {
-        final IBinder token = mA11yWindowManager.getLeashTokenLocked(OTHER_WINDOW_ID);
-        assertNull(token);
-    }
-
-    @Test
-    public void setAccessibilityWindowAttributes_windowIsNotRegistered_titleIsChanged() {
-        final int windowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
-        layoutParams.accessibilityTitle = "accessibility window title";
-        final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
-                layoutParams, new LocaleList());
-
-        mA11yWindowManager.setAccessibilityWindowAttributes(Display.DEFAULT_DISPLAY, windowId,
-                USER_SYSTEM_ID, attributes);
-
-        final AccessibilityWindowInfo a11yWindow = mA11yWindowManager.findA11yWindowInfoByIdLocked(
-                windowId);
-        assertEquals(toString(layoutParams.accessibilityTitle), toString(a11yWindow.getTitle()));
-    }
-
-    @Test
-    public void sendAccessibilityEventOnWindowRemoval() {
-        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
-
-        // Removing index 0 because it's not focused, and avoids unnecessary layer change.
-        final int windowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-        windows.remove(0);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(1))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(windowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_REMOVED)));
-    }
-
-    @Test
-    public void sendAccessibilityEventOnWindowAddition() throws RemoteException {
-        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
-
-        final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, USER_SYSTEM_ID);
-        // Adding window to the front so that other windows' layer won't change.
-        windows.add(0, createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
-        final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(1))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(windowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ADDED)));
-    }
-
-    @Test
-    public void sendAccessibilityEventOnWindowChange() {
-        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
-        windows.get(0).getWindowInfo().title = "new title";
-        final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(1))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(windowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_TITLE)));
-    }
-
-    private void registerLeashedTokenAndWindowId() {
-        mA11yWindowManager.registerIdLocked(mMockHostToken, HOST_WINDOW_ID);
-        mA11yWindowManager.registerIdLocked(mMockEmbeddedToken, EMBEDDED_WINDOW_ID);
-    }
-
-    private void startTrackingPerDisplay(int displayId) throws RemoteException {
-        ArrayList<AccessibilityWindow> windowsForDisplay = new ArrayList<>();
-        // Adds RemoteAccessibilityConnection into AccessibilityWindowManager, and copy
-        // mock window token into mA11yWindowTokens. Also, preparing WindowInfo mWindowInfos
-        // for the test.
-        for (int i = 0; i < NUM_GLOBAL_WINDOWS; i++) {
-            final IWindow token = addAccessibilityInteractionConnection(displayId,
-                    true, USER_SYSTEM_ID);
-            windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
-
-        }
-        for (int i = 0; i < NUM_APP_WINDOWS; i++) {
-            final IWindow token = addAccessibilityInteractionConnection(displayId,
-                    false, USER_SYSTEM_ID);
-            windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
-        }
-        // Sets up current focused window of display.
-        // Each display has its own current focused window if config_perDisplayFocusEnabled is true.
-        // Otherwise only default display needs to current focused window.
-        if (mSupportPerDisplayFocus || displayId == Display.DEFAULT_DISPLAY) {
-            windowsForDisplay.get(DEFAULT_FOCUSED_INDEX).getWindowInfo().focused = true;
-        }
-        // Turns on windows tracking, and update window info.
-        mA11yWindowManager.startTrackingWindows(displayId, false);
-        // Puts window lists into array.
-        mWindows.put(displayId, windowsForDisplay);
-        // Sets the default display is the top focused display and
-        // its current focused window is the top focused window.
-        if (displayId == Display.DEFAULT_DISPLAY) {
-            setTopFocusedWindowAndDisplay(displayId, DEFAULT_FOCUSED_INDEX);
-        }
-        // Invokes callback for sending window lists to A11y framework.
-        onAccessibilityWindowsChanged(displayId, FORCE_SEND);
-
-        assertEquals(mA11yWindowManager.getWindowListLocked(displayId).size(),
-                windowsForDisplay.size());
-    }
-
-    private WindowsForAccessibilityCallback getWindowsForAccessibilityCallbacks(int displayId) {
-        ArgumentCaptor<WindowsForAccessibilityCallback> windowsForAccessibilityCallbacksCaptor =
-                ArgumentCaptor.forClass(
-                        WindowsForAccessibilityCallback.class);
-        verify(mMockWindowManagerInternal)
-                .setWindowsForAccessibilityCallback(eq(displayId),
-                        windowsForAccessibilityCallbacksCaptor.capture());
-        return windowsForAccessibilityCallbacksCaptor.getValue();
-    }
-
-    private IWindow addAccessibilityInteractionConnection(int displayId, boolean bGlobal,
-            int userId) throws RemoteException {
-        final IWindow mockWindowToken = Mockito.mock(IWindow.class);
-        final IAccessibilityInteractionConnection mockA11yConnection = Mockito.mock(
-                IAccessibilityInteractionConnection.class);
-        final IBinder mockConnectionBinder = Mockito.mock(IBinder.class);
-        final IBinder mockWindowBinder = Mockito.mock(IBinder.class);
-        final IBinder mockLeashToken = Mockito.mock(IBinder.class);
-        when(mockA11yConnection.asBinder()).thenReturn(mockConnectionBinder);
-        when(mockWindowToken.asBinder()).thenReturn(mockWindowBinder);
-        when(mMockA11ySecurityPolicy.isCallerInteractingAcrossUsers(userId))
-                .thenReturn(bGlobal);
-        when(mMockWindowManagerInternal.getDisplayIdForWindow(mockWindowBinder))
-                .thenReturn(displayId);
-
-        int windowId = mA11yWindowManager.addAccessibilityInteractionConnection(
-                mockWindowToken, mockLeashToken, mockA11yConnection, PACKAGE_NAME, userId);
-        mA11yWindowTokens.put(windowId, mockWindowToken);
-        return mockWindowToken;
-    }
-
-    private int addAccessibilityInteractionConnection(int displayId, boolean bGlobal,
-            IBinder leashToken, int userId) throws RemoteException {
-        final IWindow mockWindowToken = Mockito.mock(IWindow.class);
-        final IAccessibilityInteractionConnection mockA11yConnection = Mockito.mock(
-                IAccessibilityInteractionConnection.class);
-        final IBinder mockConnectionBinder = Mockito.mock(IBinder.class);
-        final IBinder mockWindowBinder = Mockito.mock(IBinder.class);
-        when(mockA11yConnection.asBinder()).thenReturn(mockConnectionBinder);
-        when(mockWindowToken.asBinder()).thenReturn(mockWindowBinder);
-        when(mMockA11ySecurityPolicy.isCallerInteractingAcrossUsers(userId))
-                .thenReturn(bGlobal);
-        when(mMockWindowManagerInternal.getDisplayIdForWindow(mockWindowBinder))
-                .thenReturn(displayId);
-
-        int windowId = mA11yWindowManager.addAccessibilityInteractionConnection(
-                mockWindowToken, leashToken, mockA11yConnection, PACKAGE_NAME, userId);
-        mA11yWindowTokens.put(windowId, mockWindowToken);
-        return windowId;
-    }
-
-    private int getWindowIdFromWindowInfosForDisplay(int displayId, int index) {
-        final IBinder windowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
-        return mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, windowToken);
-    }
-
-    private void setTopFocusedWindowAndDisplay(int displayId, int index) {
-        // Sets the top focus window.
-        mTopFocusedWindowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
-        // Sets the top focused display.
-        mTopFocusedDisplayId = displayId;
-    }
-
-    private void onAccessibilityWindowsChanged(int displayId, boolean forceSend) {
-        WindowsForAccessibilityCallback callbacks = mCallbackOfWindows.get(displayId);
-        if (callbacks == null) {
-            callbacks = getWindowsForAccessibilityCallbacks(displayId);
-            mCallbackOfWindows.put(displayId, callbacks);
-        }
-        callbacks.onAccessibilityWindowsChanged(forceSend, mTopFocusedDisplayId,
-                mTopFocusedWindowToken, new Point(SCREEN_WIDTH, SCREEN_HEIGHT),
-                mWindows.get(displayId));
-    }
-
-    private void changeFocusedWindowOnDisplayPerDisplayFocusConfig(
-            int changeFocusedDisplayId, int newFocusedWindowIndex, int oldTopFocusedDisplayId,
-            int oldFocusedWindowIndex) {
-        if (mSupportPerDisplayFocus) {
-            // Gets the old focused window of display which wants to change focused window.
-            WindowInfo focusedWindowInfo =
-                    mWindows.get(changeFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
-            // Resets the focus of old focused window.
-            focusedWindowInfo.focused = false;
-            // Gets the new window of display which wants to change focused window.
-            focusedWindowInfo =
-                    mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
-            // Sets the focus of new focused window.
-            focusedWindowInfo.focused = true;
-        } else {
-            // Gets the window of display which wants to change focused window.
-            WindowInfo focusedWindowInfo =
-                    mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
-            // Sets the focus of new focused window.
-            focusedWindowInfo.focused = true;
-            // Gets the old focused window of old top focused display.
-            focusedWindowInfo =
-                    mWindows.get(oldTopFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
-            // Resets the focus of old focused window.
-            focusedWindowInfo.focused = false;
-            // Changes the top focused display and window.
-            setTopFocusedWindowAndDisplay(changeFocusedDisplayId, newFocusedWindowIndex);
-        }
-    }
-
-    private AccessibilityWindow createMockAccessibilityWindow(IWindow windowToken, int displayId) {
-        final WindowInfo windowInfo = WindowInfo.obtain();
-        windowInfo.type = WindowManager.LayoutParams.TYPE_APPLICATION;
-        windowInfo.token = windowToken.asBinder();
-
-        final AccessibilityWindow window = Mockito.mock(AccessibilityWindow.class);
-        when(window.getWindowInfo()).thenReturn(windowInfo);
-        when(window.isFocused()).thenAnswer(invocation -> windowInfo.focused);
-        when(window.isTouchable()).thenReturn(true);
-        when(window.getType()).thenReturn(windowInfo.type);
-
-        setRegionForMockAccessibilityWindow(window, nextToucableRegion(displayId));
-        return window;
-    }
-
-    private void setRegionForMockAccessibilityWindow(AccessibilityWindow window, Region region) {
-        doAnswer(invocation -> {
-            ((Region) invocation.getArgument(0)).set(region);
-            return null;
-        }).when(window).getTouchableRegionInScreen(any(Region.class));
-        doAnswer(invocation -> {
-            ((Region) invocation.getArgument(0)).set(region);
-            return null;
-        }).when(window).getTouchableRegionInWindow(any(Region.class));
-    }
-
-    private Region nextToucableRegion(int displayId) {
-        final int topLeft = mNextRegionOffsets.get(displayId, 0);
-        final int bottomRight = topLeft + 100;
-        mNextRegionOffsets.put(displayId, topLeft + 10);
-        return new Region(topLeft, topLeft, bottomRight, bottomRight);
-    }
-
-    @Nullable
-    private static String toString(@Nullable CharSequence cs) {
-        return cs == null ? null : cs.toString();
-    }
-
-    static class DisplayIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
-        private final int mDisplayId;
-
-        DisplayIdMatcher(int displayId) {
-            super();
-            mDisplayId = displayId;
-        }
-
-        static DisplayIdMatcher displayId(int displayId) {
-            return new DisplayIdMatcher(displayId);
-        }
-
-        @Override
-        protected boolean matchesSafely(AccessibilityEvent event) {
-            return event.getDisplayId() == mDisplayId;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("Matching to displayId " + mDisplayId);
-        }
-    }
-
-    static class EventWindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
-        private int mWindowId;
-
-        EventWindowIdMatcher(int windowId) {
-            super();
-            mWindowId = windowId;
-        }
-
-        static EventWindowIdMatcher eventWindowId(int windowId) {
-            return new EventWindowIdMatcher(windowId);
-        }
-
-        @Override
-        protected boolean matchesSafely(AccessibilityEvent event) {
-            return event.getWindowId() == mWindowId;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("Matching to windowId " + mWindowId);
-        }
-    }
-
-    static class WindowChangesMatcher extends TypeSafeMatcher<AccessibilityEvent> {
-        private int mWindowChanges;
-
-        WindowChangesMatcher(int windowChanges) {
-            super();
-            mWindowChanges = windowChanges;
-        }
-
-        static WindowChangesMatcher a11yWindowChanges(int windowChanges) {
-            return new WindowChangesMatcher(windowChanges);
-        }
-
-        @Override
-        protected boolean matchesSafely(AccessibilityEvent event) {
-            return event.getWindowChanges() == mWindowChanges;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("Matching to window changes " + mWindowChanges);
-        }
-    }
-
-    static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityWindowInfo> {
-        private final int mWindowId;
-
-        WindowIdMatcher(int windowId) {
-            super();
-            mWindowId = windowId;
-        }
-
-        static WindowIdMatcher windowId(int windowId) {
-            return new WindowIdMatcher(windowId);
-        }
-
-        @Override
-        protected boolean matchesSafely(AccessibilityWindowInfo window) {
-            return window.getId() == mWindowId;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("Matching to windowId " + mWindowId);
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
index 7e0c12a..ac27a97 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
@@ -21,7 +21,6 @@
 import static com.android.server.accessibility.Flags.FLAG_MAGNIFICATION_ENLARGE_POINTER_BUGFIX;
 import static com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationInfoChangedCallback;
 import static com.android.server.accessibility.magnification.MockMagnificationConnection.TEST_DISPLAY;
-import static com.android.window.flags.Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -308,7 +307,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER)
     public void testSetScale_noConnection_doNothing() {
         register(TEST_DISPLAY);
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index f0d3456..c878799 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -57,10 +57,6 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
-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.provider.Settings;
 import android.test.mock.MockContentResolver;
 import android.testing.DexmakerShareClassLoaderRule;
@@ -82,7 +78,6 @@
 import com.android.server.accessibility.test.MessageCapturingHandler;
 import com.android.server.input.InputManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
-import com.android.window.flags.Flags;
 
 import org.junit.After;
 import org.junit.Before;
@@ -101,9 +96,6 @@
 @RunWith(AndroidJUnit4.class)
 public class MagnificationControllerTest {
 
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
     private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
     private static final int TEST_SERVICE_ID = 1;
     private static final Region INITIAL_SCREEN_MAGNIFICATION_REGION =
@@ -1365,8 +1357,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER)
-    public void onFullscreenMagnificationActivationState_systemUiBorderFlagOn_notifyConnection() {
+    public void onFullscreenMagnificationActivationState_notifyConnection() {
         mMagnificationController.onFullScreenMagnificationActivationState(
                 TEST_DISPLAY, /* activated= */ true);
 
@@ -1374,17 +1365,6 @@
                 .onFullscreenMagnificationActivationChanged(TEST_DISPLAY, /* activated= */ true);
     }
 
-    @Test
-    @RequiresFlagsDisabled(Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER)
-    public void
-            onFullscreenMagnificationActivationState_systemUiBorderFlagOff_neverNotifyConnection() {
-        mMagnificationController.onFullScreenMagnificationActivationState(
-                TEST_DISPLAY, /* activated= */ true);
-
-        verify(mMagnificationConnectionManager, never())
-                .onFullscreenMagnificationActivationChanged(TEST_DISPLAY, /* activated= */ true);
-    }
-
     private void setMagnificationEnabled(int mode) throws RemoteException {
         setMagnificationEnabled(mode, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y);
     }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index cf5dc4b..30aa8ce 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -4404,6 +4404,7 @@
     }
 
     @Test
+    @Ignore("b/277916462")
     public void testSetAutoTimeEnabledModifiesSetting() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -4415,6 +4416,7 @@
     }
 
     @Test
+    @Ignore("b/277916462")
     public void testSetAutoTimeEnabledWithPOOnUser0() throws Exception {
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         setupProfileOwnerOnUser0();
@@ -4434,7 +4436,7 @@
     }
 
     @Test
-    @Ignore("b/359188869")
+    @Ignore("b/277916462")
     public void testSetAutoTimeEnabledWithPOOfOrganizationOwnedDevice() throws Exception {
         setupProfileOwner();
         configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
@@ -5034,8 +5036,6 @@
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_SECONDARY_LOCKSCREEN_API_ENABLED)
     public void testSetSecondaryLockscreenEnabled() throws Exception {
-        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
-
         verifySetSecondaryLockscreenEnabled(false);
         verifySetSecondaryLockscreenEnabled(true);
     }
@@ -5043,6 +5043,10 @@
     private void verifySetSecondaryLockscreenEnabled(boolean enabled) throws Exception {
         reset(getServices().supervisionManagerInternal);
 
+        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+        doReturn(DpmMockContext.CALLER_UID).when(getServices().packageManagerInternal)
+                .getPackageUid(any(), anyLong(), anyInt());
+
         dpm.setSecondaryLockscreenEnabled(admin1, enabled);
         verify(getServices().supervisionManagerInternal).setSupervisionLockscreenEnabledForUser(
                 CALLER_USER_HANDLE, enabled, null);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
index c7574bd..dd4101e 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
@@ -41,11 +41,14 @@
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiPortInfo;
 import android.hardware.tv.cec.V1_0.SendMessageResult;
+import android.media.tv.flags.Flags;
 import android.os.Binder;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.test.TestLooper;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.stats.hdmi.HdmiStatsEnums;
 
 import androidx.test.InstrumentationRegistry;
@@ -54,6 +57,7 @@
 import com.android.server.SystemService;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -83,6 +87,9 @@
     private HdmiEarcController mHdmiEarcController;
     private FakeEarcNativeWrapper mEarcNativeWrapper;
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     @Before
     public void setUp() throws RemoteException {
         mHdmiCecAtomWriterSpy = spy(new HdmiCecAtomWriter());
@@ -232,7 +239,8 @@
                         HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
                         HdmiStatsEnums.VOLUME_MUTE,
                         HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
-                        HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN);
+                        HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+                        HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
     }
 
     @Test
@@ -258,7 +266,8 @@
                         HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
                         HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
                         HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
-                        HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN);
+                        HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+                        HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
     }
 
     @Test
@@ -285,7 +294,8 @@
                         HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
                         HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
                         Constants.MESSAGE_RECORD_ON,
-                        HdmiStatsEnums.UNRECOGNIZED_OPCODE);
+                        HdmiStatsEnums.UNRECOGNIZED_OPCODE,
+                        HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
     }
 
     @Test
@@ -311,7 +321,8 @@
                         HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
                         HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
                         HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
-                        HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN);
+                        HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+                        HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
     }
 
     @Test
@@ -337,6 +348,59 @@
     }
 
     @Test
+    @EnableFlags({Flags.FLAG_HDMI_CONTROL_COLLECT_PHYSICAL_ADDRESS})
+    public void testMessageReported_writesAtom_reportPhysicalAddress() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
+                ADDR_PLAYBACK_1, 0x1234, HdmiDeviceInfo.DEVICE_PLAYBACK);
+
+        mHdmiCecAtomWriterSpy.messageReported(
+                message,
+                HdmiStatsEnums.INCOMING,
+                1234);
+
+        verify(mHdmiCecAtomWriterSpy, times(1))
+                .writeHdmiCecMessageReportedAtom(
+                        1234,
+                        HdmiStatsEnums.INCOMING,
+                        Constants.ADDR_PLAYBACK_1,
+                        Constants.ADDR_BROADCAST,
+                        Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS,
+                        HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
+                        HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
+                        HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
+                        HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+                        0x1234);
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_HDMI_CONTROL_COLLECT_PHYSICAL_ADDRESS})
+    public void testMessageReported_writesAtom_reportPhysicalAddress_noParams() {
+        HdmiCecMessage message = HdmiCecMessage.build(
+                Constants.ADDR_PLAYBACK_1,
+                Constants.ADDR_BROADCAST,
+                Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS,
+                new byte[0]);
+
+        mHdmiCecAtomWriterSpy.messageReported(
+                message,
+                HdmiStatsEnums.INCOMING,
+                1234);
+
+        verify(mHdmiCecAtomWriterSpy, times(1))
+                .writeHdmiCecMessageReportedAtom(
+                        1234,
+                        HdmiStatsEnums.INCOMING,
+                        Constants.ADDR_PLAYBACK_1,
+                        Constants.ADDR_BROADCAST,
+                        Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS,
+                        HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN,
+                        HdmiStatsEnums.USER_CONTROL_PRESSED_COMMAND_UNKNOWN,
+                        HdmiCecAtomWriter.FEATURE_ABORT_OPCODE_UNKNOWN,
+                        HdmiStatsEnums.FEATURE_ABORT_REASON_UNKNOWN,
+                        HdmiCecAtomWriter.PHYSICAL_ADDRESS_INVALID);
+    }
+
+    @Test
     public void testDsmStatusChanged_onWakeUp_ArcSupported_writesAtom_logReasonWake() {
         mHdmiControlServiceSpy.setSoundbarMode(HdmiControlManager.SOUNDBAR_MODE_DISABLED);
         Mockito.clearInvocations(mHdmiCecAtomWriterSpy);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 51276a4..5be4490 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -28,7 +28,7 @@
 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE;
 import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF;
 import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;
-import static com.android.server.hdmi.RequestActiveSourceAction.TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS;
+import static com.android.server.hdmi.RequestActiveSourceAction.TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS;
 import static com.android.server.hdmi.RoutingControlAction.TIMEOUT_ROUTING_INFORMATION_MS;
 import static com.android.server.hdmi.RequestSadAction.RETRY_COUNTER_MAX;
 
@@ -118,6 +118,7 @@
     private boolean mDisableCecOnStandbyByLowEnergyMode;
     private boolean mWasCecDisabledOnStandbyByLowEnergyMode;
     private boolean mUseHdmiCecPowerStatusController;
+    private boolean mUserEnabledCecInOfflineMode;
 
     private class DeviceEventListener {
         private HdmiDeviceInfo mDevice;
@@ -250,6 +251,11 @@
                     protected void setWasCecDisabledOnStandbyByLowEnergyMode(boolean value) {
                         mWasCecDisabledOnStandbyByLowEnergyMode = value;
                     }
+
+                    @Override
+                    protected boolean userEnabledCecInOfflineMode() {
+                        return mUserEnabledCecInOfflineMode;
+                    }
                 };
 
         mHdmiControlService.setIoLooper(mMyLooper);
@@ -298,6 +304,7 @@
         mWasCecDisabledOnStandbyByLowEnergyMode = false;
         mDisableCecOnStandbyByLowEnergyMode = false;
         mUseHdmiCecPowerStatusController = false;
+        mUserEnabledCecInOfflineMode = false;
         mNativeWrapper.clearResultMessages();
     }
 
@@ -1877,7 +1884,7 @@
         mTestLooper.dispatchAll();
 
         // Skip the LauncherX API timeout.
-        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
         mTestLooper.dispatchAll();
 
         assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource);
@@ -1910,7 +1917,7 @@
         mTestLooper.dispatchAll();
 
         // Skip the LauncherX API timeout.
-        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
         mTestLooper.dispatchAll();
 
         assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource);
@@ -1946,7 +1953,7 @@
         mTestLooper.dispatchAll();
 
         // Skip the LauncherX API timeout.
-        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
         mTestLooper.dispatchAll();
 
         assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource);
@@ -1989,7 +1996,7 @@
         mTestLooper.dispatchAll();
 
         // Skip the LauncherX API timeout.
-        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
         mTestLooper.dispatchAll();
 
         assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource);
@@ -2026,7 +2033,7 @@
         mHdmiControlService.sendCecCommand(setStreamPathFromTv);
 
         // Skip the LauncherX API timeout.
-        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+        mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
         mTestLooper.dispatchAll();
 
         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestActiveSource);
@@ -2400,6 +2407,32 @@
         assertTrue(mVendorCommandListeners.contains(vendorCommandListenerInvocationSettingChange));
     }
 
+    @Test
+    public void lowEnergyMode_userEnabledCecInOfflineMode_onStandby_cecStaysEnabled() {
+        mDisableCecOnStandbyByLowEnergyMode = true;
+        mUseHdmiCecPowerStatusController = true;
+        mUserEnabledCecInOfflineMode = true;
+        mPowerManager.setIsLowPowerStandbyEnabled(true);
+
+        assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue(
+                        HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED),
+                HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlService.onStandby(STANDBY_SCREEN_OFF);
+        mTestLooper.dispatchAll();
+
+        assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue(
+                        HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED),
+                HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        assertFalse(mWasCecDisabledOnStandbyByLowEnergyMode);
+        mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON);
+        mTestLooper.dispatchAll();
+
+        assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue(
+                        HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED),
+                HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        assertFalse(mWasCecDisabledOnStandbyByLowEnergyMode);
+    }
+
     protected static class MockTvDevice extends HdmiCecLocalDeviceTv {
         MockTvDevice(HdmiControlService service) {
             super(service);
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index b2a7d20..3ced56a 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -67,10 +67,12 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Rect;
 import android.media.projection.IMediaProjection;
 import android.media.projection.IMediaProjectionCallback;
 import android.media.projection.IMediaProjectionWatcherCallback;
 import android.media.projection.ReviewGrantedConsentResult;
+import android.media.projection.StopReason;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Looper;
@@ -549,7 +551,7 @@
         MediaProjectionManagerService.MediaProjection projection =
                 startProjectionPreconditions(service);
 
-        projection.stop();
+        projection.stop(StopReason.STOP_UNKNOWN);
 
         verifyZeroInteractions(mMediaProjectionMetricsLogger);
     }
@@ -562,10 +564,10 @@
                 startProjectionPreconditions(service);
         projection.start(mIMediaProjectionCallback);
 
-        projection.stop();
+        final @StopReason int stopReason = StopReason.STOP_UNKNOWN;
+        projection.stop(stopReason);
 
-        verify(mMediaProjectionMetricsLogger)
-                .logStopped(UID, TARGET_UID_UNKNOWN);
+        verify(mMediaProjectionMetricsLogger).logStopped(UID, TARGET_UID_UNKNOWN, stopReason);
     }
 
     @Test
@@ -580,15 +582,16 @@
                 .setContentRecordingSession(any(ContentRecordingSession.class));
         service.setContentRecordingSession(DISPLAY_SESSION);
 
-        projection.stop();
+        final @StopReason int stopReason = StopReason.STOP_UNKNOWN;
+        projection.stop(stopReason);
 
-        verify(mMediaProjectionMetricsLogger)
-                .logStopped(UID, TARGET_UID_FULL_SCREEN);
+        verify(mMediaProjectionMetricsLogger).logStopped(UID, TARGET_UID_FULL_SCREEN, stopReason);
     }
 
     @Test
     public void stop_taskSession_logsHostUidAndTargetUid() throws Exception {
         int targetUid = 1234;
+        int stopReason = StopReason.STOP_UNKNOWN;
         MediaProjectionManagerService service =
                 new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
         MediaProjectionManagerService.MediaProjection projection =
@@ -601,9 +604,9 @@
         taskSession.setTargetUid(targetUid);
         service.setContentRecordingSession(taskSession);
 
-        projection.stop();
+        projection.stop(stopReason);
 
-        verify(mMediaProjectionMetricsLogger).logStopped(UID, targetUid);
+        verify(mMediaProjectionMetricsLogger).logStopped(UID, targetUid, stopReason);
     }
 
     @Test
@@ -638,7 +641,7 @@
         projection.start(mIMediaProjectionCallback);
         assertThat(projection.isValid()).isTrue();
 
-        projection.stop();
+        projection.stop(StopReason.STOP_UNKNOWN);
 
         // Second start - so not valid.
         projection.start(mIMediaProjectionCallback);
@@ -692,7 +695,7 @@
         MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(
                 service);
         projection.start(mIMediaProjectionCallback);
-        projection.stop();
+        projection.stop(StopReason.STOP_UNKNOWN);
         // Second start - so not valid.
         projection.start(mIMediaProjectionCallback);
 
@@ -708,7 +711,7 @@
         MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(
                 service);
         projection.start(mIMediaProjectionCallback);
-        projection.stop();
+        projection.stop(StopReason.STOP_UNKNOWN);
 
         // Second start - so not valid.
         projection.start(mIMediaProjectionCallback);
@@ -947,6 +950,26 @@
                 projection.uid, targetUid, WINDOWING_MODE_MULTI_WINDOW);
     }
 
+    @Test
+    public void notifyCaptureBoundsChanged_forwardsToLoggerAndResizeCallbacks() throws Exception {
+        int targetUid = 123;
+        mService =
+                new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
+
+        ContentRecordingSession taskSession = createTaskSession(mock(IBinder.class));
+        taskSession.setTargetUid(targetUid);
+        mService.setContentRecordingSession(taskSession);
+
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.start(mIMediaProjectionCallback);
+
+        Rect newBounds = new Rect(0, 0, 1000, 2000);
+        mService.notifyCaptureBoundsChanged(RECORD_CONTENT_TASK, targetUid, newBounds);
+
+        verify(mMediaProjectionMetricsLogger)
+                .logChangedCaptureBounds(RECORD_CONTENT_TASK, projection.uid, targetUid, newBounds);
+    }
+
     /**
      * Executes and validates scenario where the consent result indicates the projection ends.
      */
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java
index 72ce9fe..c727bb6 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java
@@ -32,6 +32,17 @@
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_DEVICE_LOCK;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_ERROR;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_FOREGROUND_SERVICE_CHANGE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_HOST_APP_STOP;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_MEDIA_ROUTE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_PROJECTION;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_QS_TILE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_STATUS_BAR_CHIP_STOP;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_TASK_APP_CLOSE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_USER_SWITCH;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_APP_TASK;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_DISPLAY;
 import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN;
@@ -46,6 +57,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.media.projection.StopReason;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -81,6 +93,7 @@
 
     private static final int TEST_WINDOWING_MODE = 987;
     private static final int TEST_CONTENT_TO_RECORD = 654;
+    private static final int TEST_STOP_SOURCE = 321;
 
     @Mock private FrameworkStatsLogWrapper mFrameworkStatsLogWrapper;
     @Mock private MediaProjectionSessionIdGenerator mSessionIdGenerator;
@@ -136,6 +149,14 @@
     }
 
     @Test
+    public void logInitiated_logsUnknownStopSource() {
+        mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
+
+        verifyStopSourceLogged(
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+    }
+
+    @Test
     public void logInitiated_noPreviousSession_logsUnknownTimeSinceLastActive() {
         when(mTimestampStore.timeSinceLastActiveSession()).thenReturn(null);
 
@@ -177,7 +198,7 @@
 
     @Test
     public void logStopped_logsStateChangedAtomId() {
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
 
         verifyStateChangedAtomIdLogged();
     }
@@ -187,42 +208,49 @@
         int currentSessionId = 987;
         when(mSessionIdGenerator.getCurrentSessionId()).thenReturn(currentSessionId);
 
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
 
         verifySessionIdLogged(currentSessionId);
     }
 
     @Test
     public void logStopped_logsStateStopped() {
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
 
         verifyStateLogged(MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED);
     }
 
     @Test
     public void logStopped_logsHostUid() {
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
 
         verifyStateChangedHostUidLogged(TEST_HOST_UID);
     }
 
     @Test
     public void logStopped_logsTargetUid() {
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
 
         verifyStageChangedTargetUidLogged(TEST_TARGET_UID);
     }
 
     @Test
+    public void logStopped_logsStopSource() {
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, StopReason.STOP_UNKNOWN);
+
+        verifyStopSourceLogged(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+    }
+
+    @Test
     public void logStopped_logsUnknownTimeSinceLastActive() {
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
 
         verifyTimeSinceLastActiveSessionLogged(-1);
     }
 
     @Test
     public void logStopped_logsUnknownSessionCreationSource() {
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
 
         verifyCreationSourceLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
@@ -230,7 +258,7 @@
 
     @Test
     public void logStopped_logsPreviousState() {
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
         verifyPreviousStateLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN);
 
@@ -238,7 +266,7 @@
         verifyPreviousStateLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED);
 
-        mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE);
+        mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE, TEST_STOP_SOURCE);
         verifyPreviousStateLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
     }
@@ -247,14 +275,14 @@
     public void logStopped_capturingWasInProgress_registersActiveSessionEnded() {
         mLogger.logInProgress(TEST_HOST_UID, TEST_TARGET_UID);
 
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
 
         verify(mTimestampStore).registerActiveSessionEnded();
     }
 
     @Test
     public void logStopped_capturingWasNotInProgress_doesNotRegistersActiveSessionEnded() {
-        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+        mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
 
         verify(mTimestampStore, never()).registerActiveSessionEnded();
     }
@@ -314,6 +342,14 @@
     }
 
     @Test
+    public void logInProgress_logsUnknownSessionStopSource() {
+        mLogger.logInProgress(TEST_HOST_UID, TEST_TARGET_UID);
+
+        verifyStopSourceLogged(
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+    }
+
+    @Test
     public void logInProgress_logsPreviousState() {
         mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
         verifyPreviousStateLogged(
@@ -323,7 +359,7 @@
         verifyPreviousStateLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
 
-        mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE);
+        mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE, TEST_STOP_SOURCE);
         verifyPreviousStateLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS);
 
@@ -387,6 +423,14 @@
     }
 
     @Test
+    public void logPermissionRequestDisplayed_logsUnknownSessionStopSource() {
+        mLogger.logPermissionRequestDisplayed(TEST_HOST_UID);
+
+        verifyStopSourceLogged(
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+    }
+
+    @Test
     public void logPermissionRequestDisplayed_logsPreviousState() {
         mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
         verifyPreviousStateLogged(
@@ -396,7 +440,7 @@
         verifyPreviousStateLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
 
-        mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE);
+        mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE, TEST_STOP_SOURCE);
         verifyPreviousStateLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED);
 
@@ -460,6 +504,14 @@
     }
 
     @Test
+    public void logAppSelectorDisplayed_logsUnknownSessionStopSource() {
+        mLogger.logAppSelectorDisplayed(TEST_HOST_UID);
+
+        verifyStopSourceLogged(
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+    }
+
+    @Test
     public void logAppSelectorDisplayed_logsPreviousState() {
         mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
         verifyPreviousStateLogged(
@@ -469,7 +521,7 @@
         verifyPreviousStateLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
 
-        mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE);
+        mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE, TEST_STOP_SOURCE);
         verifyPreviousStateLogged(
                 MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_APP_SELECTOR_DISPLAYED);
 
@@ -536,6 +588,14 @@
     }
 
     @Test
+    public void logProjectionPermissionRequestCancelled_logsUnknownStopSource() {
+        mLogger.logProjectionPermissionRequestCancelled(TEST_HOST_UID);
+
+        verifyStopSourceLogged(
+                MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+    }
+
+    @Test
     public void logWindowingModeChanged_logsTargetChangedAtomId() {
         mLogger.logChangedWindowingMode(
                 TEST_CONTENT_TO_RECORD, TEST_HOST_UID, TEST_TARGET_UID, TEST_WINDOWING_MODE);
@@ -614,6 +674,42 @@
                 .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_UNKNOWN);
     }
 
+    @Test
+    public void testStopReasonToSessionStopSource() {
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_HOST_APP))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_HOST_APP_STOP);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_TARGET_REMOVED))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_TASK_APP_CLOSE);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_DEVICE_LOCKED))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_DEVICE_LOCK);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_PRIVACY_CHIP))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_STATUS_BAR_CHIP_STOP);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_QS_TILE))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_QS_TILE);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_USER_SWITCH))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_USER_SWITCH);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_FOREGROUND_SERVICE_CHANGE))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_FOREGROUND_SERVICE_CHANGE);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_NEW_PROJECTION))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_PROJECTION);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_NEW_MEDIA_ROUTE))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_MEDIA_ROUTE);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_ERROR))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_ERROR);
+
+        mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_UNKNOWN))
+                .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+    }
+
     private void verifyStateChangedAtomIdLogged() {
         verify(mFrameworkStatsLogWrapper)
                 .writeStateChanged(
@@ -624,7 +720,8 @@
                         /* hostUid= */ anyInt(),
                         /* targetUid= */ anyInt(),
                         /* timeSinceLastActive= */ anyInt(),
-                        /* creationSource= */ anyInt());
+                        /* creationSource= */ anyInt(),
+                        /* stopSource= */ anyInt());
     }
 
     private void verifyStateLogged(int state) {
@@ -637,7 +734,8 @@
                         /* hostUid= */ anyInt(),
                         /* targetUid= */ anyInt(),
                         /* timeSinceLastActive= */ anyInt(),
-                        /* creationSource= */ anyInt());
+                        /* creationSource= */ anyInt(),
+                        /* stopSource= */ anyInt());
     }
 
     private void verifyStateChangedHostUidLogged(int hostUid) {
@@ -650,7 +748,8 @@
                         eq(hostUid),
                         /* targetUid= */ anyInt(),
                         /* timeSinceLastActive= */ anyInt(),
-                        /* creationSource= */ anyInt());
+                        /* creationSource= */ anyInt(),
+                        /* stopSource= */ anyInt());
     }
 
     private void verifyCreationSourceLogged(int creationSource) {
@@ -663,7 +762,22 @@
                         /* hostUid= */ anyInt(),
                         /* targetUid= */ anyInt(),
                         /* timeSinceLastActive= */ anyInt(),
-                        eq(creationSource));
+                        eq(creationSource),
+                        /* stopSource= */ anyInt());
+    }
+
+    private void verifyStopSourceLogged(int stopSource) {
+        verify(mFrameworkStatsLogWrapper)
+                .writeStateChanged(
+                        /* code= */ anyInt(),
+                        /* sessionId= */ anyInt(),
+                        /* state= */ anyInt(),
+                        /* previousState= */ anyInt(),
+                        /* hostUid= */ anyInt(),
+                        /* targetUid= */ anyInt(),
+                        /* timeSinceLastActive= */ anyInt(),
+                        /* stopSource= */ anyInt(),
+                        eq(stopSource));
     }
 
     private void verifyStageChangedTargetUidLogged(int targetUid) {
@@ -676,7 +790,8 @@
                         /* hostUid= */ anyInt(),
                         eq(targetUid),
                         /* timeSinceLastActive= */ anyInt(),
-                        /* creationSource= */ anyInt());
+                        /* creationSource= */ anyInt(),
+                        /* stopSource= */ anyInt());
     }
 
     private void verifyTimeSinceLastActiveSessionLogged(int timeSinceLastActiveSession) {
@@ -689,7 +804,8 @@
                         /* hostUid= */ anyInt(),
                         /* targetUid= */ anyInt(),
                         /* timeSinceLastActive= */ eq(timeSinceLastActiveSession),
-                        /* creationSource= */ anyInt());
+                        /* creationSource= */ anyInt(),
+                        /* stopSource= */ anyInt());
     }
 
     private void verifySessionIdLogged(int newSessionId) {
@@ -702,7 +818,8 @@
                         /* hostUid= */ anyInt(),
                         /* targetUid= */ anyInt(),
                         /* timeSinceLastActive= */ anyInt(),
-                        /* creationSource= */ anyInt());
+                        /* creationSource= */ anyInt(),
+                        /* stopSource= */ anyInt());
     }
 
     private void verifyPreviousStateLogged(int previousState) {
@@ -715,7 +832,8 @@
                         /* hostUid= */ anyInt(),
                         /* targetUid= */ anyInt(),
                         /* timeSinceLastActive= */ anyInt(),
-                        /* creationSource= */ anyInt());
+                        /* creationSource= */ anyInt(),
+                        /* stopSource= */ anyInt());
     }
 
     private void verifyTargetChangedAtomIdLogged() {
@@ -726,7 +844,12 @@
                         /* targetType= */ anyInt(),
                         /* hostUid= */ anyInt(),
                         /* targetUid= */ anyInt(),
-                        /* targetWindowingMode= */ anyInt());
+                        /* targetWindowingMode= */ anyInt(),
+                        /* width= */ anyInt(),
+                        /* height= */ anyInt(),
+                        /* centerX= */ anyInt(),
+                        /* centerY= */ anyInt(),
+                        /* targetChangeType= */ anyInt());
     }
 
     private void verifyTargetTypeLogged(int targetType) {
@@ -737,7 +860,12 @@
                         eq(targetType),
                         /* hostUid= */ anyInt(),
                         /* targetUid= */ anyInt(),
-                        /* targetWindowingMode= */ anyInt());
+                        /* targetWindowingMode= */ anyInt(),
+                        /* width= */ anyInt(),
+                        /* height= */ anyInt(),
+                        /* centerX= */ anyInt(),
+                        /* centerY= */ anyInt(),
+                        /* targetChangeType= */ anyInt());
     }
 
     private void verifyTargetChangedHostUidLogged(int hostUid) {
@@ -748,7 +876,12 @@
                         /* targetType= */ anyInt(),
                         eq(hostUid),
                         /* targetUid= */ anyInt(),
-                        /* targetWindowingMode= */ anyInt());
+                        /* targetWindowingMode= */ anyInt(),
+                        /* width= */ anyInt(),
+                        /* height= */ anyInt(),
+                        /* centerX= */ anyInt(),
+                        /* centerY= */ anyInt(),
+                        /* targetChangeType= */ anyInt());
     }
 
     private void verifyTargetChangedTargetUidLogged(int targetUid) {
@@ -759,7 +892,12 @@
                         /* targetType= */ anyInt(),
                         /* hostUid= */ anyInt(),
                         eq(targetUid),
-                        /* targetWindowingMode= */ anyInt());
+                        /* targetWindowingMode= */ anyInt(),
+                        /* width= */ anyInt(),
+                        /* height= */ anyInt(),
+                        /* centerX= */ anyInt(),
+                        /* centerY= */ anyInt(),
+                        /* targetChangeType= */ anyInt());
     }
 
     private void verifyWindowingModeLogged(int targetWindowingMode) {
@@ -770,6 +908,11 @@
                         /* targetType= */ anyInt(),
                         /* hostUid= */ anyInt(),
                         /* targetUid= */ anyInt(),
-                        eq(targetWindowingMode));
+                        eq(targetWindowingMode),
+                        /* width= */ anyInt(),
+                        /* height= */ anyInt(),
+                        /* centerX= */ anyInt(),
+                        /* centerY= */ anyInt(),
+                        /* targetChangeType= */ anyInt());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 3e748ff..2c1e37b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -52,6 +52,7 @@
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IIntentSender;
 import android.content.Intent;
@@ -273,6 +274,11 @@
         public String getPackageName() {
             return SYSTEM_PACKAGE_NAME;
         }
+
+        @Override
+        public ContentResolver getContentResolver() {
+            return mContentResolver;
+        }
     }
 
     /** ShortcutService with injection override methods. */
@@ -665,6 +671,7 @@
 
     protected ServiceContext mServiceContext;
     protected ClientContext mClientContext;
+    protected ContentResolver mContentResolver;
 
     protected ShortcutServiceTestable mService;
     protected ShortcutManagerTestable mManager;
@@ -861,6 +868,7 @@
 
         mServiceContext = spy(new ServiceContext());
         mClientContext = new ClientContext();
+        mContentResolver = mock(ContentResolver.class);
 
         mMockPackageManager = mock(PackageManager.class);
         mMockPackageManagerInternal = mock(PackageManagerInternal.class);
@@ -982,6 +990,8 @@
                     }
                     return userProperties;
                 });
+        when(mMockUserManagerInternal.getUserInfos()).thenReturn(
+                mUserInfos.values().toArray(new UserInfo[0]));
 
         // User 0 and P0 are always running
         mRunningUsers.put(USER_0, true);
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerCacheTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerCacheTest.java
new file mode 100644
index 0000000..d69e476
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerCacheTest.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.app.ActivityManager;
+import android.app.LocaleManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.multiuser.Flags;
+import android.os.LocaleList;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.platform.test.annotations.Postsubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.util.ArraySet;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+/**
+ * Test {@link UserManager Cache} functionality.
+ *
+ * atest com.android.server.pm.UserManagerCacheTest
+ */
+@Postsubmit
+@RunWith(AndroidJUnit4.class)
+public final class UserManagerCacheTest {
+
+    private static final LocaleList TEST_LOCALE_LIST = LocaleList.forLanguageTags("pl-PL");
+    private static final long SLEEP_TIMEOUT = 5_000;
+    private static final int REMOVE_USER_TIMEOUT_SECONDS = 180; // 180 seconds
+    private static final String TAG = UserManagerCacheTest.class.getSimpleName();
+
+    private final Context mContext =
+            InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+    private UserManager mUserManager = null;
+    private PackageManager mPackageManager;
+    private LocaleManager mLocaleManager;
+    private ArraySet<Integer> mUsersToRemove;
+    private UserRemovalWaiter mUserRemovalWaiter;
+    private int mOriginalCurrentUserId;
+    private LocaleList mSystemLocales;
+
+    @Before
+    public void setUp() throws Exception {
+        mOriginalCurrentUserId = ActivityManager.getCurrentUser();
+        mUserManager = UserManager.get(mContext);
+        mPackageManager = mContext.getPackageManager();
+        mLocaleManager = mContext.getSystemService(LocaleManager.class);
+        mSystemLocales = mLocaleManager.getSystemLocales();
+        mUserRemovalWaiter = new UserRemovalWaiter(mContext, TAG, REMOVE_USER_TIMEOUT_SECONDS);
+        mUsersToRemove = new ArraySet<>();
+        removeExistingUsers();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // Making a copy of mUsersToRemove to avoid ConcurrentModificationException
+        mUsersToRemove.stream().toList().forEach(this::removeUser);
+        mUserRemovalWaiter.close();
+        mUserManager.setUserRestriction(UserManager.DISALLOW_GRANT_ADMIN, false,
+                mContext.getUser());
+        mLocaleManager.setSystemLocales(mSystemLocales);
+    }
+
+    private void removeExistingUsers() {
+        int currentUser = ActivityManager.getCurrentUser();
+
+        UserHandle communalProfile = mUserManager.getCommunalProfile();
+        int communalProfileId = communalProfile != null
+                ? communalProfile.getIdentifier() : UserHandle.USER_NULL;
+
+        List<UserInfo> list = mUserManager.getUsers();
+        for (UserInfo user : list) {
+            // Keep system and current user
+            if (user.id != UserHandle.USER_SYSTEM
+                    && user.id != currentUser
+                    && user.id != communalProfileId
+                    && !user.isMain()) {
+                removeUser(user.id);
+            }
+        }
+    }
+
+    @MediumTest
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_CACHE_USER_INFO_READ_ONLY)
+    public void testUserInfoAfterLocaleChange() throws Exception {
+        UserInfo userInfo = mUserManager.createGuest(mContext);
+        mUsersToRemove.add(userInfo.id);
+        assertThat(userInfo).isNotNull();
+
+        UserInfo guestUserInfo = mUserManager.getUserInfo(userInfo.id);
+        assertThat(guestUserInfo).isNotNull();
+        assertThat(guestUserInfo.name).isNotEqualTo("Gość");
+
+        UserInfo ownerUserInfo = mUserManager.getUserInfo(mOriginalCurrentUserId);
+        assertThat(ownerUserInfo).isNotNull();
+        assertThat(ownerUserInfo.name).isNotEqualTo("Właściciel");
+
+        mLocaleManager.setSystemLocales(TEST_LOCALE_LIST);
+        SystemClock.sleep(SLEEP_TIMEOUT);
+        UserInfo guestUserInfoPl = mUserManager.getUserInfo(userInfo.id);
+        UserInfo ownerUserInfoPl = mUserManager.getUserInfo(mOriginalCurrentUserId);
+
+        assertThat(guestUserInfoPl).isNotNull();
+        assertThat(guestUserInfoPl.name).isEqualTo("Gość");
+
+        assertThat(ownerUserInfoPl).isNotNull();
+        assertThat(ownerUserInfoPl.name).isEqualTo("Właściciel");
+    }
+
+
+    @MediumTest
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_CACHE_USER_INFO_READ_ONLY)
+    public void testGetUserInfo10kSpam() throws Exception {
+        UserInfo cachedUserInfo = mUserManager.getUserInfo(mOriginalCurrentUserId);
+        for (int i = 0; i < 10000; i++) {
+            // Control how often cache is calling the API
+            UserInfo ownerUserInfo = mUserManager.getUserInfo(mOriginalCurrentUserId);
+            assertThat(ownerUserInfo).isNotNull();
+            // If indeed it was chached then objects should stay the same. We use == to compare
+            // object addresses to make sure UserInfo is not new copy of the same UserInfo.
+            assertThat(cachedUserInfo.toFullString()).isEqualTo(ownerUserInfo.toFullString());
+        }
+    }
+
+
+    @MediumTest
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_CACHE_USER_INFO_READ_ONLY)
+    public void testSetUserAdmin() throws Exception {
+        UserInfo userInfo = mUserManager.createUser("SecondaryUser",
+                UserManager.USER_TYPE_FULL_SECONDARY, /*flags=*/ 0);
+        mUsersToRemove.add(userInfo.id);
+        // cache user
+        UserInfo cachedUserInfo = mUserManager.getUserInfo(userInfo.id);
+
+        assertThat(userInfo.isAdmin()).isFalse();
+        assertThat(cachedUserInfo.isAdmin()).isFalse();
+
+        // invalidate cache
+        mUserManager.setUserAdmin(userInfo.id);
+
+        // updated UserInfo should be returned
+        cachedUserInfo = mUserManager.getUserInfo(userInfo.id);
+        assertThat(cachedUserInfo.isAdmin()).isTrue();
+    }
+
+
+    @MediumTest
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_CACHE_USER_INFO_READ_ONLY)
+    public void testRevokeUserAdmin() throws Exception {
+        UserInfo userInfo = mUserManager.createUser("Admin",
+                UserManager.USER_TYPE_FULL_SECONDARY, /*flags=*/ UserInfo.FLAG_ADMIN);
+        mUsersToRemove.add(userInfo.id);
+        // cache user
+        UserInfo cachedUserInfo = mUserManager.getUserInfo(userInfo.id);
+        assertThat(userInfo.isAdmin()).isTrue();
+        assertThat(cachedUserInfo.isAdmin()).isTrue();
+
+        // invalidate cache
+        mUserManager.revokeUserAdmin(userInfo.id);
+
+        // updated UserInfo should be returned
+        cachedUserInfo = mUserManager.getUserInfo(userInfo.id);
+        assertThat(cachedUserInfo.isAdmin()).isFalse();
+    }
+
+    @MediumTest
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_CACHE_USER_INFO_READ_ONLY)
+    public void testRevokeUserAdminFromNonAdmin() throws Exception {
+        UserInfo userInfo = mUserManager.createUser("NonAdmin",
+                UserManager.USER_TYPE_FULL_SECONDARY, /*flags=*/ 0);
+        mUsersToRemove.add(userInfo.id);
+        // cache user
+        UserInfo cachedUserInfo = mUserManager.getUserInfo(userInfo.id);
+        assertThat(userInfo.isAdmin()).isFalse();
+        assertThat(cachedUserInfo.isAdmin()).isFalse();
+
+        // invalidate cache
+        mUserManager.revokeUserAdmin(userInfo.id);
+
+        // updated UserInfo should be returned
+        cachedUserInfo = mUserManager.getUserInfo(userInfo.id);
+        assertThat(cachedUserInfo.isAdmin()).isFalse();
+    }
+
+
+    @MediumTest
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_CACHE_USER_INFO_READ_ONLY)
+    public void testSetUserName_withContextUserId() throws Exception {
+        assumeManagedUsersSupported();
+        final String newName = "Managed_user 1";
+        final int mainUserId = mUserManager.getMainUser().getIdentifier();
+
+        // cache main user
+        UserInfo mainUserInfo =  mUserManager.getUserInfo(mainUserId);
+
+        assertThat(mainUserInfo).isNotNull();
+
+        // invalidate cache
+        UserInfo userInfo =  mUserManager.createProfileForUser("Managed 1",
+                UserManager.USER_TYPE_PROFILE_MANAGED,  0, mainUserId, null);
+        mUsersToRemove.add(userInfo.id);
+        // cache user
+        UserInfo cachedUserInfo = mUserManager.getUserInfo(userInfo.id);
+        // updated cache for main user
+        mainUserInfo =  mUserManager.getUserInfo(mainUserId);
+
+        assertThat(userInfo).isNotNull();
+        assertThat(cachedUserInfo).isNotNull();
+        assertThat(mainUserInfo).isNotNull();
+        // profileGroupId are the same after adding profile to user.
+        assertThat(mainUserInfo.profileGroupId).isEqualTo(cachedUserInfo.profileGroupId);
+
+        UserManager um = (UserManager) mContext.createPackageContextAsUser(
+                        "android", 0, userInfo.getUserHandle())
+                .getSystemService(Context.USER_SERVICE);
+        // invalidate cache
+        um.setUserName(newName);
+
+        // updated UserInfo should be returned
+        cachedUserInfo = mUserManager.getUserInfo(userInfo.id);
+        assertThat(cachedUserInfo.name).isEqualTo(newName);
+
+        // get user name from getUserName using context.getUserId
+        assertThat(um.getUserName()).isEqualTo(newName);
+    }
+
+    private void assumeManagedUsersSupported() {
+        // In Automotive, if headless system user is enabled, a managed user cannot be created
+        // under a primary user.
+        assumeTrue("device doesn't support managed users",
+                mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)
+                        && (!isAutomotive() || !UserManager.isHeadlessSystemUserMode()));
+    }
+
+    private void removeUser(int userId) {
+        mUserManager.removeUser(userId);
+        mUserRemovalWaiter.waitFor(userId);
+        mUsersToRemove.remove(userId);
+    }
+
+    private boolean isAutomotive() {
+        return mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
index 24bf6ca..b1df0f1 100644
--- a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
@@ -60,7 +60,7 @@
     public void setup() throws Settings.SettingNotFoundException {
         mContext = mock(Context.class);
         mPermissionEnforcer = new FakePermissionEnforcer();
-        mPermissionEnforcer.grant(Manifest.permission.SET_ADVANCED_PROTECTION_MODE);
+        mPermissionEnforcer.grant(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE);
         mPermissionEnforcer.grant(Manifest.permission.QUERY_ADVANCED_PROTECTION_MODE);
 
         mStore = new AdvancedProtectionService.AdvancedProtectionStore(mContext) {
@@ -299,7 +299,7 @@
 
     @Test
     public void testSetProtection_withoutPermission() {
-        mPermissionEnforcer.revoke(Manifest.permission.SET_ADVANCED_PROTECTION_MODE);
+        mPermissionEnforcer.revoke(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE);
         assertThrows(SecurityException.class, () -> mService.setAdvancedProtectionEnabled(true));
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index 3bc089f..842c441 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -691,6 +691,40 @@
         assertThat(actual).isEqualTo(expected);
     }
 
+    /**
+     * Tests that readPermissions works correctly for the tags:
+     * disabled-in-sku, enabled-in-sku-override.
+     * I.e. that disabled-in-sku add package to block list and
+     * enabled-in-sku-override removes package from the list.
+     */
+    @Test
+    public void testDisablePackageInSku() throws Exception {
+        final String disable_in_sku =
+                "<config>\n"
+                        + "    <disabled-in-sku package=\"com.sony.product1.app\"/>\n"
+                        + "    <disabled-in-sku package=\"com.sony.product2.app\"/>\n"
+                        + "</config>\n";
+
+        final String enable_in_sku_override =
+                "<config>\n"
+                        + "    <enabled-in-sku-override package=\"com.sony.product2.app\"/>\n"
+                        + "</config>\n";
+
+        final File folder1 = createTempSubfolder("folder1");
+        createTempFile(folder1, "permissionFile1.xml", disable_in_sku);
+
+        final File folder2 = createTempSubfolder("folder2");
+        createTempFile(folder2, "permissionFile2.xml", enable_in_sku_override);
+
+        readPermissions(folder1, /* Grant all permission flags */ ~0);
+        readPermissions(folder2, /* Grant all permission flags */ ~0);
+
+        final ArraySet<String> blocklist = mSysConfig.getDisabledUntilUsedPreinstalledCarrierApps();
+
+        assertThat(blocklist).contains("com.sony.product1.app");
+        assertThat(blocklist).doesNotContain("com.sony.product2.app");
+    }
+
     private void parseSharedLibraries(String contents) throws IOException {
         File folder = createTempSubfolder("permissions_folder");
         createTempFile(folder, "permissions.xml", contents);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 6af6542..dd278fc 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -2170,6 +2170,174 @@
     }
 
     @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testRemoveChildNotification_summaryForceGrouped() {
+        // Check that removing all child notifications from a group will trigger empty summary
+        // force grouping re-evaluation
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        // Post summaries without children, below the force grouping limit
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+                    UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(summary);
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        // Post a valid (full) group
+        final int summaryId = 4242;
+        final int numChildren = 3;
+        final ArrayList<NotificationRecord> childrenToRemove = new ArrayList<>();
+        NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+                String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp " + summaryId, true);
+        notificationList.add(summary);
+        summaryByGroup.put(summary.getGroupKey(), summary);
+        for (int i = 0; i < numChildren; i++) {
+            NotificationRecord child = getNotificationRecord(pkg, summaryId + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp " + summaryId, false);
+            notificationList.add(child);
+            // schedule all children for removal
+            childrenToRemove.add(child);
+        }
+        mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+
+        // Remove all child notifications from the valid group => summary without children
+        Mockito.reset(mCallback);
+        for (NotificationRecord r: childrenToRemove) {
+            notificationList.remove(r);
+            mGroupHelper.onNotificationRemoved(r, notificationList);
+        }
+        // Only call onGroupedNotificationRemovedWithDelay with the summary notification
+        mGroupHelper.onGroupedNotificationRemovedWithDelay(summary, notificationList,
+                summaryByGroup);
+
+        // Check that the summaries were force grouped
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testRemoveChildNotification_groupBecomesSingleton() {
+        // Check that removing child notifications from a group will trigger singleton force
+        // grouping re-evaluation
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        // Post singleton groups, under forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT - 1; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                    String.valueOf(i), UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp " + i, false);
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        // Post a valid (full) group
+        final int summaryId = 4242;
+        final int numChildren = 3;
+        final ArrayList<NotificationRecord> childrenToRemove = new ArrayList<>();
+        NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+                String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp " + summaryId, true);
+        notificationList.add(summary);
+        summaryByGroup.put(summary.getGroupKey(), summary);
+        for (int i = 0; i < numChildren; i++) {
+            NotificationRecord child = getNotificationRecord(pkg, summaryId + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp " + summaryId, false);
+            notificationList.add(child);
+
+            // schedule all children except one for removal
+            if (i < numChildren - 1) {
+                childrenToRemove.add(child);
+            }
+        }
+        mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+
+        // Remove some child notifications from the valid group, transform into a singleton group
+        Mockito.reset(mCallback);
+        for (NotificationRecord r: childrenToRemove) {
+            notificationList.remove(r);
+            mGroupHelper.onNotificationRemoved(r, notificationList);
+        }
+        // Only call onGroupedNotificationRemovedWithDelay with the summary notification
+        mGroupHelper.onGroupedNotificationRemovedWithDelay(summary, notificationList,
+                summaryByGroup);
+
+        // Check that the singleton groups were force grouped
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).removeAppProvidedSummary(
+                anyString());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testRemoveAllGroupNotifications_noForceGrouping() {
+        // Check that removing all notifications from a group will not trigger any force grouping
+        // re-evaluation
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        // Post summaries without children, below the force grouping limit
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+                    UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(summary);
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        // Post a valid (full) group
+        final int summaryId = 4242;
+        final int numChildren = 3;
+        final String groupToRemove = "testRemoveGrp";
+        NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+                String.valueOf(summaryId), UserHandle.SYSTEM, groupToRemove + summaryId, true);
+        notificationList.add(summary);
+        summaryByGroup.put(summary.getGroupKey(), summary);
+        for (int i = 0; i < numChildren; i++) {
+            NotificationRecord child = getNotificationRecord(pkg, summaryId + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, groupToRemove + summaryId, false);
+            notificationList.add(child);
+        }
+        mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+
+        // Remove all child notifications from the valid group => summary without children
+        Mockito.reset(mCallback);
+        for (NotificationRecord r: notificationList) {
+            if (r.getGroupKey().contains(groupToRemove)) {
+                r.isCanceled = true;
+                mGroupHelper.onNotificationRemoved(r, notificationList);
+            }
+        }
+        // Only call onGroupedNotificationRemovedWithDelay with the summary notification
+        mGroupHelper.onGroupedNotificationRemovedWithDelay(summary, notificationList,
+                summaryByGroup);
+        // Check that nothing was force grouped
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
     @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testMoveAggregateGroups_updateChannel() {
         final String pkg = "package";
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
index 9eddcc9..decbaac 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -60,8 +60,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.IntArray;
-import android.util.Log;
-import android.util.Slog;
 import android.util.Xml;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -729,4 +727,79 @@
         assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
                 .containsExactly(TYPE_PROMOTION);
     }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testSetAssistantAdjustmentKeyTypeStateForPackage_allowsAndDenies() {
+        // Given that a package is allowed to have its type adjusted,
+        String allowedPackage = "allowed.package";
+        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty();
+        mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true);
+
+        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty();
+        assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage));
+
+        // Set type adjustment disallowed for this package
+        mAssistants.setTypeAdjustmentForPackageState(allowedPackage, false);
+
+        // Then the package is marked as denied
+        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
+                .containsExactly(allowedPackage);
+        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage));
+
+        // Set type adjustment allowed again
+        mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true);
+
+        // Then the package is marked as allowed again
+        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty();
+        assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage));
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testSetAssistantAdjustmentKeyTypeStateForPackage_deniesMultiple() {
+        // Given packages not allowed to have their type adjusted,
+        String deniedPkg1 = "denied.Pkg1";
+        String deniedPkg2 = "denied.Pkg2";
+        String deniedPkg3 = "denied.Pkg3";
+        // Set type adjustment disallowed for these packages
+        mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false);
+        mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, false);
+        mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false);
+
+        // Then the packages are marked as denied
+        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
+                .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg2, deniedPkg3));
+        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1));
+        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2));
+        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3));
+
+        // And when we re-allow one of them,
+        mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, true);
+
+        // Then the rest of the original packages are still marked as denied.
+        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
+                .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3));
+        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1));
+        assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2));
+        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3));
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testSetAssistantAdjustmentKeyTypeStateForPackage_readWriteXml() throws Exception {
+        mAssistants.loadDefaultsFromConfig(true);
+        String deniedPkg1 = "denied.Pkg1";
+        String allowedPkg2 = "allowed.Pkg2";
+        String deniedPkg3 = "denied.Pkg3";
+        // Set type adjustment disallowed or allowed for these packages
+        mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false);
+        mAssistants.setTypeAdjustmentForPackageState(allowedPkg2, true);
+        mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false);
+
+        writeXmlAndReload(USER_ALL);
+
+        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
+                .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3));
+    }
 }
\ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
index b34b1fb..bf33333 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
@@ -907,10 +907,18 @@
         ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
         verify(mNm.mHandler, times(1)).post(runnableCaptor.capture());
         runnableCaptor.getValue().run();
-        ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
-                ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
-        verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
-        StatusBarNotification sbnResult = sbnCaptor.getValue().get();
+        StatusBarNotification sbnResult = null;
+        if (android.app.Flags.noSbnholder()) {
+            ArgumentCaptor<StatusBarNotification> sbnCaptor =
+                    ArgumentCaptor.forClass(StatusBarNotification.class);
+            verify(sysuiListener, times(1)).onNotificationPostedFull(sbnCaptor.capture(), any());
+            sbnResult = sbnCaptor.getValue();
+        } else {
+            ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
+                    ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
+            verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
+            sbnResult = sbnCaptor.getValue().get();
+        }
         assertThat(sbnResult.getNotification()
                 .extras.getCharSequence(Notification.EXTRA_TITLE).toString())
                 .isEqualTo("new title");
@@ -920,7 +928,7 @@
     }
 
     @Test
-    public void testListenerPostLifeimteExtension_postsToAppropriateListeners() throws Exception {
+    public void testListenerPostLifetimeExtension_postsToAppropriateListeners() throws Exception {
         mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
 
         // Create original notification, with FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY.
@@ -998,16 +1006,29 @@
             r.run();
         }
 
-        ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
-                ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
-        verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
-        StatusBarNotification sbnResult = sbnCaptor.getValue().get();
+        StatusBarNotification sbnResult = null;
+        if (android.app.Flags.noSbnholder()) {
+            ArgumentCaptor<StatusBarNotification> sbnCaptor =
+                    ArgumentCaptor.forClass(StatusBarNotification.class);
+            verify(sysuiListener, times(1)).onNotificationPostedFull(sbnCaptor.capture(), any());
+            sbnResult = sbnCaptor.getValue();
+        } else {
+            ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
+                    ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
+            verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
+            sbnResult = sbnCaptor.getValue().get();
+        }
         assertThat(sbnResult.getNotification()
                 .extras.getCharSequence(Notification.EXTRA_TITLE).toString())
                 .isEqualTo("new title");
 
-        verify(otherListener1, times(1)).onNotificationPosted(any(), any());
-        verify(otherListener2, times(1)).onNotificationPosted(any(), any());
+        if (android.app.Flags.noSbnholder()) {
+            verify(otherListener1, times(1)).onNotificationPostedFull(any(), any());
+            verify(otherListener2, times(1)).onNotificationPostedFull(any(), any());
+        } else {
+            verify(otherListener1, times(1)).onNotificationPosted(any(), any());
+            verify(otherListener2, times(1)).onNotificationPosted(any(), any());
+        }
     }
 
     @Test
@@ -1083,16 +1104,29 @@
             r.run();
         }
 
-        ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
-                ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
-        verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
-        StatusBarNotification sbnResult = sbnCaptor.getValue().get();
+        StatusBarNotification sbnResult = null;
+        if (android.app.Flags.noSbnholder()) {
+            ArgumentCaptor<StatusBarNotification> sbnCaptor =
+                    ArgumentCaptor.forClass(StatusBarNotification.class);
+            verify(sysuiListener, times(1)).onNotificationPostedFull(sbnCaptor.capture(), any());
+            sbnResult = sbnCaptor.getValue();
+        } else {
+            ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
+                    ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
+            verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
+            sbnResult = sbnCaptor.getValue().get();
+        }
         assertThat(sbnResult.getNotification()
                 .extras.getCharSequence(Notification.EXTRA_TITLE).toString())
                 .isEqualTo("new title");
 
-        verify(otherListener1, times(1)).onNotificationPosted(any(), any());
-        verify(otherListener2, times(1)).onNotificationPosted(any(), any());
+        if (android.app.Flags.noSbnholder()) {
+            verify(otherListener1, times(1)).onNotificationPostedFull(any(), any());
+            verify(otherListener2, times(1)).onNotificationPostedFull(any(), any());
+        } else {
+            verify(otherListener1, times(1)).onNotificationPosted(any(), any());
+            verify(otherListener2, times(1)).onNotificationPosted(any(), any());
+        }
     }
 
     /**
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index e6b4bc9..863f42f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -232,7 +232,6 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.LauncherApps;
 import android.content.pm.ModuleInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ParceledListSlice;
@@ -337,12 +336,12 @@
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
-import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-
 import com.google.android.collect.Lists;
 import com.google.common.collect.ImmutableList;
 
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -361,9 +360,6 @@
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
-import platform.test.runner.parameterized.Parameters;
-
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
@@ -378,6 +374,9 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Consumer;
 
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4.class)
 @RunWithLooper
@@ -3094,6 +3093,92 @@
     }
 
     @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST})
+    public void testScheduleGroupHelperWithDelay_onChildNotificationCanceled() throws Exception {
+        // Post summary + 2 child notification
+        final String originalGroupName = "originalGroup";
+        final int summaryId = 0;
+        final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel,
+                summaryId + 1, originalGroupName, false);
+        mService.addNotification(r1);
+        final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel,
+                summaryId + 2, originalGroupName, false);
+        mService.addNotification(r2);
+        final NotificationRecord summary = generateNotificationRecord(mTestNotificationChannel,
+                summaryId, originalGroupName, true);
+        mService.addNotification(summary);
+        final String originalGroupKey = summary.getGroupKey();
+        assertThat(mService.mSummaryByGroupKey).containsEntry(originalGroupKey, summary);
+
+        // Cancel the child notifications
+        mBinderService.cancelNotificationWithTag(r1.getSbn().getPackageName(),
+                r1.getSbn().getPackageName(), r1.getSbn().getTag(),
+                r1.getSbn().getId(), r1.getSbn().getUserId());
+        waitForIdle();
+
+        mBinderService.cancelNotificationWithTag(r2.getSbn().getPackageName(),
+                r2.getSbn().getPackageName(), r2.getSbn().getTag(),
+                r2.getSbn().getId(), r2.getSbn().getUserId());
+        waitForIdle();
+
+        mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+        waitForIdle();
+
+        // Check that onGroupedNotificationRemovedWithDelay was called only once
+        verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r1), any());
+        verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r2), any());
+        verify(mGroupHelper, times(1)).onGroupedNotificationRemovedWithDelay(eq(summary), any(),
+                any());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST})
+    public void testCleanupScheduleGroupHelperWithDelay_onAllNotificationCanceled()
+            throws Exception {
+        // Post summary + 2 child notification
+        final String originalGroupName = "originalGroup";
+        final int summaryId = 0;
+        final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel,
+                summaryId + 1, originalGroupName, false);
+        mService.addNotification(r1);
+        final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel,
+                summaryId + 2, originalGroupName, false);
+        mService.addNotification(r2);
+        final NotificationRecord summary = generateNotificationRecord(mTestNotificationChannel,
+                summaryId, originalGroupName, true);
+        mService.addNotification(summary);
+        final String originalGroupKey = summary.getGroupKey();
+        assertThat(mService.mSummaryByGroupKey).containsEntry(originalGroupKey, summary);
+
+        // Cancel all notifications: children + summary
+        mBinderService.cancelNotificationWithTag(r1.getSbn().getPackageName(),
+                r1.getSbn().getPackageName(), r1.getSbn().getTag(),
+                r1.getSbn().getId(), r1.getSbn().getUserId());
+        waitForIdle();
+
+        mBinderService.cancelNotificationWithTag(r2.getSbn().getPackageName(),
+                r2.getSbn().getPackageName(), r2.getSbn().getTag(),
+                r2.getSbn().getId(), r2.getSbn().getUserId());
+        waitForIdle();
+
+        mBinderService.cancelNotificationWithTag(summary.getSbn().getPackageName(),
+                summary.getSbn().getPackageName(), summary.getSbn().getTag(),
+                summary.getSbn().getId(), summary.getSbn().getUserId());
+        waitForIdle();
+
+        mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+        waitForIdle();
+
+        // Check that onGroupedNotificationRemovedWithDelay was never called: summary was canceled
+        verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r1), any());
+        verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r2), any());
+        verify(mGroupHelper, times(1)).onNotificationRemoved(eq(summary), any());
+        verify(mGroupHelper, never()).onGroupedNotificationRemovedWithDelay(any(), any(), any());
+    }
+
+    @Test
     public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
         when(mAmi.applyForegroundServiceNotification(
                 any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY);
@@ -7534,6 +7619,7 @@
         when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
         when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
         when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
 
         // Set up notifications that will be adjusted
         final NotificationRecord r1 = spy(generateNotificationRecord(
@@ -17142,6 +17228,7 @@
                 NotificationManagerService.WorkerHandler.class);
         mService.setHandler(handler);
         when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
 
         Bundle signals = new Bundle();
         signals.putInt(KEY_TYPE, TYPE_NEWS);
@@ -17176,6 +17263,42 @@
     }
 
     @Test
+    @EnableFlags({android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION,
+            android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI})
+    public void testApplyAdjustment_keyTypeForDisallowedPackage_DoesNotApply() throws Exception {
+        final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+        mService.addNotification(r);
+        NotificationManagerService.WorkerHandler handler = mock(
+                NotificationManagerService.WorkerHandler.class);
+        mService.setHandler(handler);
+        when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
+
+        Bundle signals = new Bundle();
+        signals.putInt(KEY_TYPE, TYPE_NEWS);
+        Adjustment adjustment = new Adjustment(
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+        when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
+        mBinderService.applyAdjustmentFromAssistant(null, adjustment);
+
+        waitForIdle();
+
+        r.applyAdjustments();
+
+        assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID);
+
+        // When we block adjustments for this package
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(false);
+
+        signals.putInt(KEY_TYPE, TYPE_PROMOTION);
+        mBinderService.applyAdjustmentFromAssistant(null, adjustment);
+        waitForIdle();
+        r.applyAdjustments();
+        // Then the adjustment is not applied.
+        assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID);
+    }
+
+    @Test
     @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
     public void testSetCanBePromoted_granted() throws Exception {
         // qualifying posted notification
@@ -17405,6 +17528,9 @@
     @Test
     @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
     public void testPostPromotableNotification_noPermission() throws Exception {
+        mBinderService.setCanBePromoted(mPkg, mUid, false, true);
+        assertThat(mBinderService.appCanBePromoted(mPkg, mUid)).isFalse();
+
         Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId())
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG"))
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 dda060d..80e86a1 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -256,6 +256,7 @@
     @Parameters(name = "{0}")
     public static List<FlagsParameterization> getParams() {
         return FlagsParameterization.allCombinationsOf(
+                android.app.Flags.FLAG_API_RICH_ONGOING,
                 FLAG_NOTIFICATION_CLASSIFICATION, FLAG_MODES_UI);
     }
 
@@ -6511,12 +6512,21 @@
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
+    @DisableFlags(android.app.Flags.FLAG_UI_RICH_ONGOING)
     public void testNoAppHasPermissionToPromoteByDefault() {
         mHelper.setShowBadge(PKG_P, UID_P, true);
         assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isFalse();
     }
 
     @Test
+    @EnableFlags({android.app.Flags.FLAG_API_RICH_ONGOING,
+            android.app.Flags.FLAG_UI_RICH_ONGOING})
+    public void testAllAppsHavePermissionToPromoteByDefault() {
+        mHelper.setShowBadge(PKG_P, UID_P, true);
+        assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isTrue();
+    }
+
+    @Test
     @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
     public void testSetCanBePromoted() {
         mHelper.setCanBePromoted(PKG_P, UID_P, true, true);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SystemZenRulesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SystemZenRulesTest.java
index 4d82c3c..949c5e2 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SystemZenRulesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SystemZenRulesTest.java
@@ -69,6 +69,8 @@
                 R.string.zen_mode_trigger_summary_range_symbol_combination, "%1$s-%2$s");
         mContext.getOrCreateTestableResources().addOverride(
                 R.string.zen_mode_trigger_summary_divider_text, ",");
+        mContext.getOrCreateTestableResources().addOverride(
+                R.string.zen_mode_trigger_summary_combined, "%1$s,%2$s");
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index bf61d06..09da015 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -7363,6 +7363,20 @@
         verify(callback, never()).onZenModeChanged();
     }
 
+    @Test
+    @EnableFlags(FLAG_MODES_MULTIUSER)
+    public void getNotificationPolicy_fromUserWithoutZenConfig_returnsDefaultPolicy() {
+        // Set a custom policy for the current user to double check we return a default one below.
+        mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, new Policy(0, 0, 0), ORIGIN_SYSTEM,
+                SYSTEM_UID);
+
+        Policy ghostPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.of(5552368));
+
+        assertThat(ghostPolicy).isNotNull();
+        assertThat(ZenAdapters.notificationPolicyToZenPolicy(ghostPolicy))
+                .isEqualTo(mZenModeHelper.getDefaultZenPolicy());
+    }
+
     private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode,
             @Nullable ZenPolicy zenPolicy) {
         ZenRule rule = new ZenRule();
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java b/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java
index 81026fd..d5548a4 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java
@@ -39,6 +39,7 @@
 import android.os.PersistableBundle;
 import android.os.VibrationEffect;
 import android.os.test.TestLooper;
+import android.os.vibrator.BasicPwleSegment;
 import android.os.vibrator.Flags;
 import android.os.vibrator.PrebakedSegment;
 import android.os.vibrator.PrimitiveSegment;
@@ -80,7 +81,12 @@
     private static final int TEST_MIN_ENVELOPE_EFFECT_CONTROL_POINT_DURATION_MILLIS = 20;
     private static final float[] TEST_FREQUENCIES_HZ = new float[]{30f, 50f, 100f, 120f, 150f};
     private static final float[] TEST_OUTPUT_ACCELERATIONS_GS =
-            new float[]{0.3f, 0.5f, 1.0f, 0.8f, 0.6f};
+            new float[]{0.0f, 3.0f, 4.0f, 2.0f, 1.0f};
+
+    private static final float[] TEST_BASIC_FREQUENCIES_HZ = new float[]{50f, 200f, 400f, 500f};
+    private static final float[] TEST_BASIC_OUTPUT_ACCELERATIONS_GS =
+            new float[]{0.05f, 0.5f, 2.0f, 1.0f};
+
     private static final float PWLE_V2_MIN_FREQUENCY = TEST_FREQUENCIES_HZ[0];
     private static final float PWLE_V2_MAX_FREQUENCY =
             TEST_FREQUENCIES_HZ[TEST_FREQUENCIES_HZ.length - 1];
@@ -397,6 +403,46 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+    public void testBasicPwleSegment_withoutPwleV2Capability_returnsNull() {
+        VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+                new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.5f, 100),
+                new BasicPwleSegment(0.2f, 0.8f, 0.2f, 0.4f, 20),
+                new BasicPwleSegment(0.8f, 0.2f, 0.4f, 0.5f, 100),
+                new BasicPwleSegment(0.2f, 0.65f, 0.5f, 0.5f, 50)),
+                /* repeatIndex= */ 1);
+
+        VibrationEffect.Composed adaptedEffect =
+                (VibrationEffect.Composed) mAdapter.adaptToVibrator(EMPTY_VIBRATOR_ID, effect);
+        assertThat(adaptedEffect).isNull();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+    public void testBasicPwleSegment_withPwleV2Capability_returnsAdaptedSegments() {
+        VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+                new BasicPwleSegment(0.0f, 0.5f, 0.0f, 0.5f, 20),
+                new BasicPwleSegment(0.5f, 1.0f, 0.5f, 1.0f, 100),
+                new BasicPwleSegment(1.0f, 0.0f, 1.0f, 0.5f, 100)),
+                /* repeatIndex= */ 1);
+
+
+        VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
+                new PwleSegment(0.0f, 0.16522837f, 63.52442f, 281.7622f, 20),
+                new PwleSegment(0.16522837f, 1.0f, 281.7622f, 500f, 100),
+                new PwleSegment(1.0f, 0.0f, 500, 281.7622f, 100)),
+                /* repeatIndex= */ 1);
+
+        SparseArray<VibratorController> vibrators = new SparseArray<>();
+        vibrators.put(PWLE_V2_VIBRATOR_ID,
+                createPwleV2VibratorController(PWLE_V2_VIBRATOR_ID, TEST_BASIC_FREQUENCIES_HZ,
+                        TEST_BASIC_OUTPUT_ACCELERATIONS_GS));
+        DeviceAdapter adapter = new DeviceAdapter(mVibrationSettings, vibrators);
+
+        assertThat(adapter.adaptToVibrator(PWLE_V2_VIBRATOR_ID, effect)).isEqualTo(expected);
+    }
+
+    @Test
     @DisableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY)
     public void testPrimitiveWithRelativeDelay_withoutFlag_returnsNull() {
         VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
@@ -477,11 +523,17 @@
     }
 
     private VibratorController createPwleV2VibratorController(int vibratorId) {
+        return createPwleV2VibratorController(vibratorId, TEST_FREQUENCIES_HZ,
+                TEST_OUTPUT_ACCELERATIONS_GS);
+    }
+
+    private VibratorController createPwleV2VibratorController(int vibratorId, float[] frequencies,
+            float[] accelerations) {
         FakeVibratorControllerProvider provider = createVibratorProviderWithEffects(
                 IVibrator.CAP_COMPOSE_EFFECTS, IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2);
         provider.setResonantFrequency(TEST_RESONANT_FREQUENCY);
-        provider.setFrequenciesHz(TEST_FREQUENCIES_HZ);
-        provider.setOutputAccelerationsGs(TEST_OUTPUT_ACCELERATIONS_GS);
+        provider.setFrequenciesHz(frequencies);
+        provider.setOutputAccelerationsGs(accelerations);
         provider.setMaxEnvelopeEffectSize(TEST_MAX_ENVELOPE_EFFECT_SIZE);
         provider.setMinEnvelopeEffectControlPointDurationMillis(
                 TEST_MIN_ENVELOPE_EFFECT_CONTROL_POINT_DURATION_MILLIS);
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
index 23ee893..da1c1ae 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -449,6 +449,18 @@
         }
     }
 
+    @Test
+    public void shouldIgnoreVibration_withoutAudioManager_allowsAllVibrations() {
+        mVibrationSettings = new VibrationSettings(mContextSpy,
+                new Handler(mTestLooper.getLooper()), mVibrationConfigMock);
+        mVibrationSettings.onSystemReady(mPackageManagerInternalMock,
+                mPowerManagerInternalMock, mActivityManagerMock, mVirtualDeviceManagerInternalMock,
+                /* audioManager= */ null);
+
+        for (int usage : ALL_USAGES) {
+            assertVibrationNotIgnoredForUsage(usage);
+        }
+    }
 
     @Test
     public void shouldIgnoreVibration_vibrateOnDisabled_ignoresUsagesNotAccessibility() {
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
index eb44daa..b4345b6 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -905,10 +905,10 @@
         fakeVibrator.setMinEnvelopeEffectControlPointDurationMillis(20);
 
         VibrationEffect effect = new VibrationEffect.WaveformEnvelopeBuilder()
-                .addControlPoint(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 20)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 30)
+                .addControlPoint(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30)
+                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 20)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 30)
                 .build();
         HalVibration vibration = startThreadAndDispatcher(effect);
         waitForCompletion();
@@ -930,6 +930,41 @@
 
     @Test
     @EnableFlags(android.os.vibrator.Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+    public void vibrate_singleVibratorBasicPwle_runsComposePwleV2() {
+        FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+        fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2);
+        fakeVibrator.setResonantFrequency(150);
+        fakeVibrator.setFrequenciesHz(new float[]{50f, 100f, 120f, 150f});
+        fakeVibrator.setOutputAccelerationsGs(new float[]{0.05f, 1.0f, 3.0f, 2.0f});
+        fakeVibrator.setMaxEnvelopeEffectSize(10);
+        fakeVibrator.setMinEnvelopeEffectControlPointDurationMillis(20);
+
+        VibrationEffect effect = new VibrationEffect.BasicEnvelopeBuilder()
+                .setInitialSharpness(/*initialSharpness=*/ 1.0f)
+                .addControlPoint(/*intensity=*/ 1.0f, /*sharpness=*/ 1.0f, /*durationMillis=*/ 20)
+                .addControlPoint(/*intensity=*/ 1.0f, /*sharpness=*/ 1.0f, /*durationMillis=*/ 100)
+                .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 1.0f, /*durationMillis=*/ 100)
+                .build();
+
+        HalVibration vibration = startThreadAndDispatcher(effect);
+        waitForCompletion();
+
+        verify(mManagerHooks).noteVibratorOn(eq(UID), eq(220L));
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+        verifyCallbacksTriggered(vibration, Status.FINISHED);
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+        assertEquals(Arrays.asList(
+                expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 0),
+                expectedPwle(/*amplitude=*/ 1.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 20),
+                expectedPwle(/*amplitude=*/ 1.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 100),
+                expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 100)
+        ), fakeVibrator.getEffectPwlePoints(vibration.id));
+
+    }
+
+    @Test
+    @EnableFlags(android.os.vibrator.Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
     public void vibrate_singleVibratorPwle_withInitialFrequency_runsComposePwleV2() {
         FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
         fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2);
@@ -941,10 +976,10 @@
 
         VibrationEffect effect = new VibrationEffect.WaveformEnvelopeBuilder()
                 .setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
-                .addControlPoint(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
-                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30)
-                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 20)
-                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 30)
+                .addControlPoint(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+                .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30)
+                .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 20)
+                .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 30)
                 .build();
 
         HalVibration vibration = startThreadAndDispatcher(effect);
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
index efe1af3..8b861ed 100644
--- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
@@ -79,6 +79,7 @@
 
         InstrumentationRegistry.getInstrumentation().getUiAutomation()
                 .adoptShellPermissionIdentity(Manifest.permission.WRITE_DEVICE_CONFIG,
+                        Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG,
                         Manifest.permission.READ_DEVICE_CONFIG);
 
         Identity identity = new Identity();
diff --git a/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java b/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
index 6f9c890..038e135 100644
--- a/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
@@ -40,7 +40,7 @@
  */
 @MediumTest
 @RunWith(AndroidJUnit4.class)
-@DisableFlags(com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER_MULTI_PRESS_GESTURES)
+@DisableFlags(com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER_MULTI_KEY_GESTURES)
 public class CombinationKeyTests extends ShortcutKeyTestBase {
     private static final long A11Y_KEY_HOLD_MILLIS = 3500;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
index d5ed048..1d138e4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
@@ -249,6 +249,18 @@
     }
 
     @Test
+    @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+    public void testShouldApplyCameraCompatFreeformTreatment_enabledByShellCommand_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.setCameraCompatTreatmentEnabledViaShellCommand(true);
+
+            robot.checkShouldApplyFreeformTreatmentForCameraCompat(true);
+        });
+    }
+
+    @Test
     @EnableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA,
             OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA,
             OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
@@ -350,6 +362,11 @@
             spyOn(displayContent.mAppCompatCameraPolicy);
         }
 
+        void setCameraCompatTreatmentEnabledViaShellCommand(boolean enabled) {
+            activity().top().mWmService.mAppCompatConfiguration
+                    .setIsCameraCompatFreeformWindowingTreatmentEnabled(enabled);
+        }
+
         void checkShouldRefreshActivityForCameraCompat(boolean expected) {
             Assert.assertEquals(getAppCompatCameraOverrides()
                     .shouldRefreshActivityForCameraCompat(), expected);
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index d6be915..40da9ea 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -66,6 +66,7 @@
 import android.window.BackAnimationAdapter;
 import android.window.BackMotionEvent;
 import android.window.BackNavigationInfo;
+import android.window.IBackAnimationHandoffHandler;
 import android.window.IOnBackInvokedCallback;
 import android.window.OnBackInvokedCallback;
 import android.window.OnBackInvokedCallbackInfo;
@@ -780,6 +781,10 @@
             @Override
             public void setTriggerBack(boolean triggerBack) {
             }
+
+            @Override
+            public void setHandoffHandler(IBackAnimationHandoffHandler unused) {
+            }
         };
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java
index ade591d..da010ae 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java
@@ -333,7 +333,8 @@
         int realCallingPid = REGULAR_PID_2;
 
         // setup state
-        mActiveUids.onNonAppSurfaceVisibilityChanged(callingUid, true);
+        mActiveUids.onNonAppSurfaceVisibilityChanged(callingUid,
+                WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, true);
         when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW);
 
         // prepare call
@@ -367,7 +368,8 @@
         int realCallingPid = REGULAR_PID_2;
 
         // setup state
-        mActiveUids.onNonAppSurfaceVisibilityChanged(realCallingUid, true);
+        mActiveUids.onNonAppSurfaceVisibilityChanged(realCallingUid,
+                WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, true);
         when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW);
 
         // prepare call
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index c51261f..76b994d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -49,6 +49,7 @@
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.media.projection.StopReason;
 import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 import android.view.ContentRecordingSession;
@@ -213,7 +214,7 @@
         mContentRecorder.setContentRecordingSession(session);
         mContentRecorder.updateRecording();
         assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
-        verify(mMediaProjectionManagerWrapper).stopActiveProjection();
+        verify(mMediaProjectionManagerWrapper).stopActiveProjection(StopReason.STOP_ERROR);
     }
 
     @Test
@@ -225,7 +226,7 @@
         mContentRecorder.setContentRecordingSession(invalidTaskSession);
         mContentRecorder.updateRecording();
         assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
-        verify(mMediaProjectionManagerWrapper).stopActiveProjection();
+        verify(mMediaProjectionManagerWrapper).stopActiveProjection(StopReason.STOP_ERROR);
     }
 
     @Test
@@ -310,8 +311,7 @@
                 mVirtualDisplayContent.getConfiguration().orientation, WINDOWING_MODE_FULLSCREEN);
 
         // No resize is issued, only the initial transformations when we started recording.
-        verify(mTransaction).setPosition(eq(mRecordedSurface), anyFloat(),
-                anyFloat());
+        verify(mTransaction).setPosition(eq(mRecordedSurface), anyFloat(), anyFloat());
         verify(mTransaction).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(),
                 anyFloat(), anyFloat());
     }
@@ -386,19 +386,18 @@
 
         // WHEN a configuration change arrives, and the recorded content is a different size.
         Configuration configuration = mTask.getConfiguration();
-        configuration.windowConfiguration.setBounds(new Rect(0, 0, recordedWidth, recordedHeight));
-        configuration.windowConfiguration.setAppBounds(
-                new Rect(0, 0, recordedWidth, recordedHeight));
+        Rect newBounds = new Rect(0, 0, recordedWidth, recordedHeight);
+        configuration.windowConfiguration.setBounds(newBounds);
+        configuration.windowConfiguration.setAppBounds(newBounds);
         mTask.onConfigurationChanged(configuration);
         assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
 
         // THEN content in the captured DisplayArea is scaled to fit the surface size.
-        verify(mTransaction, atLeastOnce()).setMatrix(eq(mRecordedSurface), anyFloat(), eq(0f),
-                eq(0f),
-                anyFloat());
+        verify(mTransaction, atLeastOnce()).setMatrix(
+                eq(mRecordedSurface), anyFloat(), eq(0f), eq(0f), anyFloat());
         // THEN the resize callback is notified.
-        verify(mMediaProjectionManagerWrapper).notifyActiveProjectionCapturedContentResized(
-                recordedWidth, recordedHeight);
+        verify(mMediaProjectionManagerWrapper).notifyCaptureBoundsChanged(
+                mTaskSession.getContentToRecord(), mTaskSession.getTargetUid(), newBounds);
     }
 
     @Test
@@ -649,7 +648,7 @@
 
         mTask.removeImmediately();
 
-        verify(mMediaProjectionManagerWrapper).stopActiveProjection();
+        verify(mMediaProjectionManagerWrapper).stopActiveProjection(StopReason.STOP_TARGET_REMOVED);
     }
 
     @Test
@@ -684,8 +683,8 @@
         int xInset = (mSurfaceSize.x - scaledWidth) / 2;
         verify(mTransaction, atLeastOnce()).setPosition(mRecordedSurface, xInset, 0);
         // THEN the resize callback is notified.
-        verify(mMediaProjectionManagerWrapper).notifyActiveProjectionCapturedContentResized(
-                displayAreaBounds.width(), displayAreaBounds.height());
+        verify(mMediaProjectionManagerWrapper).notifyCaptureBoundsChanged(
+                mDisplaySession.getContentToRecord(), mDisplaySession.getTargetUid(),  displayAreaBounds);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java b/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java
index c9c31df..a0f4ae7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java
@@ -239,6 +239,9 @@
         } else if (type.equals(FrameRateCategoryRate.class)) {
             field.set(first, new FrameRateCategoryRate(16666667, 11111111));
             field.set(second, new FrameRateCategoryRate(11111111, 8333333));
+        } else if (type.isArray() && type.getComponentType().equals(float.class)) {
+            field.set(first, new float[]{60.0f});
+            field.set(second, new float[]{120.0f});
         } else {
             throw new IllegalArgumentException("Field " + field
                     + " is not supported by this test, please add implementation of setting "
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
index c8fc482..6397334 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
@@ -20,16 +20,19 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
 
 import android.platform.test.annotations.Presubmit;
 import android.view.Surface;
@@ -54,6 +57,7 @@
 
     private DisplayRotationImmersiveAppCompatPolicy mPolicy;
 
+    private DisplayRotation mMockDisplayRotation;
     private AppCompatConfiguration mMockAppCompatConfiguration;
     private ActivityRecord mMockActivityRecord;
     private Task mMockTask;
@@ -98,6 +102,7 @@
         when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_90)).thenReturn(true);
         when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_180)).thenReturn(false);
         when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_270)).thenReturn(true);
+        mMockDisplayRotation = mockDisplayRotation;
 
         return mockDisplayRotation;
     }
@@ -196,6 +201,24 @@
     }
 
     @Test
+    public void testDeferOrientationUpdate() {
+        assertFalse(mPolicy.deferOrientationUpdate());
+
+        doReturn(SCREEN_ORIENTATION_UNSPECIFIED).when(mMockDisplayRotation).getLastOrientation();
+        final WindowOrientationListener orientationListener = mock(WindowOrientationListener.class);
+        doReturn(Surface.ROTATION_90).when(orientationListener).getProposedRotation();
+        doReturn(orientationListener).when(mMockDisplayRotation).getOrientationListener();
+        spyOn(mDisplayContent.mTransitionController);
+        doReturn(true).when(mDisplayContent.mTransitionController)
+                .hasTransientLaunch(mDisplayContent);
+
+        assertTrue(mPolicy.deferOrientationUpdate());
+        mDisplayContent.mTransitionController.mStateValidators.getFirst().run();
+
+        verify(mWm).updateRotation(false, false);
+    }
+
+    @Test
     public void testRotationChoiceEnforcedOnly_nullTopRunningActivity_lockNotEnforced() {
         when(mDisplayContent.topRunningActivity()).thenReturn(null);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
index a0c5b54..c016c5e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
@@ -69,7 +69,9 @@
     private static final FrameRateVote FRAME_RATE_VOTE_60_PREFERRED =
             new FrameRateVote(60, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT,
                     SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN);
-
+    private static final float HI_REFRESH_RATE = 90;
+    private static final float MID_REFRESH_RATE = 70;
+    private static final float LOW_REFRESH_RATE = 60;
     WindowState createWindow(String name) {
         WindowState window = createWindow(null, TYPE_APPLICATION, name);
         when(window.mWmService.mDisplayManagerInternal.getRefreshRateSwitchingType())
@@ -82,14 +84,16 @@
         DisplayInfo di = new DisplayInfo(mDisplayInfo);
         Mode defaultMode = di.getDefaultMode();
         Mode hiMode = new Mode(1,
-                defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 90);
+                defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), HI_REFRESH_RATE);
         Mode midMode = new Mode(2,
-                defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 70);
+                defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), MID_REFRESH_RATE);
         Mode lowMode = new Mode(LOW_MODE_ID,
-                defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 60);
+                defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), LOW_REFRESH_RATE);
 
         di.supportedModes = new Mode[] { hiMode, midMode };
         di.appsSupportedModes = new Mode[] { hiMode, midMode, lowMode };
+        di.supportedRefreshRates = new float[] {HI_REFRESH_RATE, MID_REFRESH_RATE,
+                LOW_REFRESH_RATE};
         di.defaultModeId = 1;
         mRefreshRatePolicy = new RefreshRatePolicy(mWm, di, mDenylist);
         when(mDisplayPolicy.getRefreshRatePolicy()).thenReturn(mRefreshRatePolicy);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 7ed8283..aa99250 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -434,6 +434,7 @@
     @Test
     public void testAddTaskCompatibleWindowingMode_withFreeformAndFullscreen_expectRemove() {
         Task task1 = createTaskBuilder(".Task1")
+                .setTaskId(1)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK)
                 .build();
         doReturn(WINDOWING_MODE_FREEFORM).when(task1).getWindowingMode();
@@ -452,6 +453,10 @@
         assertThat(mCallbacksRecorder.mTrimmed).isEmpty();
         assertThat(mCallbacksRecorder.mRemoved).hasSize(1);
         assertThat(mCallbacksRecorder.mRemoved).contains(task1);
+
+        TaskChangeNotificationController controller =
+                mAtm.getTaskChangeNotificationController();
+        verify(controller, times(1)).notifyRecentTaskRemovedForAddTask(task1.mTaskId);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index 3d08ca2..73e5f58 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -101,6 +101,8 @@
                 defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), LOW_REFRESH_RATE);
         mDisplayInfo.supportedModes = new Mode[] { hiMode, midMode };
         mDisplayInfo.appsSupportedModes = new Mode[] { hiMode, midMode, lowMode };
+        mDisplayInfo.supportedRefreshRates = new float[] {HI_REFRESH_RATE, MID_REFRESH_RATE,
+                LOW_REFRESH_RATE};
         mDisplayInfo.defaultModeId = HI_MODE_ID;
         mPolicy = new RefreshRatePolicy(mWm, mDisplayInfo, mDenylist);
     }
@@ -270,6 +272,46 @@
     }
 
     @Test
+    public void testInsetsAnimationAppOverridePreferredModeId() {
+        final WindowState overrideWindow = createWindow("overrideWindow");
+        overrideWindow.mAttrs.packageName = "com.android.test";
+        overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID;
+        parcelLayoutParams(overrideWindow);
+        assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
+        assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
+        assertEquals(FRAME_RATE_VOTE_LOW_EXACT, overrideWindow.mFrameRateVote);
+        assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+
+        overrideWindow.notifyInsetsAnimationRunningStateChanged(true);
+        assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
+        assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
+        assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote);
+        assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+    }
+
+    @Test
+    public void testInsetsAnimationAppOverridePreferredRefreshRate() {
+        final WindowState overrideWindow = createWindow("overrideWindow");
+        overrideWindow.mAttrs.packageName = "com.android.test";
+        overrideWindow.mAttrs.preferredRefreshRate = LOW_REFRESH_RATE;
+        parcelLayoutParams(overrideWindow);
+        assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
+        assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
+        assertEquals(FRAME_RATE_VOTE_LOW_PREFERRED, overrideWindow.mFrameRateVote);
+        assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+
+        overrideWindow.notifyInsetsAnimationRunningStateChanged(true);
+        assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
+        assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
+        assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote);
+        assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+    }
+
+    @Test
     public void testAnimatingCamera() {
         final WindowState cameraUsingWindow = createWindow("cameraUsingWindow");
         cameraUsingWindow.mAttrs.packageName = "com.android.test";
diff --git a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
index 791b5b5..a92fe3a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
@@ -162,6 +162,10 @@
             verifySecureExceptionThrown(activityOptions, taskSupervisor);
 
             activityOptions = ActivityOptions.makeBasic();
+            activityOptions.setTaskAlwaysOnTop(true);
+            verifySecureExceptionThrown(activityOptions, taskSupervisor);
+
+            activityOptions = ActivityOptions.makeBasic();
             activityOptions.setLaunchDisplayId(DEFAULT_DISPLAY);
             verifySecureExceptionThrown(activityOptions, taskSupervisor);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 41f1e23..584c4c9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -4863,7 +4863,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
-    public void testCameraCompatAspectRatio_defualtAspectRatioAppliedWhenGreater() {
+    public void testCameraCompatAspectRatio_defaultAspectRatioAppliedWhenGreater() {
         // Needed to create camera compat policy in DisplayContent.
         allowDesktopMode();
         // Create display that has all stable insets and does not rotate.
@@ -4917,7 +4917,8 @@
         assertEquals(minAspect, aspectRatioPolicy.getMinAspectRatio(), 0 /* delta */);
 
         // User override can still take effect.
-        doReturn(true).when(aspectRatioOverrides).shouldApplyUserMinAspectRatioOverride();
+        doReturn(USER_MIN_ASPECT_RATIO_3_2).when(aspectRatioOverrides)
+                .getUserMinAspectRatioOverrideCode();
         assertFalse(mActivity.isResizeable());
         assertEquals(maxAspect, aspectRatioPolicy.getMaxAspectRatio(), 0 /* delta */);
         assertNotEquals(SCREEN_ORIENTATION_UNSPECIFIED, mActivity.getOverrideOrientation());
@@ -4928,6 +4929,7 @@
         spyOn(pm);
         final PackageManager.Property property = new PackageManager.Property("propertyName",
                 true /* value */, name.getPackageName(), name.getClassName());
+        // Activity level.
         try {
             doReturn(property).when(pm).getPropertyAsUser(
                     WindowManager.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY,
@@ -4938,6 +4940,19 @@
         final ActivityRecord optOutActivity = new ActivityBuilder(mAtm)
                 .setComponent(name).setTask(mTask).build();
         assertFalse(optOutActivity.isUniversalResizeable());
+
+        // Application level.
+        try {
+            doReturn(property).when(pm).getProperty(
+                    WindowManager.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY,
+                    name.getPackageName());
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        final ActivityRecord optOutAppActivity = new ActivityBuilder(mAtm)
+                .setComponent(getUniqueComponentName(mContext.getPackageName()))
+                .setTask(mTask).build();
+        assertFalse(optOutAppActivity.isUniversalResizeable());
     }
 
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 8bbba1b..a425401 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -42,7 +42,6 @@
 import static android.view.flags.Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION;
 import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
 
-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;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
@@ -85,7 +84,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
-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;
@@ -97,7 +95,6 @@
 import android.view.InputDevice;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
-import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.WindowInsets;
@@ -1192,55 +1189,6 @@
                 argThat(h -> (h.inputConfig & InputConfig.SENSITIVE_FOR_PRIVACY) != 0));
     }
 
-    @RequiresFlagsDisabled(Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER)
-    @Test
-    public void testDrawMagnifiedViewport() {
-        final int displayId = mDisplayContent.mDisplayId;
-        // Use real surface, so ViewportWindow's BlastBufferQueue can be created.
-        final ArrayList<SurfaceControl> surfaceControls = new ArrayList<>();
-        mWm.mSurfaceControlFactory = () -> new SurfaceControl.Builder() {
-            @Override
-            public SurfaceControl build() {
-                final SurfaceControl sc = super.build();
-                surfaceControls.add(sc);
-                return sc;
-            }
-        };
-        mWm.mAccessibilityController.setMagnificationCallbacks(displayId,
-                mock(WindowManagerInternal.MagnificationCallbacks.class));
-        final boolean[] lockCanvasInWmLock = { false };
-        final Surface surface = mWm.mAccessibilityController.forceShowMagnifierSurface(displayId);
-        spyOn(surface);
-        doAnswer(invocationOnMock -> {
-            lockCanvasInWmLock[0] |= Thread.holdsLock(mWm.mGlobalLock);
-            invocationOnMock.callRealMethod();
-            return null;
-        }).when(surface).lockCanvas(any());
-        mWm.mAccessibilityController
-                .recomputeMagnifiedRegionAndDrawMagnifiedRegionBorderIfNeeded(displayId);
-        waitUntilHandlersIdle();
-        try {
-            verify(surface).lockCanvas(any());
-
-            clearInvocations(surface);
-            // Invalidate and redraw.
-            mWm.mAccessibilityController.onDisplaySizeChanged(mDisplayContent);
-            mWm.mAccessibilityController
-                    .recomputeMagnifiedRegionAndDrawMagnifiedRegionBorderIfNeeded(displayId);
-            // Turn off magnification to release surface.
-            mWm.mAccessibilityController.setMagnificationCallbacks(displayId, null);
-            waitUntilHandlersIdle();
-            // lockCanvas must not be called after releasing.
-            verify(surface, never()).lockCanvas(any());
-            verify(surface).release();
-            assertFalse(lockCanvasInWmLock[0]);
-        } finally {
-            for (int i = surfaceControls.size() - 1; i >= 0; --i) {
-                surfaceControls.get(i).release();
-            }
-        }
-    }
-
     @Test
     public void testRequestKeyboardShortcuts_noWindow() {
         doNothing().when(mWm.mContext).enforceCallingOrSelfPermission(anyString(), anyString());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 817c368..410fa28 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -82,9 +82,9 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
 import android.util.ArrayMap;
 import android.util.Rational;
 import android.view.Display;
@@ -544,6 +544,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
     public void testSetActivityWindowingMode() {
         final ActivityRecord record = makePipableActivity();
         final Task rootTask = record.getRootTask();
@@ -1302,7 +1303,7 @@
     }
 
     @Test
-    @DisableFlags(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
+    @RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
     public void testEnterPipParams() {
         final StubOrganizer o = new StubOrganizer();
         mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o);
@@ -1318,7 +1319,7 @@
     }
 
     @Test
-    @DisableFlags(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
+    @RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
     public void testChangePipParams() {
         class ChangeSavingOrganizer extends StubOrganizer {
             RunningTaskInfo mChangedInfo;
@@ -1890,6 +1891,7 @@
 
     @SuppressWarnings("GuardedBy")
     @Test
+    @RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
     public void testResumeTopsWhenLeavingPinned() {
         final ActivityRecord home = new ActivityBuilder(mAtm).setTask(
                 mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask()).build();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6f2c862..ad5d42a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8825,9 +8825,6 @@
      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION} or doesn't support given
      *          authType.
      */
-    // TODO(b/73660190): This should probably require MODIFY_PHONE_STATE, not
-    // READ_PRIVILEGED_PHONE_STATE. It certainly shouldn't reference the permission in Javadoc since
-    // it's not public API.
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getIccAuthentication(int appType, @AuthType int authType, String data) {
         return getIccAuthentication(getSubId(), appType, authType, data);
@@ -12239,9 +12236,10 @@
      * @param subId Subscription ID
      * @return true if IMS status is registered, false if the IMS status is not registered or a
      * RemoteException occurred.
-     * Use {@link ImsMmTelManager.RegistrationCallback} instead.
      * @hide
+     * @deprecated Use {@link ImsMmTelManager#getRegistrationState(Executor, Consumer)} instead.
      */
+    @Deprecated
     public boolean isImsRegistered(int subId) {
         try {
             return getITelephony().isImsRegistered(subId);
@@ -12259,8 +12257,10 @@
      * @return true if IMS status is registered, false if the IMS status is not registered or a
      * RemoteException occurred.
      * @see SubscriptionManager#getDefaultSubscriptionId()
+     * @deprecated Use {@link ImsMmTelManager#getRegistrationState(Executor, Consumer)} instead.
      * @hide
      */
+    @Deprecated
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public boolean isImsRegistered() {
        try {
@@ -12277,9 +12277,10 @@
      * @return true if Voice over LTE is available or false if it is unavailable or unknown.
      * @see SubscriptionManager#getDefaultSubscriptionId()
      * <p>
-     * Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
+     * @Deprecated Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
      * @hide
      */
+    @Deprecated
     @UnsupportedAppUsage
     public boolean isVolteAvailable() {
         try {
@@ -12297,9 +12298,10 @@
      * used during creation, the default subscription ID will be used. To query the
      * underlying technology that VT is available on, use {@link #getImsRegTechnologyForMmTel}.
      * @return true if VT is available, or false if it is unavailable or unknown.
-     * Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
+     * @Deprecated Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
      * @hide
      */
+    @Deprecated
     @UnsupportedAppUsage
     public boolean isVideoTelephonyAvailable() {
         try {
@@ -12313,9 +12315,10 @@
      * Returns the Status of Wi-Fi calling (Voice over WiFi) for the subscription ID specified.
      * @param subId the subscription ID.
      * @return true if VoWiFi is available, or false if it is unavailable or unknown.
-     * Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
+     * @Deprecated Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
      * @hide
      */
+    @Deprecated
     @UnsupportedAppUsage
     public boolean isWifiCallingAvailable() {
        try {
@@ -12336,9 +12339,11 @@
      *  other sim's internet, or
      *  - {@link ImsRegistrationImplBase#REGISTRATION_TECH_NONE} if we are not registered or the
      *  result is unavailable.
-     *  Use {@link ImsMmTelManager.RegistrationCallback} instead.
+     *  @Deprecated Use {@link ImsMmTelManager#registerImsRegistrationCallback(Executor, RegistrationCallback)}
+     *      or {@link ImsMmTelManager#getRegistrationTransportType(Executor, Consumer)} instead.
      *  @hide
      */
+    @Deprecated
     public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel() {
         try {
             return getITelephony().getImsRegTechnologyForMmTel(getSubId());
@@ -19594,4 +19599,37 @@
             throw ex.rethrowAsRuntimeException();
         }
     }
+
+    /**
+     * Returns carrier id maps to the passing CarrierIdentifier.
+     * To recognize a carrier (including MVNO) as a first-class identity,
+     * Android assigns each carrier with a canonical integer a.k.a. carrier id.
+     * The carrier ID is an Android platform-wide identifier for a carrier.
+     * AOSP maintains carrier ID assignments in
+     * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
+     *
+     * @param carrierIdentifier {@link CarrierIdentifier}
+     *
+     * @return Carrier id. Return {@link #UNKNOWN_CARRIER_ID} if the carrier cannot be identified.
+     * @throws UnsupportedOperationException If the device does not have
+     *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_CARRIER_ID_FROM_CARRIER_IDENTIFIER)
+    @SystemApi
+    @WorkerThread
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public int getCarrierIdFromCarrierIdentifier(@NonNull CarrierIdentifier carrierIdentifier) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.getCarrierIdFromIdentifier(carrierIdentifier);
+            }
+        } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
+        }
+        return UNKNOWN_CARRIER_ID;
+    }
 }
diff --git a/telephony/java/android/telephony/satellite/EarfcnRange.java b/telephony/java/android/telephony/satellite/EarfcnRange.java
index 38043b5..207b25d6 100644
--- a/telephony/java/android/telephony/satellite/EarfcnRange.java
+++ b/telephony/java/android/telephony/satellite/EarfcnRange.java
@@ -24,6 +24,8 @@
 
 import com.android.internal.telephony.flags.Flags;
 
+import java.util.Objects;
+
 /**
  * EARFCN (E-UTRA Absolute Radio Frequency Channel Number):  A number that identifies a
  * specific frequency channel in LTE/5G NR, used to define the carrier frequency.
@@ -73,10 +75,10 @@
      * @param startEarfcn The starting earfcn value.
      * @param endEarfcn   The ending earfcn value.
      */
-    public EarfcnRange(@IntRange(from = 0, to = 65535) int endEarfcn,
-            @IntRange(from = 0, to = 65535) int startEarfcn) {
-        mEndEarfcn = endEarfcn;
+    public EarfcnRange(@IntRange(from = 0, to = 65535) int startEarfcn,
+            @IntRange(from = 0, to = 65535) int endEarfcn) {
         mStartEarfcn = startEarfcn;
+        mEndEarfcn = endEarfcn;
     }
 
     @Override
@@ -85,6 +87,7 @@
     }
 
     @Override
+    @NonNull
     public String toString() {
         return "startEarfcn: " + mStartEarfcn + ", " + "endEarfcn: " + mEndEarfcn;
     }
@@ -121,4 +124,17 @@
     public @IntRange(from = 0, to = 65535) int getEndEarfcn() {
         return mEndEarfcn;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof EarfcnRange that)) return false;
+
+        return (that.mStartEarfcn == mStartEarfcn) && (that.mEndEarfcn == mEndEarfcn);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mStartEarfcn, mEndEarfcn);
+    }
 }
diff --git a/telephony/java/android/telephony/satellite/ISelectedNbIotSatelliteSubscriptionCallback.aidl b/telephony/java/android/telephony/satellite/ISelectedNbIotSatelliteSubscriptionCallback.aidl
new file mode 100644
index 0000000..178bb3c
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ISelectedNbIotSatelliteSubscriptionCallback.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+/**
+ * Interface for selected satellite subscription change callback.
+ *
+ * @hide
+ */
+oneway interface ISelectedNbIotSatelliteSubscriptionCallback {
+    /**
+     * Called when the selected satellite subscription has changed.
+     *
+     * @param selectedSubId The new satellite subscription id.
+     */
+    void onSelectedNbIotSatelliteSubscriptionChanged(in int selectedSubId);
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteAccessConfiguration.java b/telephony/java/android/telephony/satellite/SatelliteAccessConfiguration.java
index c3ae70b..c1a6ae8 100644
--- a/telephony/java/android/telephony/satellite/SatelliteAccessConfiguration.java
+++ b/telephony/java/android/telephony/satellite/SatelliteAccessConfiguration.java
@@ -24,7 +24,9 @@
 
 import com.android.internal.telephony.flags.Flags;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * SatelliteAccessConfiguration is used to store satellite access configuration
@@ -44,25 +46,25 @@
      * The list of tag IDs associated with the current location
      */
     @NonNull
-    private int[] mTagIds;
+    private List<Integer> mTagIdList;
 
     /**
      * Constructor for {@link SatelliteAccessConfiguration}.
      *
      * @param satelliteInfos The list of {@link SatelliteInfo} objects representing the satellites
      *                       accessible with this configuration.
-     * @param tagIds         The list of tag IDs associated with this configuration.
+     * @param tagIdList      The list of tag IDs associated with this configuration.
      */
     public SatelliteAccessConfiguration(@NonNull List<SatelliteInfo> satelliteInfos,
-            @NonNull int[] tagIds) {
+            @NonNull List<Integer> tagIdList) {
         mSatelliteInfoList = satelliteInfos;
-        mTagIds = tagIds;
+        mTagIdList = tagIdList;
     }
 
     public SatelliteAccessConfiguration(Parcel in) {
         mSatelliteInfoList = in.createTypedArrayList(SatelliteInfo.CREATOR);
-        mTagIds = new int[in.readInt()];
-        in.readIntArray(mTagIds);
+        mTagIdList = new ArrayList<>();
+        in.readList(mTagIdList, Integer.class.getClassLoader(), Integer.class);
     }
 
     public static final Creator<SatelliteAccessConfiguration> CREATOR =
@@ -91,12 +93,7 @@
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeTypedList(mSatelliteInfoList);
-        if (mTagIds != null && mTagIds.length > 0) {
-            dest.writeInt(mTagIds.length);
-            dest.writeIntArray(mTagIds);
-        } else {
-            dest.writeInt(0);
-        }
+        dest.writeList(mTagIdList);
     }
 
     /**
@@ -116,7 +113,34 @@
      * @return The list of tag IDs.
      */
     @NonNull
-    public int[] getTagIds() {
-        return mTagIds;
+    public List<Integer> getTagIds() {
+        return mTagIdList;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof SatelliteAccessConfiguration that)) return false;
+
+        return mSatelliteInfoList.equals(that.mSatelliteInfoList)
+                && Objects.equals(mTagIdList, that.mTagIdList);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(mSatelliteInfoList);
+        result = 31 * result + Objects.hashCode(mTagIdList);
+        return result;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("SatelliteAccessConfiguration{");
+        sb.append("mSatelliteInfoList=").append(mSatelliteInfoList);
+        sb.append(", mTagIds=").append(mTagIdList);
+        sb.append('}');
+        return sb.toString();
     }
 }
diff --git a/telephony/java/android/telephony/satellite/SatelliteInfo.java b/telephony/java/android/telephony/satellite/SatelliteInfo.java
index bca907e..1d5f613 100644
--- a/telephony/java/android/telephony/satellite/SatelliteInfo.java
+++ b/telephony/java/android/telephony/satellite/SatelliteInfo.java
@@ -25,7 +25,9 @@
 
 import com.android.internal.telephony.flags.Flags;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.UUID;
 
 /**
@@ -44,20 +46,23 @@
     private UUID mId;
 
     /**
-     * Position information of a satellite.
+     * Position information of a geostationary satellite.
      * This includes the longitude and altitude of the satellite.
+     * If the SatellitePosition is invalid,
+     * longitudeDegree and altitudeKm will be represented as DOUBLE.NaN.
      */
+    @NonNull
     private SatellitePosition mPosition;
 
     /**
-     * The frequency bands to scan. Bands and earfcns won't overlap.
+     * The frequency band list to scan. Bands and earfcns won't overlap.
      * Bands will be filled only if the whole band is needed.
      * Maximum length of the vector is 8.
      */
-    private int[] mBands;
+    private List<Integer> mBandList;
 
     /**
-     * EARFCN (E-UTRA Absolute Radio Frequency Channel Number) Ranges
+     * EARFCN (E-UTRA Absolute Radio Frequency Channel Number) range list
      * The supported frequency range list.
      * Maximum length of the vector is 8.
      */
@@ -71,13 +76,8 @@
         }
         mPosition = in.readParcelable(SatellitePosition.class.getClassLoader(),
                 SatellitePosition.class);
-        int numBands = in.readInt();
-        mBands = new int[numBands];
-        if (numBands > 0) {
-            for (int i = 0; i < numBands; i++) {
-                mBands[i] = in.readInt();
-            }
-        }
+        mBandList = new ArrayList<>();
+        in.readList(mBandList, Integer.class.getClassLoader(), Integer.class);
         mEarfcnRangeList = in.createTypedArrayList(EarfcnRange.CREATOR);
     }
 
@@ -86,15 +86,15 @@
      *
      * @param satelliteId       The ID of the satellite.
      * @param satellitePosition The {@link SatellitePosition} of the satellite.
-     * @param bands             The list of frequency bands supported by the satellite.
+     * @param bandList          The list of frequency bandList supported by the satellite.
      * @param earfcnRanges      The list of {@link EarfcnRange} objects representing the EARFCN
      *                          ranges supported by the satellite.
      */
     public SatelliteInfo(@NonNull UUID satelliteId, @NonNull SatellitePosition satellitePosition,
-            @NonNull int[] bands, @NonNull List<EarfcnRange> earfcnRanges) {
+            @NonNull List<Integer> bandList, @NonNull List<EarfcnRange> earfcnRanges) {
         mId = satelliteId;
         mPosition = satellitePosition;
-        mBands = bands;
+        mBandList = bandList;
         mEarfcnRangeList = earfcnRanges;
     }
 
@@ -119,12 +119,7 @@
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeParcelable(new ParcelUuid(mId), flags);
         dest.writeParcelable(mPosition, flags);
-        if (mBands != null && mBands.length > 0) {
-            dest.writeInt(mBands.length);
-            dest.writeIntArray(mBands);
-        } else {
-            dest.writeInt(0);
-        }
+        dest.writeList(mBandList);
         dest.writeTypedList(mEarfcnRangeList);
     }
 
@@ -143,6 +138,7 @@
      *
      * @return The {@link SatellitePosition} of the satellite.
      */
+    @NonNull
     public SatellitePosition getSatellitePosition() {
         return mPosition;
     }
@@ -153,8 +149,8 @@
      * @return The list of frequency bands.
      */
     @NonNull
-    public int[] getBands() {
-        return mBands;
+    public List<Integer> getBands() {
+        return mBandList;
     }
 
     /**
@@ -166,4 +162,35 @@
     public List<EarfcnRange> getEarfcnRanges() {
         return mEarfcnRangeList;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof SatelliteInfo that)) return false;
+
+        return mId.equals(that.mId)
+                && Objects.equals(mPosition, that.mPosition)
+                && Objects.equals(mBandList, that.mBandList)
+                && mEarfcnRangeList.equals(that.mEarfcnRangeList);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(mId, mPosition, mEarfcnRangeList);
+        result = 31 * result + Objects.hashCode(mBandList);
+        return result;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("SatelliteInfo{");
+        sb.append("mId=").append(mId);
+        sb.append(", mPosition=").append(mPosition);
+        sb.append(", mBandList=").append(mBandList);
+        sb.append(", mEarfcnRangeList=").append(mEarfcnRangeList);
+        sb.append('}');
+        return sb.toString();
+    }
 }
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 23203ed..5a34b00 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -99,16 +99,18 @@
     private static final ConcurrentHashMap<SatelliteSupportedStateCallback,
             ISatelliteSupportedStateCallback> sSatelliteSupportedStateCallbackMap =
             new ConcurrentHashMap<>();
-
     private static final ConcurrentHashMap<SatelliteCommunicationAllowedStateCallback,
             ISatelliteCommunicationAllowedStateCallback>
             sSatelliteCommunicationAllowedStateCallbackMap =
             new ConcurrentHashMap<>();
-
     private static final ConcurrentHashMap<SatelliteDisallowedReasonsCallback,
             ISatelliteDisallowedReasonsCallback>
             sSatelliteDisallowedReasonsCallbackMap =
             new ConcurrentHashMap<>();
+    private static final ConcurrentHashMap<SelectedNbIotSatelliteSubscriptionCallback,
+            ISelectedNbIotSatelliteSubscriptionCallback>
+            sSelectedNbIotSatelliteSubscriptionCallbackMap =
+            new ConcurrentHashMap<>();
 
     private final int mSubId;
 
@@ -746,7 +748,7 @@
      * @hide
      */
     public static final String ACTION_SATELLITE_SUBSCRIBER_ID_LIST_CHANGED =
-            "android.telephony.action.ACTION_SATELLITE_SUBSCRIBER_ID_LIST_CHANGED";
+            "android.telephony.satellite.action.SATELLITE_SUBSCRIBER_ID_LIST_CHANGED";
 
 
     /**
@@ -757,7 +759,7 @@
      * @hide
      */
     public static final String ACTION_SATELLITE_START_NON_EMERGENCY_SESSION =
-            "android.telephony.action.ACTION_SATELLITE_START_NON_EMERGENCY_SESSION";
+            "android.telephony.satellite.action.SATELLITE_START_NON_EMERGENCY_SESSION";
     /**
      * Meta-data represents whether the application supports P2P SMS over carrier roaming satellite
      * which needs manual trigger to connect to satellite. The messaging applications that supports
@@ -2541,6 +2543,89 @@
     }
 
     /**
+     * Registers for selected satellite subscription changed event from the satellite service.
+     *
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback to handle the selected satellite subscription changed event.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteResult public int registerForSelectedNbIotSatelliteSubscriptionChanged(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull SelectedNbIotSatelliteSubscriptionCallback callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                ISelectedNbIotSatelliteSubscriptionCallback internalCallback =
+                        new ISelectedNbIotSatelliteSubscriptionCallback.Stub() {
+                            @Override
+                            public void onSelectedNbIotSatelliteSubscriptionChanged(
+                                    int selectedSubId) {
+                                executor.execute(() -> Binder.withCleanCallingIdentity(
+                                        () -> callback.onSelectedNbIotSatelliteSubscriptionChanged(
+                                                selectedSubId)));
+                            }
+                        };
+                sSelectedNbIotSatelliteSubscriptionCallbackMap.put(callback, internalCallback);
+                return telephony.registerForSelectedNbIotSatelliteSubscriptionChanged(
+                        internalCallback);
+            } else {
+                throw new IllegalStateException("Telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("registerForSelectedNbIotSatelliteSubscriptionChanged() RemoteException: " + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_RESULT_REQUEST_FAILED;
+    }
+
+    /**
+     * Unregisters for selected satellite subscription changed event from the satellite service. If
+     * callback was not registered before, the request will be ignored.
+     *
+     * @param callback The callback that was passed to {@link
+     *     #registerForSelectedNbIotSatelliteSubscriptionChanged(Executor,
+     *     SelectedNbIotSatelliteSubscriptionCallback)}.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    public void unregisterForSelectedNbIotSatelliteSubscriptionChanged(
+            @NonNull SelectedNbIotSatelliteSubscriptionCallback callback) {
+        Objects.requireNonNull(callback);
+        ISelectedNbIotSatelliteSubscriptionCallback internalCallback =
+                sSelectedNbIotSatelliteSubscriptionCallbackMap.remove(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                if (internalCallback != null) {
+                    telephony.unregisterForSelectedNbIotSatelliteSubscriptionChanged(
+                            internalCallback);
+                } else {
+                    loge("unregisterForSelectedNbIotSatelliteSubscriptionChanged: " +
+                            "No internal callback.");
+                }
+            } else {
+                throw new IllegalStateException("Telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("unregisterForSelectedNbIotSatelliteSubscriptionChanged() RemoteException: " +
+                    ex);
+            ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Inform whether the device is aligned with the satellite in both real and demo mode.
      *
      * In demo mode, framework will send datagram to modem only when device is aligned with
diff --git a/telephony/java/android/telephony/satellite/SatellitePosition.java b/telephony/java/android/telephony/satellite/SatellitePosition.java
index 1e8c018..dd463e0 100644
--- a/telephony/java/android/telephony/satellite/SatellitePosition.java
+++ b/telephony/java/android/telephony/satellite/SatellitePosition.java
@@ -23,6 +23,8 @@
 
 import com.android.internal.telephony.flags.Flags;
 
+import java.util.Objects;
+
 /**
  * The position of a satellite in Earth orbit.
  *
@@ -111,4 +113,24 @@
     public double getAltitudeKm() {
         return mAltitudeKm;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof SatellitePosition that)) return false;
+
+        return Double.compare(that.mLongitudeDegree, mLongitudeDegree) == 0
+                && Double.compare(that.mAltitudeKm, mAltitudeKm) == 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mLongitudeDegree, mAltitudeKm);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        return "mLongitudeDegree: " + mLongitudeDegree + ", " + "mAltitudeKm: " + mAltitudeKm;
+    }
 }
diff --git a/telephony/java/android/telephony/satellite/SelectedNbIotSatelliteSubscriptionCallback.java b/telephony/java/android/telephony/satellite/SelectedNbIotSatelliteSubscriptionCallback.java
new file mode 100644
index 0000000..d896554
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SelectedNbIotSatelliteSubscriptionCallback.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+/**
+ * A callback class for selected satellite subscription changed events.
+ *
+ * @hide
+ */
+public interface SelectedNbIotSatelliteSubscriptionCallback {
+    /**
+     * Called when the selected satellite subscription has changed.
+     *
+     * @param selectedSubId The new satellite subscription id.
+     */
+    void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId);
+}
diff --git a/telephony/java/android/telephony/satellite/SystemSelectionSpecifier.java b/telephony/java/android/telephony/satellite/SystemSelectionSpecifier.java
index 8a5e7f2..c2ac44f 100644
--- a/telephony/java/android/telephony/satellite/SystemSelectionSpecifier.java
+++ b/telephony/java/android/telephony/satellite/SystemSelectionSpecifier.java
@@ -17,11 +17,13 @@
 package android.telephony.satellite;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.util.IntArray;
 
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -39,16 +41,26 @@
      * The radio channels to scan as defined in 3GPP TS 25.101 and 36.101.
      * Maximum length of the vector is 32.
      */
-    @NonNull private IntArray mEarfcs;
+    @NonNull private IntArray mEarfcns;
+
+    /* The list of satellites configured for the current location */
+    @Nullable
+    private SatelliteInfo[] mSatelliteInfos;
+
+    /* The list of tag IDs associated with the current location */
+    @Nullable private IntArray mTagIds;
 
     /**
      * @hide
      */
     public SystemSelectionSpecifier(@NonNull String mccmnc, @NonNull IntArray bands,
-            @NonNull IntArray earfcs) {
+            @NonNull IntArray earfcns, @Nullable SatelliteInfo[] satelliteInfos,
+            @Nullable IntArray tagIds) {
         mMccMnc = mccmnc;
         mBands = bands;
-        mEarfcs = earfcs;
+        mEarfcns = earfcns;
+        mSatelliteInfos = satelliteInfos;
+        mTagIds = tagIds;
     }
 
     private SystemSelectionSpecifier(Parcel in) {
@@ -74,10 +86,21 @@
             out.writeInt(0);
         }
 
-        if (mEarfcs != null && mEarfcs.size() > 0) {
-            out.writeInt(mEarfcs.size());
-            for (int i = 0; i < mEarfcs.size(); i++) {
-                out.writeInt(mEarfcs.get(i));
+        if (mEarfcns != null && mEarfcns.size() > 0) {
+            out.writeInt(mEarfcns.size());
+            for (int i = 0; i < mEarfcns.size(); i++) {
+                out.writeInt(mEarfcns.get(i));
+            }
+        } else {
+            out.writeInt(0);
+        }
+
+        out.writeTypedArray(mSatelliteInfos, flags);
+
+        if (mTagIds != null) {
+            out.writeInt(mTagIds.size());
+            for (int i = 0; i < mTagIds.size(); i++) {
+                out.writeInt(mTagIds.get(i));
             }
         } else {
             out.writeInt(0);
@@ -115,14 +138,35 @@
         }
 
         sb.append("earfcs:");
-        if (mEarfcs != null && mEarfcs.size() > 0) {
-            for (int i = 0; i < mEarfcs.size(); i++) {
-                sb.append(mEarfcs.get(i));
+        if (mEarfcns != null && mEarfcns.size() > 0) {
+            for (int i = 0; i < mEarfcns.size(); i++) {
+                sb.append(mEarfcns.get(i));
                 sb.append(",");
             }
         } else {
             sb.append("none");
         }
+
+        sb.append("mSatelliteInfos:");
+        if (mSatelliteInfos != null && mSatelliteInfos.length > 0) {
+            for (SatelliteInfo satelliteInfo : mSatelliteInfos) {
+                sb.append(satelliteInfo);
+                sb.append(",");
+            }
+        } else {
+            sb.append("none");
+        }
+
+        sb.append("mTagIds:");
+        if (mTagIds != null && mTagIds.size() > 0) {
+            for (int i = 0; i < mTagIds.size(); i++) {
+                sb.append(mTagIds.get(i));
+                sb.append(",");
+            }
+        } else {
+            sb.append("none");
+        }
+
         return sb.toString();
     }
 
@@ -133,12 +177,15 @@
         SystemSelectionSpecifier that = (SystemSelectionSpecifier) o;
         return Objects.equals(mMccMnc, that.mMccMnc)
                 && Objects.equals(mBands, that.mBands)
-                && Objects.equals(mEarfcs, that.mEarfcs);
+                && Objects.equals(mEarfcns, that.mEarfcns)
+                && (mSatelliteInfos == null ? that.mSatelliteInfos == null : Arrays.equals(
+                mSatelliteInfos, that.mSatelliteInfos))
+                && Objects.equals(mTagIds, that.mTagIds);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mMccMnc, mBands, mEarfcs);
+        return Objects.hash(mMccMnc, mBands, mEarfcns);
     }
 
     @NonNull public String getMccMnc() {
@@ -149,8 +196,18 @@
         return mBands;
     }
 
-    @NonNull public IntArray getEarfcs() {
-        return mEarfcs;
+    @NonNull public IntArray getEarfcns() {
+        return mEarfcns;
+    }
+
+    @NonNull
+    public SatelliteInfo[] getSatelliteInfos() {
+        return mSatelliteInfos;
+    }
+
+    @NonNull
+    public IntArray getTagIds() {
+        return mTagIds;
     }
 
     private void readFromParcel(Parcel in) {
@@ -164,11 +221,20 @@
             }
         }
 
-        mEarfcs = new IntArray();
-        int numEarfcs = in.readInt();
-        if (numEarfcs > 0) {
-            for (int i = 0; i < numEarfcs; i++) {
-                mEarfcs.add(in.readInt());
+        mEarfcns = new IntArray();
+        int numEarfcns = in.readInt();
+        if (numEarfcns > 0) {
+            for (int i = 0; i < numEarfcns; i++) {
+                mEarfcns.add(in.readInt());
+            }
+        }
+
+        mSatelliteInfos = in.createTypedArray(SatelliteInfo.CREATOR);
+
+        int numTagIds = in.readInt();
+        if (numTagIds > 0) {
+            for (int i = 0; i < numTagIds; i++) {
+                mTagIds.add(in.readInt());
             }
         }
     }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/telephony/java/android/telephony/satellite/stub/EarfcnRange.aidl
similarity index 60%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to telephony/java/android/telephony/satellite/stub/EarfcnRange.aidl
index 5a04169..6e9d19e 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/telephony/java/android/telephony/satellite/stub/EarfcnRange.aidl
@@ -5,7 +5,7 @@
  * 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
+ *     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,
@@ -14,8 +14,19 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.telephony.satellite.stub;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+parcelable EarfcnRange {
+    /**
+     * The start frequency of the earfcn range and is inclusive in the range
+     */
+    int startEarfcn;
+
+    /**
+     * The end frequency of the earfcn range and is inclusive in the range.
+     */
+    int endEarfcn;
 }
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteInfo.aidl b/telephony/java/android/telephony/satellite/stub/SatelliteInfo.aidl
new file mode 100644
index 0000000..312bd8f
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteInfo.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.telephony.satellite.stub;
+
+import android.telephony.satellite.stub.UUID;
+import android.telephony.satellite.stub.SatellitePosition;
+import android.telephony.satellite.stub.EarfcnRange;
+
+/**
+ * @hide
+ */
+parcelable SatelliteInfo {
+    /**
+     * Unique identification number for the satellite.
+     * This ID is used to distinguish between different satellites in the network.
+     */
+    UUID id;
+
+    /**
+     * Position information of a geostationary satellite.
+     * This includes the longitude and altitude of the satellite.
+     * If the SatellitePosition is invalid,
+     * longitudeDegree and altitudeKm will be represented as DOUBLE.NaN.
+     */
+    SatellitePosition position;
+
+    /**
+     * The frequency bands to scan.
+     * Bands will be filled only if the whole band is needed.
+     * Maximum length of the vector is 8.
+     */
+    int[] bands;
+
+    /**
+     * The supported frequency ranges. Earfcn ranges and earfcns won't overlap.
+     */
+    EarfcnRange[] earfcnRanges;
+}
diff --git a/telephony/java/android/telephony/satellite/stub/SatellitePosition.aidl b/telephony/java/android/telephony/satellite/stub/SatellitePosition.aidl
new file mode 100644
index 0000000..e87b26c
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/SatellitePosition.aidl
@@ -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 android.telephony.satellite.stub;
+
+/**
+ * @hide
+ */
+parcelable SatellitePosition {
+    /**
+     * The longitude of the satellite in degrees, ranging from -180 to 180 degrees
+     */
+    double longitudeDegree;
+
+    /**
+     * The distance from the center of the earth to the satellite, measured in kilometers
+     */
+    double altitudeKm;
+}
diff --git a/telephony/java/android/telephony/satellite/stub/SystemSelectionSpecifier.aidl b/telephony/java/android/telephony/satellite/stub/SystemSelectionSpecifier.aidl
index 22240f6..3aff4cb 100644
--- a/telephony/java/android/telephony/satellite/stub/SystemSelectionSpecifier.aidl
+++ b/telephony/java/android/telephony/satellite/stub/SystemSelectionSpecifier.aidl
@@ -16,6 +16,8 @@
 
 package android.telephony.satellite.stub;
 
+import android.telephony.satellite.stub.SatelliteInfo;
+
 /**
  * {@hide}
  */
@@ -24,15 +26,26 @@
     String mMccMnc;
 
     /**
-     * The frequency bands to scan. Bands and earfcns won't overlap.
+     * The frequency bands to scan.
      * Bands will be filled only if the whole band is needed.
      * Maximum length of the vector is 8.
+     * The values are populated from the mBands array within the SatelliteInfo[] array, which is
+     * included in the SystemSelectionSpecifier, for backward compatibility.
      */
     int[] mBands;
 
     /**
      * The radio channels to scan as defined in 3GPP TS 25.101 and 36.101.
+     * The values are populated from the earfcns defined in the EarfcnRange[] array inside
+     * SatelliteInfo[], which is included in the SystemSelectionSpecifier, for backward
+     * compatibility.
      * Maximum length of the vector is 32.
      */
     int[] mEarfcs;
+
+    /* The list of satellites configured for the current location */
+    SatelliteInfo[] satelliteInfos;
+
+    /* The list of tag IDs associated with the current location */
+    int[] tagIds;
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/telephony/java/android/telephony/satellite/stub/UUID.aidl
similarity index 64%
copy from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
copy to telephony/java/android/telephony/satellite/stub/UUID.aidl
index 5a04169..004a507 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/telephony/java/android/telephony/satellite/stub/UUID.aidl
@@ -5,7 +5,7 @@
  * 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
+ *     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,
@@ -14,8 +14,19 @@
  * limitations under the License.
  */
 
-package com.android.systemui.shared.clocks
+package android.telephony.satellite.stub;
 
-object ClockAnimation {
-    const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+/**
+ * @hide
+ */
+parcelable UUID {
+    /*
+     * The most significant 64 bits of this UUID.
+     */
+    long mostSigBits;
+
+    /*
+     * The least significant 64 bits of this UUID.
+     */
+    long leastSigBits;
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d22e9fa..131f46b 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -76,6 +76,7 @@
 import android.telephony.satellite.ISatelliteProvisionStateCallback;
 import android.telephony.satellite.ISatelliteSupportedStateCallback;
 import android.telephony.satellite.ISatelliteModemStateCallback;
+import android.telephony.satellite.ISelectedNbIotSatelliteSubscriptionCallback;
 import android.telephony.satellite.NtnSignalStrength;
 import android.telephony.satellite.SatelliteCapabilities;
 import android.telephony.satellite.SatelliteDatagram;
@@ -3030,6 +3031,30 @@
     void requestSelectedNbIotSatelliteSubscriptionId(in ResultReceiver receiver);
 
     /**
+     * Registers for selected satellite subscription changed event from the satellite service.
+     *
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback to handle the satellite subscription changed event.
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    int registerForSelectedNbIotSatelliteSubscriptionChanged(
+            in ISelectedNbIotSatelliteSubscriptionCallback callback);
+
+    /**
+     * Unregisters for selected satellite subscription changed event from the satellite service. If
+     * callback was not registered before, the request will be ignored.
+     *
+     * @param callback The callback that was passed to {@link
+     *     #registerForSelectedNbIotSatelliteSubscriptionChanged(Executor,
+     *     SelectedNbIotSatelliteSubscriptionCallback)}.
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void unregisterForSelectedNbIotSatelliteSubscriptionChanged(
+            in ISelectedNbIotSatelliteSubscriptionCallback callback);
+
+    /**
      * Inform whether the device is aligned with the satellite in both real and demo mode.
      *
      * @param isAligned {@true} Device is aligned with the satellite.
@@ -3143,7 +3168,7 @@
      */
     boolean setSatelliteAccessControlOverlayConfigs(in boolean reset, in boolean isAllowed,
             in String s2CellFile, in long locationFreshDurationNanos,
-            in List<String> satelliteCountryCodes);
+            in List<String> satelliteCountryCodes, String satelliteAccessConfigurationFile);
 
     /**
      * This API can be used in only testing to override oem-enabled satellite provision status.
@@ -3519,4 +3544,15 @@
     * @hide
     */
     void setNtnSmsSupported(boolean ntnSmsSupported);
+
+    /**
+     * Returns carrier id maps to the passing {@link CarrierIdentifier}.
+     *
+     * @param {@link CarrierIdentifier}.
+     *
+     * @return carrier id from passing {@link CarrierIdentifier} or {@link #UNKNOWN_CARRIER_ID}
+     * if the carrier cannot be identified
+     * @hide
+     */
+    int getCarrierIdFromIdentifier(in CarrierIdentifier carrierIdentifier);
 }
diff --git a/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java
index bfce3d2..6d818d7 100644
--- a/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java
+++ b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java
@@ -159,7 +159,7 @@
 
     private static BatteryUsageStats buildBatteryUsageStats() {
         final BatteryUsageStats.Builder builder =
-                new BatteryUsageStats.Builder(new String[]{"FOO"}, true, false, false, false, 0)
+                new BatteryUsageStats.Builder(new String[]{"FOO"}, false, false, false, 0)
                         .setBatteryCapacity(4000)
                         .setDischargePercentage(20)
                         .setDischargedPowerRange(1000, 2000)
@@ -182,8 +182,7 @@
                             .setTimeInProcessStateMs(UidBatteryConsumer.STATE_BACKGROUND, i * 1000);
             for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
                     componentId++) {
-                consumerBuilder.addConsumedPower(componentId, componentId * 123.0,
-                        BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+                consumerBuilder.addConsumedPower(componentId, componentId * 123.0);
                 consumerBuilder.addUsageDurationMillis(componentId, componentId * 1000);
             }
 
diff --git a/tests/CtsSurfaceControlTestsStaging/AndroidManifest.xml b/tests/CtsSurfaceControlTestsStaging/AndroidManifest.xml
index d8eb9ff..da510fc 100644
--- a/tests/CtsSurfaceControlTestsStaging/AndroidManifest.xml
+++ b/tests/CtsSurfaceControlTestsStaging/AndroidManifest.xml
@@ -18,12 +18,20 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.view.surfacecontroltests">
 
+    <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER"/>
+    <uses-permission android:name="android.permission.OBSERVE_PICTURE_PROFILES"/>
+
     <application android:debuggable="true" android:testOnly="true">
         <uses-library android:name="android.test.runner"/>
         <activity
             android:name=".GraphicsActivity"
             android:exported="false">
         </activity>
+        <activity android:name=".SurfaceControlPictureProfileTestActivity"
+                  android:exported="true"
+                  android:turnScreenOn="true"
+                  android:showWhenLocked="true"
+                  android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/CtsSurfaceControlTestsStaging/AndroidTest.xml b/tests/CtsSurfaceControlTestsStaging/AndroidTest.xml
index 5c0163f..025bf37 100644
--- a/tests/CtsSurfaceControlTestsStaging/AndroidTest.xml
+++ b/tests/CtsSurfaceControlTestsStaging/AndroidTest.xml
@@ -21,6 +21,9 @@
         <option name="install-arg" value="-t" />
         <option name="test-file-name" value="CtsSurfaceControlTestsStaging.apk" />
     </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.FeatureFlagTargetPreparer" >
+        <option name="flag-value" value="media_tv/android.media.tv.flags.apply_picture_profiles=true" />
+    </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.view.surfacecontroltests" />
         <option name="hidden-api-checks" value="false" />
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTest.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTest.java
new file mode 100644
index 0000000..135f710
--- /dev/null
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.surfacecontroltests;
+
+import static android.Manifest.permission.OBSERVE_PICTURE_PROFILES;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import static java.util.Arrays.stream;
+
+import android.hardware.HardwareBuffer;
+import android.media.quality.PictureProfileHandle;
+import android.os.Process;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlActivePicture;
+import android.view.SurfaceControlActivePictureListener;
+import android.view.SurfaceView;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SurfaceControlPictureProfileTest {
+    private static final String TAG = SurfaceControlPictureProfileTest.class.getSimpleName();
+
+    private SurfaceControl[] mSurfaceControls;
+    private SurfaceControl mSurfaceControl;
+
+    @Rule
+    public ActivityTestRule<SurfaceControlPictureProfileTestActivity> mActivityRule =
+            new ActivityTestRule<>(SurfaceControlPictureProfileTestActivity.class);
+
+    @Before
+    public void setup() {
+        SurfaceView[] surfaceViews = mActivityRule.getActivity().getSurfaceViews();
+        mSurfaceControls = new SurfaceControl[surfaceViews.length];
+        // Create a child surface control so we can set a buffer, priority and profile handle all
+        // on one single surface control
+        for (int i = 0; i < mSurfaceControls.length; ++i) {
+            mSurfaceControls[i] = new SurfaceControl.Builder().setName("test").setHidden(false)
+                    .setParent(surfaceViews[i].getSurfaceControl()).build();
+        }
+        mSurfaceControl = mSurfaceControls[0];
+    }
+
+    @Test
+    public void whenPictureProfileApplied_noExecptionsThrown() {
+        assumeTrue("Skipping test because feature flag is disabled",
+                   com.android.graphics.libgui.flags.Flags.applyPictureProfiles());
+        // TODO(b/337330263): Call MediaQualityManager.getMaxPictureProfiles instead
+        assumeTrue("Skipping test because no picture profile support",
+                   SurfaceControl.getMaxPictureProfiles() > 0);
+
+        // TODO(b/337330263): Load the handle from MediaQualityManager instead
+        PictureProfileHandle handle = new PictureProfileHandle(1);
+        HardwareBuffer buffer = getSolidBuffer(100, 100);
+        new SurfaceControl.Transaction()
+                    .setBuffer(mSurfaceControl, buffer)
+                    .setPictureProfileHandle(mSurfaceControl, handle)
+                    .apply();
+    }
+
+    @Test
+    public void whenStartsListening_callsListener() {
+        assumeTrue("Skipping test because feature flag is disabled",
+                   com.android.graphics.libgui.flags.Flags.applyPictureProfiles());
+        // TODO(b/337330263): Call MediaQualityManager.getMaxPictureProfiles instead
+        assumeTrue("Skipping test because no picture profile support",
+                   SurfaceControl.getMaxPictureProfiles() > 0);
+
+        BlockingQueue<SurfaceControlActivePicture[]> picturesQueue = new LinkedBlockingQueue<>();
+        SurfaceControlActivePicture[] pictures;
+        SurfaceControlActivePictureListener listener = new SurfaceControlActivePictureListener() {
+                @Override
+                public void onActivePicturesChanged(SurfaceControlActivePicture[] pictures) {
+                    picturesQueue.add(pictures);
+                }
+            };
+        // TODO(b/337330263): Call MediaQualityManager.addActivePictureListener instead
+        adoptShellPermissionIdentity(OBSERVE_PICTURE_PROFILES);
+        listener.startListening();
+        {
+            HardwareBuffer buffer = getSolidBuffer(100, 100);
+            new SurfaceControl.Transaction().setBuffer(mSurfaceControl, buffer).apply();
+        }
+
+        pictures = pollMs(picturesQueue, 200);
+        assertThat(pictures).isNotNull();
+        assertThat(pictures).isEmpty();
+    }
+
+    @Test
+    public void whenPictureProfileApplied_callsListenerWithUidAndProfileId() {
+        assumeTrue("Skipping test because feature flag is disabled",
+                   com.android.graphics.libgui.flags.Flags.applyPictureProfiles());
+        // TODO(b/337330263): Call MediaQualityManager.getMaxPictureProfiles instead
+        assumeTrue("Skipping test because no picture profile support",
+                   SurfaceControl.getMaxPictureProfiles() > 0);
+
+        BlockingQueue<SurfaceControlActivePicture[]> picturesQueue = new LinkedBlockingQueue<>();
+        SurfaceControlActivePicture[] pictures;
+        SurfaceControlActivePictureListener listener = new SurfaceControlActivePictureListener() {
+                @Override
+                public void onActivePicturesChanged(SurfaceControlActivePicture[] pictures) {
+                    picturesQueue.add(pictures);
+                }
+            };
+        // TODO(b/337330263): Call MediaQualityManager.addActivePictureListener instead
+        adoptShellPermissionIdentity(OBSERVE_PICTURE_PROFILES);
+        listener.startListening();
+        {
+            HardwareBuffer buffer = getSolidBuffer(100, 100);
+            new SurfaceControl.Transaction().setBuffer(mSurfaceControl, buffer).apply();
+        }
+
+        pictures = pollMs(picturesQueue, 200);
+        assertThat(pictures).isNotNull();
+        assertThat(pictures).isEmpty();
+
+        // TODO(b/337330263): Load the handle from MediaQualityManager instead
+        PictureProfileHandle handle = new PictureProfileHandle(1);
+        HardwareBuffer buffer = getSolidBuffer(100, 100);
+        new SurfaceControl.Transaction()
+                    .setBuffer(mSurfaceControl, buffer)
+                    .setPictureProfileHandle(mSurfaceControl, handle)
+                    .apply();
+
+        pictures = pollMs(picturesQueue, 200);
+        assertThat(pictures).isNotNull();
+        assertThat(stream(pictures).map(picture -> picture.getPictureProfileHandle().getId()))
+                .containsExactly(handle.getId());
+        assertThat(stream(pictures).map(picture -> picture.getOwnerUid()))
+                .containsExactly(Process.myUid());
+    }
+
+    @Test
+    public void whenPriorityChanges_callsListenerOnlyForLowerPriorityLayers() {
+        assumeTrue("Skipping test because feature flag is disabled",
+                   com.android.graphics.libgui.flags.Flags.applyPictureProfiles());
+        // TODO(b/337330263): Call MediaQualityManager.getMaxPictureProfiles instead
+        int maxPictureProfiles = SurfaceControl.getMaxPictureProfiles();
+        assumeTrue("Skipping test because no picture profile support", maxPictureProfiles > 0);
+
+        BlockingQueue<SurfaceControlActivePicture[]> picturesQueue = new LinkedBlockingQueue<>();
+        SurfaceControlActivePicture[] pictures;
+        SurfaceControlActivePictureListener listener = new SurfaceControlActivePictureListener() {
+                @Override
+                public void onActivePicturesChanged(SurfaceControlActivePicture[] pictures) {
+                    picturesQueue.add(pictures);
+                }
+            };
+        // TODO(b/337330263): Call MediaQualityManager.addActivePictureListener instead
+        adoptShellPermissionIdentity(OBSERVE_PICTURE_PROFILES);
+        listener.startListening();
+        {
+            HardwareBuffer buffer = getSolidBuffer(100, 100);
+            new SurfaceControl.Transaction().setBuffer(mSurfaceControl, buffer).apply();
+        }
+
+        pictures = pollMs(picturesQueue, 200);
+        assertThat(pictures).isNotNull();
+        assertThat(pictures).isEmpty();
+
+        SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+        // Use one more picture profile than allowed
+        for (int i = 0; i <= maxPictureProfiles; ++i) {
+            // Increase the number of surface views as necessary to support device configuration.
+            assertThat(i).isLessThan(mSurfaceControls.length);
+
+            // TODO(b/337330263): Load the handle from MediaQualityManager instead
+            PictureProfileHandle handle = new PictureProfileHandle(i + 1);
+            HardwareBuffer buffer = getSolidBuffer(100, 100);
+            transaction
+                    .setBuffer(mSurfaceControls[i], buffer)
+                    .setPictureProfileHandle(mSurfaceControls[i], handle)
+                    .setContentPriority(mSurfaceControls[i], 0);
+        }
+        // Make the first layer low priority (high value)
+        transaction.setContentPriority(mSurfaceControls[0], 2);
+        // Make the last layer higher priority (lower value)
+        transaction.setContentPriority(mSurfaceControls[maxPictureProfiles], 1);
+        transaction.apply();
+
+        pictures = pollMs(picturesQueue, 200);
+        assertThat(pictures).isNotNull();
+        assertThat(stream(pictures).map(picture -> picture.getLayerId()))
+                .containsNoDuplicates();
+        // Expect all but the first layer to be listed as an active picture
+        assertThat(stream(pictures).map(picture -> picture.getPictureProfileHandle().getId()))
+                .containsExactlyElementsIn(toIterableRange(2, maxPictureProfiles + 1));
+
+        // Change priority and ensure that the first layer gets access
+        new SurfaceControl.Transaction().setContentPriority(mSurfaceControls[0], 0).apply();
+        pictures = pollMs(picturesQueue, 200);
+        assertThat(pictures).isNotNull();
+        // Expect all but the last layer to be listed as an active picture
+        assertThat(stream(pictures).map(picture -> picture.getPictureProfileHandle().getId()))
+                .containsExactlyElementsIn(toIterableRange(1, maxPictureProfiles));
+    }
+
+    private static SurfaceControlActivePicture[] pollMs(
+            BlockingQueue<SurfaceControlActivePicture[]> picturesQueue, int waitMs) {
+        SurfaceControlActivePicture[] pictures = null;
+        long nowMs = System.currentTimeMillis();
+        long endTimeMs = nowMs + waitMs;
+        while (nowMs < endTimeMs && pictures == null) {
+            try {
+                pictures = picturesQueue.poll(endTimeMs - nowMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                // continue polling until timeout when interrupted
+            }
+            nowMs = System.currentTimeMillis();
+        }
+        return pictures;
+    }
+
+    Iterable<Long> toIterableRange(int start, int stop) {
+        return () -> LongStream.rangeClosed(start, stop).iterator();
+    }
+
+    private void adoptShellPermissionIdentity(String permission) {
+        getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(permission);
+    }
+
+    private HardwareBuffer getSolidBuffer(int width, int height) {
+        // We can assume that RGBA_8888 format is supported for every platform.
+        return HardwareBuffer.create(
+                width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_CPU_WRITE_OFTEN);
+    }
+}
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTestActivity.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTestActivity.java
new file mode 100644
index 0000000..42fcb26
--- /dev/null
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTestActivity.java
@@ -0,0 +1,43 @@
+/*
+ * 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.view.surfacecontroltests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.SurfaceView;
+
+public class SurfaceControlPictureProfileTestActivity extends Activity {
+    private SurfaceView[] mSurfaceViews;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.picture_profile_test_layout);
+        mSurfaceViews = new SurfaceView[3];
+        mSurfaceViews[0] = (SurfaceView) findViewById(R.id.surfaceview1);
+        mSurfaceViews[1] = (SurfaceView) findViewById(R.id.surfaceview2);
+        mSurfaceViews[2] = (SurfaceView) findViewById(R.id.surfaceview3);
+    }
+
+    public SurfaceView getSurfaceView() {
+        return mSurfaceViews[0];
+    }
+
+    public SurfaceView[] getSurfaceViews() {
+        return mSurfaceViews;
+    }
+}
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/res/layout/picture_profile_test_layout.xml b/tests/CtsSurfaceControlTestsStaging/src/main/res/layout/picture_profile_test_layout.xml
new file mode 100644
index 0000000..9aa2578
--- /dev/null
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/res/layout/picture_profile_test_layout.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <SurfaceView android:id="@+id/surfaceview1"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:layout_weight="1"/>
+    <SurfaceView android:id="@+id/surfaceview2"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:layout_weight="1"/>
+    <SurfaceView android:id="@+id/surfaceview3"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:layout_weight="1"/>
+</LinearLayout>
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
index 01cdbb8..e59b6bd 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
@@ -35,7 +35,7 @@
 /**
  * Test the back and forward transition between 2 activities.
  *
- * To run this test: `atest FlickerTestsAppLaunch:ActivitiesTransitionTest`
+ * To run this test: `atest FlickerTestsAppLaunch:ActivityTransitionTest`
  *
  * Actions:
  * ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
index 3d9321c..2bf8cc4 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
@@ -30,7 +30,7 @@
 /**
  * Test cold launching an app from launcher
  *
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppColdFromIcon`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromIconColdTest`
  *
  * Actions:
  * ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
index 9207530..9c6bf9d 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
@@ -30,7 +30,7 @@
 /**
  * Test launching an app after cold opening camera
  *
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppAfterCameraTest`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromIntentColdAfterCameraTest`
  *
  * Notes: Some default assertions are inherited [OpenAppTransition]
  */
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
index cbe7c32..1a53a61 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
@@ -35,7 +35,7 @@
 /**
  * Test cold launching an app from launcher
  *
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppColdTest`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromIntentColdTest`
  *
  * Actions:
  * ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
index b2941e7..14b6a18 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
@@ -34,7 +34,7 @@
 /**
  * Test warm launching an app from launcher
  *
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppWarmTest`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromIntentWarmTest`
  *
  * Actions:
  * ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
index 4048e0c..f30fe96 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
@@ -41,7 +41,7 @@
  *
  * This test assumes the device doesn't have AOD enabled
  *
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppNonResizeableTest`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromLockscreenViaIntentTest`
  *
  * Actions:
  * ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
index 41423fd..9c552eb 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
@@ -41,7 +41,7 @@
 /**
  * Test cold launching camera from launcher by double pressing power button
  *
- * To run this test: `atest FlickerTestsAppLaunch:OpenCameraOnDoubleClickPowerButton`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenCameraFromHomeOnDoubleClickPowerButtonTest`
  *
  * Actions:
  * ```
@@ -140,14 +140,8 @@
 
     @Postsubmit
     @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        flicker.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry(
-                LayersTraceSubject.VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS +
-                    listOf(CAMERA_BACKGROUND)
-            )
-        }
-    }
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
 
     @Postsubmit
     @Test
@@ -170,12 +164,5 @@
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
         fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
-
-        private val CAMERA_BACKGROUND =
-            ComponentNameMatcher(
-                "Background for SurfaceView" +
-                    "[com.google.android.GoogleCamera/" +
-                    "com.google.android.apps.camera.legacy.app.activity.main.CameraActivity]"
-            )
     }
 }
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
index 6432827..c1c5dc6 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
@@ -23,6 +23,7 @@
 import android.graphics.Region
 import android.os.SystemClock
 import android.platform.uiautomatorhelpers.DeviceHelpers
+import android.tools.PlatformConsts
 import android.tools.device.apphelpers.IStandardAppHelper
 import android.tools.helpers.SYSTEMUI_PACKAGE
 import android.tools.traces.parsers.WindowManagerStateHelper
@@ -38,6 +39,7 @@
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.helpers.MotionEventHelper.InputMethod.TOUCH
 import java.time.Duration
+import kotlin.math.abs
 
 /**
  * Wrapper class around App helper classes. This class adds functionality to the apps that the
@@ -163,7 +165,10 @@
             .StateSyncBuilder()
             .withAppTransitionIdle()
             .apply {
-                if (isPip) withPipShown() else withWindowSurfaceDisappeared(innerHelper)
+                if (isPip) withPipShown()
+                else
+                    withWindowSurfaceDisappeared(innerHelper)
+                        .withActivityState(innerHelper, PlatformConsts.STATE_STOPPED)
             }
             .waitForAndVerify()
     }
@@ -218,11 +223,16 @@
         val expectedRect = Rect(displayRect).apply {
             if (toLeft) right -= expectedWidth else left += expectedWidth
         }
-
-        wmHelper
-            .StateSyncBuilder()
+        wmHelper.StateSyncBuilder()
             .withAppTransitionIdle()
-            .withSurfaceVisibleRegion(this, Region(expectedRect))
+            .withSurfaceMatchingVisibleRegion(
+                this,
+                Region(expectedRect),
+                { surfaceRegion, expectedRegion ->
+                    areSnapWindowRegionsMatchingWithinThreshold(
+                        surfaceRegion, expectedRegion, toLeft
+                    )
+                })
             .waitForAndVerify()
     }
 
@@ -456,6 +466,33 @@
     private fun isInDesktopWindowingMode(wmHelper: WindowManagerStateHelper) =
         wmHelper.getWindow(innerHelper)?.windowingMode == WINDOWING_MODE_FREEFORM
 
+    private fun areSnapWindowRegionsMatchingWithinThreshold(
+        surfaceRegion: Region, expectedRegion: Region, toLeft: Boolean
+    ): Boolean {
+        val surfaceBounds = surfaceRegion.bounds
+        val expectedBounds = expectedRegion.bounds
+        // If snapped to left, right bounds will be cut off by the center divider.
+        // Else if snapped to right, the left bounds will be cut off.
+        val leftSideMatching: Boolean
+        val rightSideMatching: Boolean
+        if (toLeft) {
+            leftSideMatching = surfaceBounds.left == expectedBounds.left
+            rightSideMatching =
+                abs(surfaceBounds.right - expectedBounds.right) <=
+                        surfaceBounds.right * SNAP_WINDOW_MAX_THRESHOLD_DIFF
+        } else {
+            leftSideMatching =
+                abs(surfaceBounds.left - expectedBounds.left) <=
+                        surfaceBounds.left * SNAP_WINDOW_MAX_THRESHOLD_DIFF
+            rightSideMatching = surfaceBounds.right == expectedBounds.right
+        }
+
+        return surfaceBounds.top == expectedBounds.top &&
+                surfaceBounds.bottom == expectedBounds.bottom &&
+                leftSideMatching &&
+                rightSideMatching
+    }
+
     private companion object {
         val TIMEOUT: Duration = Duration.ofSeconds(3)
         const val SNAP_RESIZE_DRAG_INSET: Int = 5 // inset to avoid dragging to display edge
@@ -471,5 +508,12 @@
         const val HEADER_EMPTY_VIEW: String = "caption_handle"
         val caption: BySelector
             get() = By.res(SYSTEMUI_PACKAGE, CAPTION)
+        // In DesktopMode, window snap can be done with just a single window. In this case, the
+        // divider tiling between left and right window won't be shown, and hence its states are not
+        // obtainable in test.
+        // As the test should just focus on ensuring window goes to one side of the screen, an
+        // acceptable approach is to ensure snapped window still fills > 95% of either side of the
+        // screen.
+        const val SNAP_WINDOW_MAX_THRESHOLD_DIFF = 0.05
     }
 }
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index 931e4f8..db4838e 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -250,18 +250,13 @@
             wmHelper,
             launchedAppComponentMatcherOverride,
             action,
-            stringExtras,
-            waitConditionsBuilder =
-                wmHelper
-                    .StateSyncBuilder()
-                    .add(ConditionsFactory.isWMStateComplete())
-                    .withAppTransitionIdle()
-                    .add(ConditionsFactory.hasPipWindow())
+            stringExtras
         )
 
         wmHelper
             .StateSyncBuilder()
             .withWindowSurfaceAppeared(this)
+            .add(ConditionsFactory.isWMStateComplete())
             .withPipShown()
             .waitForAndVerify()
     }
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index 34350ab..36a89f9 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -1361,7 +1361,7 @@
     @Parameters(method = "systemGesturesTestArguments_forKeyCombinations")
     @EnableFlags(
         com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER,
-        com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER_MULTI_PRESS_GESTURES
+        com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER_MULTI_KEY_GESTURES
     )
     fun testKeyCombinationGestures(test: TestData) {
         setupKeyGestureController()
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index 05a0f8f..af87bf7 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -138,7 +138,8 @@
         new File(InstrumentationRegistry.getContext().getFilesDir(),
                 "package-watchdog.xml").delete();
         adoptShellPermissions(Manifest.permission.READ_DEVICE_CONFIG,
-                Manifest.permission.WRITE_DEVICE_CONFIG);
+                Manifest.permission.WRITE_DEVICE_CONFIG,
+                Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
         mTestLooper = new TestLooper();
         mSpyContext = spy(InstrumentationRegistry.getContext());
         when(mSpyContext.getPackageManager()).thenReturn(mMockPackageManager);
@@ -1013,7 +1014,7 @@
             triggerFailureCount = 1;
         }
         for (int i = 0; i < triggerFailureCount; i++) {
-            watchdog.onPackageFailure(packages, failureReason);
+            watchdog.notifyPackageFailure(packages, failureReason);
         }
         mTestLooper.dispatchAll();
         if (Flags.recoverabilityDetection()) {
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index a540a8d..5a8a6be 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -152,7 +152,8 @@
         new File(InstrumentationRegistry.getContext().getFilesDir(),
                 "package-watchdog.xml").delete();
         adoptShellPermissions(Manifest.permission.READ_DEVICE_CONFIG,
-                Manifest.permission.WRITE_DEVICE_CONFIG);
+                Manifest.permission.WRITE_DEVICE_CONFIG,
+                Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
         mTestLooper = new TestLooper();
         mSpyContext = spy(InstrumentationRegistry.getContext());
         when(mSpyContext.getPackageManager()).thenReturn(mMockPackageManager);
@@ -391,7 +392,7 @@
 
         // Then fail APP_A below the threshold
         for (int i = 0; i < watchdog.getTriggerFailureCount() - 1; i++) {
-            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+            watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                     PackageWatchdog.FAILURE_REASON_UNKNOWN);
         }
 
@@ -1024,14 +1025,14 @@
         watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
         // Fail APP_A below the threshold which should not trigger package failures
         for (int i = 0; i < PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT - 1; i++) {
-            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+            watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                     PackageWatchdog.FAILURE_REASON_UNKNOWN);
         }
         mTestLooper.dispatchAll();
         assertThat(observer.mHealthCheckFailedPackages).isEmpty();
 
         // One more to trigger the package failure
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
         assertThat(observer.mHealthCheckFailedPackages).containsExactly(APP_A);
@@ -1050,10 +1051,10 @@
         TestObserver observer = new TestObserver(OBSERVER_NAME_1);
 
         watchdog.startObservingHealth(observer, Arrays.asList(APP_A, APP_B), Long.MAX_VALUE);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS + 1);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
 
@@ -1061,10 +1062,10 @@
         // DEFAULT_TRIGGER_FAILURE_DURATION_MS.
         assertThat(observer.mHealthCheckFailedPackages).isEmpty();
 
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS - 1);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
 
@@ -1128,17 +1129,17 @@
 
         watchdog.startObservingHealth(observer, Arrays.asList(APP_A), Long.MAX_VALUE);
         // Raise 2 failures at t=0 and t=900 respectively
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         moveTimeForwardAndDispatch(900);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
 
         // Raise 2 failures at t=1100
         moveTimeForwardAndDispatch(200);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
 
@@ -1432,13 +1433,13 @@
         TestObserver observer = new TestObserver(OBSERVER_NAME_1);
         watchdog.startObservingHealth(observer, List.of(APP_A), SHORT_DURATION);
         for (int i = 0; i < PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT - 1; i++) {
-            watchdog.onPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
+            watchdog.notifyPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
                     PackageWatchdog.FAILURE_REASON_UNKNOWN);
         }
         mTestLooper.dispatchAll();
         assertThat(observer.mMitigatedPackages).isEmpty();
         watchdog.startObservingHealth(observer, List.of(APP_A), LONG_DURATION);
-        watchdog.onPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
         assertThat(observer.mMitigatedPackages).isEqualTo(List.of(APP_A));
@@ -1736,7 +1737,7 @@
             triggerFailureCount = 1;
         }
         for (int i = 0; i < triggerFailureCount; i++) {
-            watchdog.onPackageFailure(packages, failureReason);
+            watchdog.notifyPackageFailure(packages, failureReason);
         }
         mTestLooper.dispatchAll();
         if (Flags.recoverabilityDetection()) {
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java
index 314e952..a6aa877 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java
@@ -82,7 +82,8 @@
                 Manifest.permission.DELETE_PACKAGES,
                 Manifest.permission.TEST_MANAGE_ROLLBACKS,
                 Manifest.permission.FORCE_STOP_PACKAGES,
-                Manifest.permission.WRITE_DEVICE_CONFIG);
+                Manifest.permission.WRITE_DEVICE_CONFIG,
+                Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
     }
 
     /**
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 4cddcfe..32deb2e 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -70,7 +70,8 @@
                 Manifest.permission.DELETE_PACKAGES,
                 Manifest.permission.TEST_MANAGE_ROLLBACKS,
                 Manifest.permission.FORCE_STOP_PACKAGES,
-                Manifest.permission.WRITE_DEVICE_CONFIG);
+                Manifest.permission.WRITE_DEVICE_CONFIG,
+                Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
     }
 
     /**
diff --git a/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java b/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
index 8913e8c..0530846 100644
--- a/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
+++ b/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
@@ -89,7 +89,7 @@
         //noinspection ResultOfMethodCallIgnored
         mFile.delete();
         mProtoLog = new LegacyProtoLogImpl(mFile, mViewerConfigFilename,
-                1024 * 1024, mReader, 1024, () -> {});
+                1024 * 1024, mReader, 1024, (instance) -> {});
     }
 
     @After
diff --git a/tests/Tracing/src/com/android/internal/protolog/ProcessedPerfettoProtoLogImplTest.java b/tests/Tracing/src/com/android/internal/protolog/ProcessedPerfettoProtoLogImplTest.java
index 44641f7..ed256e7 100644
--- a/tests/Tracing/src/com/android/internal/protolog/ProcessedPerfettoProtoLogImplTest.java
+++ b/tests/Tracing/src/com/android/internal/protolog/ProcessedPerfettoProtoLogImplTest.java
@@ -41,6 +41,7 @@
 import android.tools.traces.monitors.PerfettoTraceMonitor;
 import android.tools.traces.protolog.ProtoLogTrace;
 import android.tracing.perfetto.DataSource;
+import android.tracing.perfetto.DataSourceParams;
 
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -95,14 +96,14 @@
     );
 
     private static ProtoLogConfigurationService sProtoLogConfigurationService;
+    private static ProtoLogDataSource sTestDataSource;
     private static PerfettoProtoLogImpl sProtoLog;
     private static Protolog.ProtoLogViewerConfig.Builder sViewerConfigBuilder;
-    private static Runnable sCacheUpdater;
+    private static ProtoLogCacheUpdater sCacheUpdater;
 
     private static ProtoLogViewerConfigReader sReader;
 
-    public ProcessedPerfettoProtoLogImplTest() throws IOException {
-    }
+    public ProcessedPerfettoProtoLogImplTest() throws IOException { }
 
     @BeforeClass
     public static void setUp() throws Exception {
@@ -155,12 +156,18 @@
                 .thenAnswer(it -> new AutoClosableProtoInputStream(
                         sViewerConfigBuilder.build().toByteArray()));
 
-        sCacheUpdater = () -> {};
+        sCacheUpdater = (instance) -> {};
         sReader = Mockito.spy(new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider));
+        sTestDataSource = new ProtoLogDataSource(TEST_PROTOLOG_DATASOURCE_NAME);
+        DataSourceParams params =
+                new DataSourceParams.Builder()
+                        .setBufferExhaustedPolicy(
+                                DataSourceParams
+                                        .PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
+                        .build();
+        sTestDataSource.register(params);
+        busyWaitForDataSourceRegistration(TEST_PROTOLOG_DATASOURCE_NAME);
 
-        final ProtoLogDataSourceBuilder dataSourceBuilder =
-                (onStart, onFlush, onStop) -> new ProtoLogDataSource(
-                        onStart, onFlush, onStop, TEST_PROTOLOG_DATASOURCE_NAME);
         final ViewerConfigFileTracer tracer = (dataSource, viewerConfigFilePath) -> {
             Utils.dumpViewerConfig(dataSource, () -> {
                 if (!viewerConfigFilePath.equals(MOCK_VIEWER_CONFIG_FILE)) {
@@ -171,14 +178,13 @@
             });
         };
         sProtoLogConfigurationService =
-                new ProtoLogConfigurationServiceImpl(dataSourceBuilder, tracer);
+                new ProtoLogConfigurationServiceImpl(sTestDataSource, tracer);
 
-        sProtoLog = new ProcessedPerfettoProtoLogImpl(
+        sProtoLog = new ProcessedPerfettoProtoLogImpl(sTestDataSource,
                 MOCK_VIEWER_CONFIG_FILE, viewerConfigInputStreamProvider, sReader,
-                () -> sCacheUpdater.run(), TestProtoLogGroup.values(), dataSourceBuilder,
+                (instance) -> sCacheUpdater.update(instance), TestProtoLogGroup.values(),
                 sProtoLogConfigurationService);
-
-        busyWaitForDataSourceRegistration(TEST_PROTOLOG_DATASOURCE_NAME);
+        sProtoLog.enable();
     }
 
     @Before
@@ -606,7 +612,7 @@
     @Test
     public void cacheIsUpdatedWhenTracesStartAndStop() {
         final AtomicInteger cacheUpdateCallCount = new AtomicInteger(0);
-        sCacheUpdater = cacheUpdateCallCount::incrementAndGet;
+        sCacheUpdater = (instance) -> cacheUpdateCallCount.incrementAndGet();
 
         PerfettoTraceMonitor traceMonitor1 = PerfettoTraceMonitor.newBuilder()
                 .enableProtoLog(true,
diff --git a/tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java b/tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java
index ce519b7a..4924933 100644
--- a/tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java
+++ b/tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java
@@ -67,9 +67,6 @@
 
     @Test
     public void allEnabledTraceMode() {
-        final ProtoLogDataSource ds =
-                new ProtoLogDataSource((idx, c) -> {}, () -> {}, (idx, c) -> {});
-
         final ProtoLogDataSource.TlsState tlsState = createTlsState(
                 DataSourceConfigOuterClass.DataSourceConfig.newBuilder().setProtologConfig(
                         ProtologConfig.ProtoLogConfig.newBuilder()
@@ -154,8 +151,7 @@
 
     private ProtoLogDataSource.TlsState createTlsState(
             DataSourceConfigOuterClass.DataSourceConfig config) {
-        final ProtoLogDataSource ds =
-                Mockito.spy(new ProtoLogDataSource((idx, c) -> {}, () -> {}, (idx, c) -> {}));
+        final ProtoLogDataSource ds = Mockito.spy(new ProtoLogDataSource());
 
         ProtoInputStream configStream = new ProtoInputStream(config.toByteArray());
         final ProtoLogDataSource.Instance dsInstance = Mockito.spy(
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 3828a71..4ab8e6a 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -70,7 +70,6 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.Uri;
-import android.net.vcn.Flags;
 import android.net.vcn.IVcnStatusCallback;
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
 import android.net.vcn.VcnConfig;
@@ -293,8 +292,6 @@
         doReturn(Collections.singleton(TRANSPORT_WIFI))
                 .when(mMockDeps)
                 .getRestrictedTransports(any(), any(), any());
-
-        mSetFlagsRule.enableFlags(Flags.FLAG_FIX_CONFIG_GARBAGE_COLLECTION);
     }
 
 
diff --git a/tools/aapt2/util/Util.h b/tools/aapt2/util/Util.h
index 40ff5b6..03da460a 100644
--- a/tools/aapt2/util/Util.h
+++ b/tools/aapt2/util/Util.h
@@ -111,8 +111,8 @@
 // Retrieves the build fingerprint of aapt2.
 std::string GetToolFingerprint();
 
-template <typename T>
-typename std::enable_if<std::is_arithmetic<T>::value, int>::type compare(const T& a, const T& b) {
+template <std::integral T>
+int compare(T a, T b) {
   if (a < b) {
     return -1;
   } else if (a > b) {
@@ -123,10 +123,7 @@
 
 // Makes a std::unique_ptr<> with the template parameter inferred by the compiler.
 // This will be present in C++14 and can be removed then.
-template <typename T, class... Args>
-std::unique_ptr<T> make_unique(Args&&... args) {
-  return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
-}
+using std::make_unique;
 
 // Writes a set of items to the std::ostream, joining the times with the provided separator.
 template <typename Container>
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 108942e..9222ff4 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -16,6 +16,7 @@
 
 package com.android.protolog.tool
 
+import com.android.internal.protolog.common.IProtoLog
 import com.android.internal.protolog.common.LogLevel
 import com.android.internal.protolog.common.ProtoLogToolInjected
 import com.android.protolog.tool.CommandOptions.Companion.USAGE
@@ -319,6 +320,7 @@
                             MethodCallExpr()
                                 .setName("isEnabled")
                                 .setArguments(NodeList(
+                                    NameExpr("protoLogInstance"),
                                     FieldAccessExpr()
                                         .setScope(NameExpr(protoLogGroupsClassName))
                                         .setName(group.value.name),
@@ -332,6 +334,7 @@
         }
 
         cacheClass.addMethod("update").setPrivate(true).setStatic(true)
+            .addParameter(IProtoLog::class.java, "protoLogInstance")
             .setBody(updateBlockStmt)
 
         classDeclaration.addMember(cacheClass)
diff --git a/tools/systemfeatures/Android.bp b/tools/systemfeatures/Android.bp
index e6d0a3d..2ebede3 100644
--- a/tools/systemfeatures/Android.bp
+++ b/tools/systemfeatures/Android.bp
@@ -13,6 +13,7 @@
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
+        ":framework-metalava-annotations",
     ],
     static_libs: [
         "guava",
@@ -26,6 +27,12 @@
     static_libs: ["systemfeatures-gen-lib"],
 }
 
+java_plugin {
+    name: "systemfeatures-metadata-processor",
+    processor_class: "com.android.systemfeatures.SystemFeaturesMetadataProcessor",
+    static_libs: ["systemfeatures-gen-lib"],
+}
+
 genrule {
     name: "systemfeatures-gen-tests-srcs",
     cmd: "$(location systemfeatures-gen-tool) com.android.systemfeatures.RwNoFeatures --readonly=false > $(location RwNoFeatures.java) && " +
@@ -61,6 +68,7 @@
         "systemfeatures-gen-lib",
         "truth",
     ],
+    plugins: ["systemfeatures-metadata-processor"],
 }
 
 // Rename the goldens as they may be copied into the source tree, and we don't
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
new file mode 100644
index 0000000..100d869
--- /dev/null
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemfeatures
+
+import android.annotation.SdkConstant
+import com.squareup.javapoet.FieldSpec
+import com.squareup.javapoet.JavaFile
+import com.squareup.javapoet.TypeSpec
+import java.io.IOException
+import javax.annotation.processing.AbstractProcessor
+import javax.annotation.processing.ProcessingEnvironment
+import javax.annotation.processing.RoundEnvironment
+import javax.lang.model.SourceVersion
+import javax.lang.model.element.Modifier
+import javax.lang.model.element.TypeElement
+import javax.tools.Diagnostic
+
+/*
+ * Simple Java code generator for computing metadata for system features.
+ *
+ * <p>The output is a single class file, `com.android.internal.pm.SystemFeaturesMetadata`, with
+ * properties computed from feature constant definitions in the PackageManager class. This
+ * class is only produced if the processed environment includes PackageManager; all other
+ * invocations are ignored.
+ */
+class SystemFeaturesMetadataProcessor : AbstractProcessor() {
+
+    private lateinit var packageManagerType: TypeElement
+
+    override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latestSupported()
+
+    override fun getSupportedAnnotationTypes() = setOf(SDK_CONSTANT_ANNOTATION_NAME)
+
+    override fun init(processingEnv: ProcessingEnvironment) {
+        super.init(processingEnv)
+        packageManagerType =
+            processingEnv.elementUtils.getTypeElement("android.content.pm.PackageManager")!!
+    }
+
+    override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
+        if (roundEnv.processingOver()) {
+            return false
+        }
+
+        // We're only interested in feature constants defined in PackageManager.
+        var featureCount = 0
+        roundEnv.getElementsAnnotatedWith(SdkConstant::class.java).forEach {
+            if (
+                it.enclosingElement == packageManagerType &&
+                    it.getAnnotation(SdkConstant::class.java).value ==
+                        SdkConstant.SdkConstantType.FEATURE
+            ) {
+                featureCount++
+            }
+        }
+
+        if (featureCount == 0) {
+            // This is fine, and happens for any environment that doesn't include PackageManager.
+            return false
+        }
+
+        val systemFeatureMetadata =
+            TypeSpec.classBuilder("SystemFeaturesMetadata")
+                .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
+                .addJavadoc("@hide")
+                .addField(
+                    FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
+                        .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
+                        .addJavadoc(
+                            "The number of `@SdkConstant` features defined in PackageManager."
+                        )
+                        .addJavadoc("@hide")
+                        .initializer("\$L", featureCount)
+                        .build()
+                )
+                .build()
+
+        try {
+            JavaFile.builder("com.android.internal.pm", systemFeatureMetadata)
+                .skipJavaLangImports(true)
+                .build()
+                .writeTo(processingEnv.filer)
+        } catch (e: IOException) {
+            processingEnv.messager.printMessage(
+                Diagnostic.Kind.ERROR,
+                "Failed to write file: ${e.message}",
+            )
+        }
+
+        return true
+    }
+
+    companion object {
+        private val SDK_CONSTANT_ANNOTATION_NAME = SdkConstant::class.qualifiedName
+    }
+}
diff --git a/tools/systemfeatures/tests/src/PackageManager.java b/tools/systemfeatures/tests/src/PackageManager.java
index db67048..839a937 100644
--- a/tools/systemfeatures/tests/src/PackageManager.java
+++ b/tools/systemfeatures/tests/src/PackageManager.java
@@ -16,14 +16,33 @@
 
 package android.content.pm;
 
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+
 /** Stub for testing */
 public class PackageManager {
+    @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_AUTO = "automotive";
+
+    @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_PC = "pc";
+
+    @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_VULKAN = "vulkan";
+
+    @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_WATCH = "watch";
+
+    @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_WIFI = "wifi";
 
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String FEATURE_INTENT_CATEGORY = "intent_category_with_feature_name_prefix";
+
+    public static final String FEATURE_NOT_ANNOTATED = "not_annotated";
+
+    public static final String NOT_FEATURE = "not_feature";
+
     /** @hide */
     public boolean hasSystemFeature(String featureName, int version) {
         return false;
diff --git a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
new file mode 100644
index 0000000..4ffb5b9
--- /dev/null
+++ b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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.systemfeatures;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.internal.pm.SystemFeaturesMetadata;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class SystemFeaturesMetadataProcessorTest {
+
+    @Test
+    public void testSdkFeatureCount() {
+        // See the fake PackageManager definition in this directory.
+        // It defines 5 annotated features, and any/all other constants should be ignored.
+        assertThat(SystemFeaturesMetadata.SDK_FEATURE_COUNT).isEqualTo(5);
+    }
+}